diff options
author | Jonas Gorski <jogo@openwrt.org> | 2014-07-12 10:49:40 (GMT) |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-07-30 13:29:41 (GMT) |
commit | 56d53eaec1ad402cb1055e816adad102d2f5b6bf (patch) | |
tree | 71471001a3d3d0bf557bef3e41d18095144a7432 /arch/mips/bcm63xx/irq.c | |
parent | 74b8ca3f3160b062207be6ee88785409c0a777ea (diff) | |
download | linux-56d53eaec1ad402cb1055e816adad102d2f5b6bf.tar.xz |
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>
Diffstat (limited to 'arch/mips/bcm63xx/irq.c')
-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 2f19391..615b25b 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) \ unsigned reg = (irq / 32) ^ (width/32 - 1); \ unsigned bit = irq & 0x1f; \ unsigned long flags; \ + int cpu; \ \ spin_lock_irqsave(&ipic_lock, flags); \ - val = bcm_readl(irq_mask_addr[0] + reg * sizeof(u32)); \ - val &= ~(1 << bit); \ - bcm_writel(val, irq_mask_addr[0] + reg * sizeof(u32)); \ + for_each_present_cpu(cpu) { \ + if (!irq_mask_addr[cpu]) \ + break; \ + \ + val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ + val &= ~(1 << bit); \ + bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ + } \ spin_unlock_irqrestore(&ipic_lock, flags); \ } \ \ @@ -116,11 +122,20 @@ static void __internal_irq_unmask_##width(unsigned int irq) \ unsigned reg = (irq / 32) ^ (width/32 - 1); \ unsigned bit = irq & 0x1f; \ unsigned long flags; \ + int cpu; \ \ spin_lock_irqsave(&ipic_lock, flags); \ - val = bcm_readl(irq_mask_addr[0] + reg * sizeof(u32)); \ - val |= (1 << bit); \ - bcm_writel(val, irq_mask_addr[0] + reg * sizeof(u32)); \ + for_each_present_cpu(cpu) { \ + if (!irq_mask_addr[cpu]) \ + break; \ + \ + val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ + if (cpu_online(cpu)) \ + val |= (1 << bit); \ + else \ + val &= ~(1 << bit); \ + bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ + } \ spin_unlock_irqrestore(&ipic_lock, flags); \ } @@ -145,7 +160,10 @@ asmlinkage void plat_irq_dispatch(void) do_IRQ(1); if (cause & CAUSEF_IP2) dispatch_internal(0); - if (!is_ext_irq_cascaded) { + if (is_ext_irq_cascaded) { + if (cause & CAUSEF_IP3) + dispatch_internal(1); + } else { if (cause & CAUSEF_IP3) do_IRQ(IRQ_EXT_0); if (cause & CAUSEF_IP4) @@ -358,6 +376,14 @@ static struct irqaction cpu_ip2_cascade_action = { .flags = IRQF_NO_THREAD, }; +#ifdef CONFIG_SMP +static struct irqaction cpu_ip3_cascade_action = { + .handler = no_action, + .name = "cascade_ip3", + .flags = IRQF_NO_THREAD, +}; +#endif + static struct irqaction cpu_ext_cascade_action = { .handler = no_action, .name = "cascade_extirq", @@ -494,4 +520,8 @@ void __init arch_init_irq(void) } setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); +#ifdef CONFIG_SMP + if (is_ext_irq_cascaded) + setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action); +#endif } |