brcm63xx: update bmips patches with upstream submission
[openwrt.git] / target / linux / brcm63xx / patches-3.10 / 320-MIPS-BCM63XX-wire-up-the-second-CPU-s-irq-line.patch
1 From 70c33fe0df8d14e40f3ca92ce56a668d66184858 Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Fri, 26 Apr 2013 12:03:15 +0200
4 Subject: [PATCH 12/14] MIPS: BCM63XX: wire up the second cpu's irq line
5
6 ---
7  arch/mips/bcm63xx/irq.c |   50 ++++++++++++++++++++++++++++++++++++++---------
8  1 file changed, 41 insertions(+), 9 deletions(-)
9
10 --- a/arch/mips/bcm63xx/irq.c
11 +++ b/arch/mips/bcm63xx/irq.c
12 @@ -363,13 +363,20 @@ static void __internal_irq_mask_##width(
13         u32 val;                                                        \
14         unsigned reg = (irq / 32) ^ (width/32 - 1);                     \
15         unsigned bit = irq & 0x1f;                                      \
16 -       u32 irq_mask_addr = get_irq_mask_addr(0);                       \
17         unsigned long flags;                                            \
18 +       int cpu;                                                        \
19                                                                         \
20         spin_lock_irqsave(&ipic_lock, flags);                           \
21 -       val = bcm_readl(irq_mask_addr + reg * sizeof(u32));             \
22 -       val &= ~(1 << bit);                                             \
23 -       bcm_writel(val, irq_mask_addr + reg * sizeof(u32));             \
24 +       for_each_present_cpu(cpu) {                                     \
25 +               u32 irq_mask_addr = get_irq_mask_addr(cpu);             \
26 +                                                                       \
27 +               if (!irq_mask_addr)                                     \
28 +                       break;                                          \
29 +                                                                       \
30 +               val = bcm_readl(irq_mask_addr + reg * sizeof(u32));     \
31 +               val &= ~(1 << bit);                                     \
32 +               bcm_writel(val, irq_mask_addr + reg * sizeof(u32));     \
33 +       }                                                               \
34         spin_unlock_irqrestore(&ipic_lock, flags);                      \
35  }                                                                      \
36                                                                         \
37 @@ -378,13 +385,23 @@ static void __internal_irq_unmask_##widt
38         u32 val;                                                        \
39         unsigned reg = (irq / 32) ^ (width/32 - 1);                     \
40         unsigned bit = irq & 0x1f;                                      \
41 -       u32 irq_mask_addr = get_irq_mask_addr(0);                       \
42         unsigned long flags;                                            \
43 +       int cpu;                                                        \
44                                                                         \
45         spin_lock_irqsave(&ipic_lock, flags);                           \
46 -       val = bcm_readl(irq_mask_addr + reg * sizeof(u32));             \
47 -       val |= (1 << bit);                                              \
48 -       bcm_writel(val, irq_mask_addr + reg * sizeof(u32));             \
49 +       for_each_present_cpu(cpu) {                                     \
50 +               u32 irq_mask_addr = get_irq_mask_addr(cpu);             \
51 +                                                                       \
52 +               if (!irq_mask_addr)                                     \
53 +                       break;                                          \
54 +                                                                       \
55 +               val = bcm_readl(irq_mask_addr + reg * sizeof(u32));     \
56 +               if (cpu_online(cpu))                                    \
57 +                       val |= (1 << bit);                              \
58 +               else                                                    \
59 +                       val &= ~(1 << bit);                             \
60 +               bcm_writel(val, irq_mask_addr + reg * sizeof(u32));     \
61 +       }                                                               \
62         spin_unlock_irqrestore(&ipic_lock, flags);                      \
63  }
64  
65 @@ -409,7 +426,10 @@ asmlinkage void plat_irq_dispatch(void)
66                         do_IRQ(1);
67                 if (cause & CAUSEF_IP2)
68                         dispatch_internal(0);
69 -               if (!is_ext_irq_cascaded) {
70 +               if (is_ext_irq_cascaded) {
71 +                       if (cause & CAUSEF_IP3)
72 +                               dispatch_internal(1);
73 +               } else {
74                         if (cause & CAUSEF_IP3)
75                                 do_IRQ(IRQ_EXT_0);
76                         if (cause & CAUSEF_IP4)
77 @@ -622,6 +642,14 @@ static struct irqaction cpu_ip2_cascade_
78         .flags          = IRQF_NO_THREAD,
79  };
80  
81 +#ifdef CONFIG_SMP
82 +static struct irqaction cpu_ip3_cascade_action = {
83 +       .handler        = no_action,
84 +       .name           = "cascade_ip3",
85 +       .flags          = IRQF_NO_THREAD,
86 +};
87 +#endif
88 +
89  static struct irqaction cpu_ext_cascade_action = {
90         .handler        = no_action,
91         .name           = "cascade_extirq",
92 @@ -648,4 +676,8 @@ void __init arch_init_irq(void)
93         }
94  
95         setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
96 +#ifdef CONFIG_SMP
97 +       if (is_ext_irq_cascaded)
98 +               setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action);
99 +#endif
100  }