aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorJohn Crispin <blogic@openwrt.org>2012-04-30 05:33:05 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-05-15 11:49:21 -0400
commita8d096ef78c4d9a664754e1fad5e82dec2feec68 (patch)
tree21a261fc21492c49be446e30902acb3db5ff95de /arch/mips
parent59c115798430f644b43123250ae4e1d820c3c18d (diff)
MIPS: lantiq: add ipi handlers to make vsmp work
Add IPI handlers to the interrupt code. This patch makes MIPS_MT_SMP work on lantiq socs. The code is based on the malta implementation. Signed-off-by: John Crispin <blogic@openwrt.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3704/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/lantiq/irq.c60
-rw-r--r--arch/mips/lantiq/prom.c5
2 files changed, 65 insertions, 0 deletions
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index bfd4ad180aac..d227be1c3c4d 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -54,6 +54,14 @@
54#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) 54#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
55#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) 55#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
56 56
57/* our 2 ipi interrupts for VSMP */
58#define MIPS_CPU_IPI_RESCHED_IRQ 0
59#define MIPS_CPU_IPI_CALL_IRQ 1
60
61#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
62int gic_present;
63#endif
64
57static unsigned short ltq_eiu_irq[MAX_EIU] = { 65static unsigned short ltq_eiu_irq[MAX_EIU] = {
58 LTQ_EIU_IR0, 66 LTQ_EIU_IR0,
59 LTQ_EIU_IR1, 67 LTQ_EIU_IR1,
@@ -219,6 +227,47 @@ static void ltq_hw5_irqdispatch(void)
219 do_IRQ(MIPS_CPU_TIMER_IRQ); 227 do_IRQ(MIPS_CPU_TIMER_IRQ);
220} 228}
221 229
230#ifdef CONFIG_MIPS_MT_SMP
231void __init arch_init_ipiirq(int irq, struct irqaction *action)
232{
233 setup_irq(irq, action);
234 irq_set_handler(irq, handle_percpu_irq);
235}
236
237static void ltq_sw0_irqdispatch(void)
238{
239 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
240}
241
242static void ltq_sw1_irqdispatch(void)
243{
244 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
245}
246static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
247{
248 scheduler_ipi();
249 return IRQ_HANDLED;
250}
251
252static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
253{
254 smp_call_function_interrupt();
255 return IRQ_HANDLED;
256}
257
258static struct irqaction irq_resched = {
259 .handler = ipi_resched_interrupt,
260 .flags = IRQF_PERCPU,
261 .name = "IPI_resched"
262};
263
264static struct irqaction irq_call = {
265 .handler = ipi_call_interrupt,
266 .flags = IRQF_PERCPU,
267 .name = "IPI_call"
268};
269#endif
270
222asmlinkage void plat_irq_dispatch(void) 271asmlinkage void plat_irq_dispatch(void)
223{ 272{
224 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; 273 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
@@ -312,6 +361,17 @@ void __init arch_init_irq(void)
312 irq_set_chip_and_handler(i, &ltq_irq_type, 361 irq_set_chip_and_handler(i, &ltq_irq_type,
313 handle_level_irq); 362 handle_level_irq);
314 363
364#if defined(CONFIG_MIPS_MT_SMP)
365 if (cpu_has_vint) {
366 pr_info("Setting up IPI vectored interrupts\n");
367 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
368 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
369 }
370 arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
371 &irq_resched);
372 arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
373#endif
374
315#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) 375#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
316 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | 376 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
317 IE_IRQ3 | IE_IRQ4 | IE_IRQ5); 377 IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index e34fcfd0d5ca..664b7b722248 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -68,4 +68,9 @@ void __init prom_init(void)
68 soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; 68 soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
69 pr_info("SoC: %s\n", soc_info.sys_type); 69 pr_info("SoC: %s\n", soc_info.sys_type);
70 prom_init_cmdline(); 70 prom_init_cmdline();
71
72#if defined(CONFIG_MIPS_MT_SMP)
73 if (register_vsmp_smp_ops())
74 panic("failed to register_vsmp_smp_ops()");
75#endif
71} 76}