diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2016-09-29 13:00:14 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2016-10-16 18:49:07 -0400 |
commit | 3ce0fefc51bd56381b1b9a92835cf8f9db3f2ef8 (patch) | |
tree | c425859767f89b65b4d11b41325632ffd82afffb | |
parent | 1001354ca34179f3db924eb66672442a173147dc (diff) |
ARCv2: intc: untangle SMP, MCIP and IDU
The IDU intc is technically part of MCIP (Multi-core IP) hence
historically was only available in a SMP hardware build (and thus only
in a SMP kernel build). Now that hardware restriction has been lifted,
so a UP kernel needs to support it.
This requires breaking mcip.c into parts which are strictly SMP
(inter-core interrupts) and IDU which in reality is just another
intc and thus has no bearing on SMP.
This change allows IDU in UP builds and with a suitable device tree, we
can have the cascaded intc system
ARCv2 core intc <---> ARCv2 IDU intc <---> periperals
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/Kconfig | 17 | ||||
-rw-r--r-- | arch/arc/include/asm/mcip.h | 16 | ||||
-rw-r--r-- | arch/arc/kernel/mcip.c | 31 |
3 files changed, 36 insertions, 28 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index ecd12379e2cd..6f67895cd9c4 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig | |||
@@ -186,14 +186,6 @@ if SMP | |||
186 | config ARC_HAS_COH_CACHES | 186 | config ARC_HAS_COH_CACHES |
187 | def_bool n | 187 | def_bool n |
188 | 188 | ||
189 | config ARC_MCIP | ||
190 | bool "ARConnect Multicore IP (MCIP) Support " | ||
191 | depends on ISA_ARCV2 | ||
192 | help | ||
193 | This IP block enables SMP in ARC-HS38 cores. | ||
194 | It provides for cross-core interrupts, multi-core debug | ||
195 | hardware semaphores, shared memory,.... | ||
196 | |||
197 | config NR_CPUS | 189 | config NR_CPUS |
198 | int "Maximum number of CPUs (2-4096)" | 190 | int "Maximum number of CPUs (2-4096)" |
199 | range 2 4096 | 191 | range 2 4096 |
@@ -211,6 +203,15 @@ config ARC_SMP_HALT_ON_RESET | |||
211 | 203 | ||
212 | endif #SMP | 204 | endif #SMP |
213 | 205 | ||
206 | config ARC_MCIP | ||
207 | bool "ARConnect Multicore IP (MCIP) Support " | ||
208 | depends on ISA_ARCV2 | ||
209 | default y if SMP | ||
210 | help | ||
211 | This IP block enables SMP in ARC-HS38 cores. | ||
212 | It provides for cross-core interrupts, multi-core debug | ||
213 | hardware semaphores, shared memory,.... | ||
214 | |||
214 | menuconfig ARC_CACHE | 215 | menuconfig ARC_CACHE |
215 | bool "Enable Cache Support" | 216 | bool "Enable Cache Support" |
216 | default y | 217 | default y |
diff --git a/arch/arc/include/asm/mcip.h b/arch/arc/include/asm/mcip.h index 847e3bbe387f..c8fbe4114bad 100644 --- a/arch/arc/include/asm/mcip.h +++ b/arch/arc/include/asm/mcip.h | |||
@@ -55,6 +55,22 @@ struct mcip_cmd { | |||
55 | #define IDU_M_DISTRI_DEST 0x2 | 55 | #define IDU_M_DISTRI_DEST 0x2 |
56 | }; | 56 | }; |
57 | 57 | ||
58 | struct mcip_bcr { | ||
59 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
60 | unsigned int pad3:8, | ||
61 | idu:1, llm:1, num_cores:6, | ||
62 | iocoh:1, gfrc:1, dbg:1, pad2:1, | ||
63 | msg:1, sem:1, ipi:1, pad:1, | ||
64 | ver:8; | ||
65 | #else | ||
66 | unsigned int ver:8, | ||
67 | pad:1, ipi:1, sem:1, msg:1, | ||
68 | pad2:1, dbg:1, gfrc:1, iocoh:1, | ||
69 | num_cores:6, llm:1, idu:1, | ||
70 | pad3:8; | ||
71 | #endif | ||
72 | }; | ||
73 | |||
58 | /* | 74 | /* |
59 | * MCIP programming model | 75 | * MCIP programming model |
60 | * | 76 | * |
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index 72f9179b1a24..c424d5abc318 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c | |||
@@ -15,11 +15,12 @@ | |||
15 | #include <asm/mcip.h> | 15 | #include <asm/mcip.h> |
16 | #include <asm/setup.h> | 16 | #include <asm/setup.h> |
17 | 17 | ||
18 | static char smp_cpuinfo_buf[128]; | ||
19 | static int idu_detected; | ||
20 | |||
21 | static DEFINE_RAW_SPINLOCK(mcip_lock); | 18 | static DEFINE_RAW_SPINLOCK(mcip_lock); |
22 | 19 | ||
20 | #ifdef CONFIG_SMP | ||
21 | |||
22 | static char smp_cpuinfo_buf[128]; | ||
23 | |||
23 | static void mcip_setup_per_cpu(int cpu) | 24 | static void mcip_setup_per_cpu(int cpu) |
24 | { | 25 | { |
25 | smp_ipi_irq_setup(cpu, IPI_IRQ); | 26 | smp_ipi_irq_setup(cpu, IPI_IRQ); |
@@ -86,21 +87,7 @@ static void mcip_ipi_clear(int irq) | |||
86 | 87 | ||
87 | static void mcip_probe_n_setup(void) | 88 | static void mcip_probe_n_setup(void) |
88 | { | 89 | { |
89 | struct mcip_bcr { | 90 | struct mcip_bcr mp; |
90 | #ifdef CONFIG_CPU_BIG_ENDIAN | ||
91 | unsigned int pad3:8, | ||
92 | idu:1, llm:1, num_cores:6, | ||
93 | iocoh:1, gfrc:1, dbg:1, pad2:1, | ||
94 | msg:1, sem:1, ipi:1, pad:1, | ||
95 | ver:8; | ||
96 | #else | ||
97 | unsigned int ver:8, | ||
98 | pad:1, ipi:1, sem:1, msg:1, | ||
99 | pad2:1, dbg:1, gfrc:1, iocoh:1, | ||
100 | num_cores:6, llm:1, idu:1, | ||
101 | pad3:8; | ||
102 | #endif | ||
103 | } mp; | ||
104 | 91 | ||
105 | READ_BCR(ARC_REG_MCIP_BCR, mp); | 92 | READ_BCR(ARC_REG_MCIP_BCR, mp); |
106 | 93 | ||
@@ -114,7 +101,6 @@ static void mcip_probe_n_setup(void) | |||
114 | IS_AVAIL1(mp.gfrc, "GFRC")); | 101 | IS_AVAIL1(mp.gfrc, "GFRC")); |
115 | 102 | ||
116 | cpuinfo_arc700[0].extn.gfrc = mp.gfrc; | 103 | cpuinfo_arc700[0].extn.gfrc = mp.gfrc; |
117 | idu_detected = mp.idu; | ||
118 | 104 | ||
119 | if (mp.dbg) { | 105 | if (mp.dbg) { |
120 | __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf); | 106 | __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf); |
@@ -130,6 +116,8 @@ struct plat_smp_ops plat_smp_ops = { | |||
130 | .ipi_clear = mcip_ipi_clear, | 116 | .ipi_clear = mcip_ipi_clear, |
131 | }; | 117 | }; |
132 | 118 | ||
119 | #endif | ||
120 | |||
133 | /*************************************************************************** | 121 | /*************************************************************************** |
134 | * ARCv2 Interrupt Distribution Unit (IDU) | 122 | * ARCv2 Interrupt Distribution Unit (IDU) |
135 | * | 123 | * |
@@ -295,8 +283,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent) | |||
295 | /* Read IDU BCR to confirm nr_irqs */ | 283 | /* Read IDU BCR to confirm nr_irqs */ |
296 | int nr_irqs = of_irq_count(intc); | 284 | int nr_irqs = of_irq_count(intc); |
297 | int i, irq; | 285 | int i, irq; |
286 | struct mcip_bcr mp; | ||
287 | |||
288 | READ_BCR(ARC_REG_MCIP_BCR, mp); | ||
298 | 289 | ||
299 | if (!idu_detected) | 290 | if (!mp.idu) |
300 | panic("IDU not detected, but DeviceTree using it"); | 291 | panic("IDU not detected, but DeviceTree using it"); |
301 | 292 | ||
302 | pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs); | 293 | pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs); |