895bddd20d959668b8901055e5d32ea8c0aa3e03
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.2 / 0036-MIPS-lantiq-add-ipi-handlers-to-make-vsmp-work.patch
1 From da466512e536083352dcefd9ddbfd95a9c60b464 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Tue, 21 Feb 2012 21:09:01 +0100
4 Subject: [PATCH 36/73] MIPS: lantiq: add ipi handlers to make vsmp work
5
6 Add IPI handlers to the interrupt code. This patch makes MIPS_MT_SMP work
7 on lantiq SoCs.
8
9 Signed-off-by: John Crispin <blogic@openwrt.org>
10 ---
11 arch/mips/lantiq/irq.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
12 arch/mips/lantiq/prom.c | 5 ++++
13 2 files changed, 66 insertions(+), 0 deletions(-)
14
15 diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
16 index 0b2ed87..770a10c 100644
17 --- a/arch/mips/lantiq/irq.c
18 +++ b/arch/mips/lantiq/irq.c
19 @@ -9,6 +9,7 @@
20
21 #include <linux/interrupt.h>
22 #include <linux/ioport.h>
23 +#include <linux/sched.h>
24
25 #include <asm/bootinfo.h>
26 #include <asm/irq_cpu.h>
27 @@ -54,6 +55,14 @@
28 #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
29 #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
30
31 +/* our 2 ipi interrupts for VSMP */
32 +#define MIPS_CPU_IPI_RESCHED_IRQ 0
33 +#define MIPS_CPU_IPI_CALL_IRQ 1
34 +
35 +#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
36 +int gic_present;
37 +#endif
38 +
39 static unsigned short ltq_eiu_irq[MAX_EIU] = {
40 LTQ_EIU_IR0,
41 LTQ_EIU_IR1,
42 @@ -219,6 +228,47 @@ static void ltq_hw5_irqdispatch(void)
43 do_IRQ(MIPS_CPU_TIMER_IRQ);
44 }
45
46 +#ifdef CONFIG_MIPS_MT_SMP
47 +void __init arch_init_ipiirq(int irq, struct irqaction *action)
48 +{
49 + setup_irq(irq, action);
50 + irq_set_handler(irq, handle_percpu_irq);
51 +}
52 +
53 +static void ltq_sw0_irqdispatch(void)
54 +{
55 + do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
56 +}
57 +
58 +static void ltq_sw1_irqdispatch(void)
59 +{
60 + do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
61 +}
62 +static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
63 +{
64 + scheduler_ipi();
65 + return IRQ_HANDLED;
66 +}
67 +
68 +static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
69 +{
70 + smp_call_function_interrupt();
71 + return IRQ_HANDLED;
72 +}
73 +
74 +static struct irqaction irq_resched = {
75 + .handler = ipi_resched_interrupt,
76 + .flags = IRQF_PERCPU,
77 + .name = "IPI_resched"
78 +};
79 +
80 +static struct irqaction irq_call = {
81 + .handler = ipi_call_interrupt,
82 + .flags = IRQF_PERCPU,
83 + .name = "IPI_call"
84 +};
85 +#endif
86 +
87 asmlinkage void plat_irq_dispatch(void)
88 {
89 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
90 @@ -314,6 +364,17 @@ void __init arch_init_irq(void)
91 irq_set_chip_and_handler(i, &ltq_irq_type,
92 handle_level_irq);
93
94 +#if defined(CONFIG_MIPS_MT_SMP)
95 + if (cpu_has_vint) {
96 + pr_info("Setting up IPI vectored interrupts\n");
97 + set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
98 + set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
99 + }
100 + arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
101 + &irq_resched);
102 + arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
103 +#endif
104 +
105 #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
106 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
107 IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
108 diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
109 index 971554b..00ad59c 100644
110 --- a/arch/mips/lantiq/prom.c
111 +++ b/arch/mips/lantiq/prom.c
112 @@ -108,4 +108,9 @@ void __init prom_init(void)
113 soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
114 pr_info("SoC: %s\n", soc_info.sys_type);
115 prom_init_cmdline();
116 +
117 +#if defined(CONFIG_MIPS_MT_SMP)
118 + if (register_vsmp_smp_ops())
119 + panic("failed to register_vsmp_smp_ops()");
120 +#endif
121 }
122 --
123 1.7.9.1
124