summaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm63xx
diff options
context:
space:
mode:
authorJonas Gorski <jogo@openwrt.org>2014-07-12 12:49:40 +0200
committerRalf Baechle <ralf@linux-mips.org>2014-07-30 15:29:41 +0200
commit56d53eaec1ad402cb1055e816adad102d2f5b6bf (patch)
tree71471001a3d3d0bf557bef3e41d18095144a7432 /arch/mips/bcm63xx
parentMIPS: BCM63xx: Protect irq register accesses (diff)
downloadlinux-56d53eaec1ad402cb1055e816adad102d2f5b6bf.tar.xz
linux-56d53eaec1ad402cb1055e816adad102d2f5b6bf.zip
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')
-rw-r--r--arch/mips/bcm63xx/irq.c44
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) \
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
}