diff options
author | Jonas Gorski <jogo@openwrt.org> | 2014-07-12 06:49:40 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-07-30 09:29:41 -0400 |
commit | 56d53eaec1ad402cb1055e816adad102d2f5b6bf (patch) | |
tree | 71471001a3d3d0bf557bef3e41d18095144a7432 | |
parent | 74b8ca3f3160b062207be6ee88785409c0a777ea (diff) |
MIPS: BCM63xx: Wire up the second cpu's irq line
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: John Crispin <blogic@openwrt.org>
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Gregory Fong <gregory.0xf0@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/7322/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/bcm63xx/irq.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index 2f1939122bc3..615b25bb34f5 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c | |||
@@ -102,11 +102,17 @@ static void __internal_irq_mask_##width(unsigned int irq) \ | |||
102 | unsigned reg = (irq / 32) ^ (width/32 - 1); \ | 102 | unsigned reg = (irq / 32) ^ (width/32 - 1); \ |
103 | unsigned bit = irq & 0x1f; \ | 103 | unsigned bit = irq & 0x1f; \ |
104 | unsigned long flags; \ | 104 | unsigned long flags; \ |
105 | int cpu; \ | ||
105 | \ | 106 | \ |
106 | spin_lock_irqsave(&ipic_lock, flags); \ | 107 | spin_lock_irqsave(&ipic_lock, flags); \ |
107 | val = bcm_readl(irq_mask_addr[0] + reg * sizeof(u32)); \ | 108 | for_each_present_cpu(cpu) { \ |
108 | val &= ~(1 << bit); \ | 109 | if (!irq_mask_addr[cpu]) \ |
109 | bcm_writel(val, irq_mask_addr[0] + reg * sizeof(u32)); \ | 110 | break; \ |
111 | \ | ||
112 | val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
113 | val &= ~(1 << bit); \ | ||
114 | bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
115 | } \ | ||
110 | spin_unlock_irqrestore(&ipic_lock, flags); \ | 116 | spin_unlock_irqrestore(&ipic_lock, flags); \ |
111 | } \ | 117 | } \ |
112 | \ | 118 | \ |
@@ -116,11 +122,20 @@ static void __internal_irq_unmask_##width(unsigned int irq) \ | |||
116 | unsigned reg = (irq / 32) ^ (width/32 - 1); \ | 122 | unsigned reg = (irq / 32) ^ (width/32 - 1); \ |
117 | unsigned bit = irq & 0x1f; \ | 123 | unsigned bit = irq & 0x1f; \ |
118 | unsigned long flags; \ | 124 | unsigned long flags; \ |
125 | int cpu; \ | ||
119 | \ | 126 | \ |
120 | spin_lock_irqsave(&ipic_lock, flags); \ | 127 | spin_lock_irqsave(&ipic_lock, flags); \ |
121 | val = bcm_readl(irq_mask_addr[0] + reg * sizeof(u32)); \ | 128 | for_each_present_cpu(cpu) { \ |
122 | val |= (1 << bit); \ | 129 | if (!irq_mask_addr[cpu]) \ |
123 | bcm_writel(val, irq_mask_addr[0] + reg * sizeof(u32)); \ | 130 | break; \ |
131 | \ | ||
132 | val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
133 | if (cpu_online(cpu)) \ | ||
134 | val |= (1 << bit); \ | ||
135 | else \ | ||
136 | val &= ~(1 << bit); \ | ||
137 | bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
138 | } \ | ||
124 | spin_unlock_irqrestore(&ipic_lock, flags); \ | 139 | spin_unlock_irqrestore(&ipic_lock, flags); \ |
125 | } | 140 | } |
126 | 141 | ||
@@ -145,7 +160,10 @@ asmlinkage void plat_irq_dispatch(void) | |||
145 | do_IRQ(1); | 160 | do_IRQ(1); |
146 | if (cause & CAUSEF_IP2) | 161 | if (cause & CAUSEF_IP2) |
147 | dispatch_internal(0); | 162 | dispatch_internal(0); |
148 | if (!is_ext_irq_cascaded) { | 163 | if (is_ext_irq_cascaded) { |
164 | if (cause & CAUSEF_IP3) | ||
165 | dispatch_internal(1); | ||
166 | } else { | ||
149 | if (cause & CAUSEF_IP3) | 167 | if (cause & CAUSEF_IP3) |
150 | do_IRQ(IRQ_EXT_0); | 168 | do_IRQ(IRQ_EXT_0); |
151 | if (cause & CAUSEF_IP4) | 169 | if (cause & CAUSEF_IP4) |
@@ -358,6 +376,14 @@ static struct irqaction cpu_ip2_cascade_action = { | |||
358 | .flags = IRQF_NO_THREAD, | 376 | .flags = IRQF_NO_THREAD, |
359 | }; | 377 | }; |
360 | 378 | ||
379 | #ifdef CONFIG_SMP | ||
380 | static struct irqaction cpu_ip3_cascade_action = { | ||
381 | .handler = no_action, | ||
382 | .name = "cascade_ip3", | ||
383 | .flags = IRQF_NO_THREAD, | ||
384 | }; | ||
385 | #endif | ||
386 | |||
361 | static struct irqaction cpu_ext_cascade_action = { | 387 | static struct irqaction cpu_ext_cascade_action = { |
362 | .handler = no_action, | 388 | .handler = no_action, |
363 | .name = "cascade_extirq", | 389 | .name = "cascade_extirq", |
@@ -494,4 +520,8 @@ void __init arch_init_irq(void) | |||
494 | } | 520 | } |
495 | 521 | ||
496 | setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); | 522 | setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); |
523 | #ifdef CONFIG_SMP | ||
524 | if (is_ext_irq_cascaded) | ||
525 | setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action); | ||
526 | #endif | ||
497 | } | 527 | } |