lantiq: add support for tplink images to .../image/Makefile
[openwrt.git] / target / linux / brcm63xx / patches-3.9 / 322-MIPS-BCM63XX-allow-setting-affinity-for-IPIC.patch
index d976903d2fed7d55d21106620f20e7e0b4fa8b1a..c89a344ff9040d0b3830ac66ff1d91625b90ce59 100644 (file)
@@ -1,34 +1,97 @@
-From a8bb19e5ba9a3a73fe6a761295b67b641a7bc9df Mon Sep 17 00:00:00 2001
+From 9e341df1f67c3c64dc5ac668a30bbb6b5ab5f2b4 Mon Sep 17 00:00:00 2001
 From: Jonas Gorski <jogo@openwrt.org>
 Date: Fri, 26 Apr 2013 12:06:03 +0200
-Subject: [PATCH 13/13] MIPS: BCM63XX: allow setting affinity for IPIC
-
-Add support for setting the SMP affinity for the IPIC IRQs.
+Subject: [PATCH 14/14] MIPS: BCM63XX: allow setting affinity for IPIC
 
 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 ---
- arch/mips/bcm63xx/irq.c |   27 ++++++++++++++++++++++++++-
- 1 file changed, 26 insertions(+), 1 deletion(-)
+ arch/mips/bcm63xx/irq.c |   49 +++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 41 insertions(+), 8 deletions(-)
 
 --- a/arch/mips/bcm63xx/irq.c
 +++ b/arch/mips/bcm63xx/irq.c
-@@ -418,9 +418,14 @@ static void bcm63xx_internal_irq_mask(st
- static void bcm63xx_internal_irq_unmask(struct irq_data *d)
+@@ -24,8 +24,10 @@ static void __dispatch_internal_32(int c
+ static void __dispatch_internal_64(int cpu) __maybe_unused;
+ static void __internal_irq_mask_32(struct irq_data *d) __maybe_unused;
+ static void __internal_irq_mask_64(struct irq_data *d) __maybe_unused;
+-static void __internal_irq_unmask_32(struct irq_data *d) __maybe_unused;
+-static void __internal_irq_unmask_64(struct irq_data *d) __maybe_unused;
++static void __internal_irq_unmask_32(struct irq_data *d,
++                                   const struct cpumask *mask) __maybe_unused;
++static void __internal_irq_unmask_64(struct irq_data *d,
++                                   const struct cpumask *mask) __maybe_unused;
+ static DEFINE_SPINLOCK(ipic_lock);
+ static DEFINE_SPINLOCK(epic_lock);
+@@ -168,7 +170,7 @@ static unsigned int ext_irq_count;
+ static unsigned int ext_irq_start, ext_irq_end;
+ static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2;
+ static void (*internal_irq_mask)(struct irq_data *d);
+-static void (*internal_irq_unmask)(struct irq_data *d);
++static void (*internal_irq_unmask)(struct irq_data *d, const struct cpumask *m);
+ static void bcm63xx_init_irq(void)
  {
-       unsigned long flags;
-+      const struct cpumask *dest = cpu_online_mask;
+@@ -311,6 +313,20 @@ static inline void handle_internal(int i
+               do_IRQ(intbit + IRQ_INTERNAL_BASE);
+ }
  
-       spin_lock_irqsave(&ipic_lock, flags);
--      internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE, cpu_online_mask);
++static inline int enable_irq_for_cpu(int cpu, struct irq_data *d,
++                                   const struct cpumask *m)
++{
++      bool enable = cpu_online(cpu);
 +#ifdef CONFIG_SMP
-+      if (irqd_affinity_was_set(d))
-+              dest = d->affinity;
++
++      if (m)
++              enable &= cpu_isset(cpu, *m);
++      else if (irqd_affinity_was_set(d))
++              enable &= cpu_isset(cpu, *d->affinity);
 +#endif
-+      internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE, dest);
-       spin_unlock_irqrestore(&ipic_lock, flags);
++      return enable;
++}
++
+ /*
+  * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
+  * prioritize any interrupt relatively to another. the static counter
+@@ -381,7 +397,8 @@ static void __internal_irq_mask_##width(
+       spin_unlock_irqrestore(&ipic_lock, flags);                      \
+ }                                                                     \
+                                                                       \
+-static void __internal_irq_unmask_##width(struct irq_data *d)         \
++static void __internal_irq_unmask_##width(struct irq_data *d,         \
++                                        const struct cpumask *m)      \
+ {                                                                     \
+       u32 val;                                                        \
+       unsigned irq = d->irq - IRQ_INTERNAL_BASE;                      \
+@@ -398,7 +415,7 @@ static void __internal_irq_unmask_##widt
+                       break;                                          \
+                                                                       \
+               val = bcm_readl(irq_mask_addr + reg * sizeof(u32));     \
+-              if (cpu_online(cpu))                                    \
++              if (enable_irq_for_cpu(cpu, d, m))                      \
+                       val |= (1 << bit);                              \
+               else                                                    \
+                       val &= ~(1 << bit);                             \
+@@ -455,7 +472,7 @@ static void bcm63xx_internal_irq_mask(st
+ static void bcm63xx_internal_irq_unmask(struct irq_data *d)
+ {
+-      internal_irq_unmask(d);
++      internal_irq_unmask(d, NULL);
+ }
+ /*
+@@ -503,7 +520,8 @@ static void bcm63xx_external_irq_unmask(
+       spin_unlock_irqrestore(&epic_lock, flags);
+       if (is_ext_irq_cascaded)
+-              internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start));
++              internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start),
++                                  NULL);
  }
  
-@@ -596,10 +601,30 @@ static int bcm63xx_external_irq_set_type
+ static void bcm63xx_external_irq_clear(struct irq_data *d)
+@@ -622,6 +640,18 @@ static int bcm63xx_external_irq_set_type
        return IRQ_SET_MASK_OK_NOCOPY;
  }
  
@@ -37,13 +100,8 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 +                                       const struct cpumask *dest,
 +                                       bool force)
 +{
-+      unsigned int irq = data->irq - IRQ_INTERNAL_BASE;
-+      unsigned long flags;
-+
-+      spin_lock_irqsave(&ipic_lock, flags);
 +      if (!irqd_irq_disabled(data))
-+              internal_irq_unmask(irq, dest);
-+      spin_unlock_irqrestore(&ipic_lock, flags);
++              internal_irq_unmask(data, dest);
 +
 +      return 0;
 +}
@@ -52,10 +110,15 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
  static struct irq_chip bcm63xx_internal_irq_chip = {
        .name           = "bcm63xx_ipic",
        .irq_mask       = bcm63xx_internal_irq_mask,
-       .irq_unmask     = bcm63xx_internal_irq_unmask,
-+#ifdef CONFIG_SMP
-+      .irq_set_affinity = bcm63xx_internal_set_affinity,
-+#endif
- };
+@@ -679,7 +709,10 @@ void __init arch_init_irq(void)
  
- static struct irq_chip bcm63xx_external_irq_chip = {
+       setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
+ #ifdef CONFIG_SMP
+-      if (is_ext_irq_cascaded)
++      if (is_ext_irq_cascaded) {
+               setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action);
++              bcm63xx_internal_irq_chip.irq_set_affinity =
++                      bcm63xx_internal_set_affinity;
++      }
+ #endif
+ }