brcm47xx: improve IRQ handling for bcma based devices
authorHauke Mehrtens <hauke@hauke-m.de>
Thu, 3 Jan 2013 01:55:34 +0000 (01:55 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Thu, 3 Jan 2013 01:55:34 +0000 (01:55 +0000)
This was party inspirited by patches send by Nathan Hintz <nlhintz@hotmail.com>

SVN-Revision: 34989

target/linux/brcm47xx/patches-3.6/180-bcma-make-bcma_find_core_unit-accessible-by-other-pa.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.6/181-bcma-explicit-assigne-irq-numbers.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.6/182-bcma-make-some-info-messages-debug.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.6/183-bcma-mips-show-also-disabled-irqs.patch [new file with mode: 0644]
target/linux/brcm47xx/patches-3.6/235-bcma-dont-expose-mips-irq.patch

diff --git a/target/linux/brcm47xx/patches-3.6/180-bcma-make-bcma_find_core_unit-accessible-by-other-pa.patch b/target/linux/brcm47xx/patches-3.6/180-bcma-make-bcma_find_core_unit-accessible-by-other-pa.patch
new file mode 100644 (file)
index 0000000..147ac34
--- /dev/null
@@ -0,0 +1,24 @@
+--- a/drivers/bcma/bcma_private.h
++++ b/drivers/bcma/bcma_private.h
+@@ -31,6 +31,8 @@ int __init bcma_bus_early_register(struc
+ int bcma_bus_suspend(struct bcma_bus *bus);
+ int bcma_bus_resume(struct bcma_bus *bus);
+ #endif
++struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
++                                      u8 unit);
+ /* scan.c */
+ int bcma_bus_scan(struct bcma_bus *bus);
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -81,8 +81,8 @@ struct bcma_device *bcma_find_core(struc
+ }
+ EXPORT_SYMBOL_GPL(bcma_find_core);
+-static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
+-                                             u8 unit)
++struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
++                                      u8 unit)
+ {
+       struct bcma_device *core;
diff --git a/target/linux/brcm47xx/patches-3.6/181-bcma-explicit-assigne-irq-numbers.patch b/target/linux/brcm47xx/patches-3.6/181-bcma-explicit-assigne-irq-numbers.patch
new file mode 100644 (file)
index 0000000..7fac415
--- /dev/null
@@ -0,0 +1,109 @@
+--- a/drivers/bcma/driver_mips.c
++++ b/drivers/bcma/driver_mips.c
+@@ -148,6 +148,22 @@ static void bcma_core_mips_set_irq(struc
+                 dev->id.id, oldirq + 2, irq + 2);
+ }
++static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
++                                      u16 coreid, u8 unit)
++{
++      struct bcma_device *core;
++
++      core = bcma_find_core_unit(bus, coreid, unit);
++      if (!core) {
++              bcma_warn(bus,
++                        "Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
++                        coreid, unit);
++              return;
++      }
++
++      bcma_core_mips_set_irq(core, irq);
++}
++
+ static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
+ {
+       int i;
+@@ -247,7 +263,8 @@ void bcma_core_mips_early_init(struct bc
+ void bcma_core_mips_init(struct bcma_drv_mips *mcore)
+ {
+       struct bcma_bus *bus;
+-      struct bcma_device *core;
++      int irq;
++
+       bus = mcore->core->bus;
+       if (mcore->setup_done)
+@@ -259,35 +276,44 @@ void bcma_core_mips_init(struct bcma_drv
+       mcore->assigned_irqs = 1;
+-      /* Assign IRQs to all cores on the bus */
+-      list_for_each_entry(core, &bus->cores, list) {
+-              int mips_irq;
+-              if (core->irq)
+-                      continue;
+-
+-              mips_irq = bcma_core_mips_irq(core);
+-              if (mips_irq > 4)
+-                      core->irq = 0;
+-              else
+-                      core->irq = mips_irq + 2;
+-              if (core->irq > 5)
+-                      continue;
+-              switch (core->id.id) {
+-              case BCMA_CORE_PCI:
+-              case BCMA_CORE_PCIE:
+-              case BCMA_CORE_ETHERNET:
+-              case BCMA_CORE_ETHERNET_GBIT:
+-              case BCMA_CORE_MAC_GBIT:
+-              case BCMA_CORE_80211:
+-              case BCMA_CORE_USB20_HOST:
+-                      /* These devices get their own IRQ line if available,
+-                       * the rest goes on IRQ0
+-                       */
+-                      if (mcore->assigned_irqs <= 4)
+-                              bcma_core_mips_set_irq(core,
+-                                                     mcore->assigned_irqs++);
+-                      break;
+-              }
++      switch (bus->chipinfo.id) {
++      case BCMA_CHIP_ID_BCM4716:
++      case BCMA_CHIP_ID_BCM4748:
++              bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
++              bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
++              bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
++              bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
++              bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
++              bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
++              break;
++      case BCMA_CHIP_ID_BCM5356:
++      case BCMA_CHIP_ID_BCM47162:
++      case BCMA_CHIP_ID_BCM53572:
++              bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
++              bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
++              bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
++              break;
++      case BCMA_CHIP_ID_BCM5357:
++      case BCMA_CHIP_ID_BCM4749:
++              bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
++              bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
++              bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
++              bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
++              bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
++              break;
++      case BCMA_CHIP_ID_BCM4706:
++              bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
++              bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
++                                          0);
++              bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
++              bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
++              bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
++                                          0);
++              break;
++      default:
++              bcma_err(bus,
++                       "Unknown device (0x%x) found, can not configure IRQs\n",
++                       bus->chipinfo.id);
+       }
+       bcma_info(bus, "IRQ reconfiguration done\n");
+       bcma_core_mips_dump_irq(bus);
diff --git a/target/linux/brcm47xx/patches-3.6/182-bcma-make-some-info-messages-debug.patch b/target/linux/brcm47xx/patches-3.6/182-bcma-make-some-info-messages-debug.patch
new file mode 100644 (file)
index 0000000..3506fe5
--- /dev/null
@@ -0,0 +1,40 @@
+--- a/drivers/bcma/driver_mips.c
++++ b/drivers/bcma/driver_mips.c
+@@ -144,8 +144,8 @@ static void bcma_core_mips_set_irq(struc
+                            1 << irqflag);
+       }
+-      bcma_info(bus, "set_irq: core 0x%04x, irq %d => %d\n",
+-                dev->id.id, oldirq + 2, irq + 2);
++      bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
++                 dev->id.id, oldirq + 2, irq + 2);
+ }
+ static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
+@@ -168,7 +168,7 @@ static void bcma_core_mips_print_irq(str
+ {
+       int i;
+       static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
+-      printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
++      printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
+       for (i = 0; i <= 6; i++)
+               printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
+       printk("\n");
+@@ -270,7 +270,7 @@ void bcma_core_mips_init(struct bcma_drv
+       if (mcore->setup_done)
+               return;
+-      bcma_info(bus, "Initializing MIPS core...\n");
++      bcma_debug(bus, "Initializing MIPS core...\n");
+       bcma_core_mips_early_init(mcore);
+@@ -315,7 +315,7 @@ void bcma_core_mips_init(struct bcma_drv
+                        "Unknown device (0x%x) found, can not configure IRQs\n",
+                        bus->chipinfo.id);
+       }
+-      bcma_info(bus, "IRQ reconfiguration done\n");
++      bcma_debug(bus, "IRQ reconfiguration done\n");
+       bcma_core_mips_dump_irq(bus);
+       mcore->setup_done = true;
diff --git a/target/linux/brcm47xx/patches-3.6/183-bcma-mips-show-also-disabled-irqs.patch b/target/linux/brcm47xx/patches-3.6/183-bcma-mips-show-also-disabled-irqs.patch
new file mode 100644 (file)
index 0000000..6606970
--- /dev/null
@@ -0,0 +1,49 @@
+--- a/drivers/bcma/driver_mips.c
++++ b/drivers/bcma/driver_mips.c
+@@ -75,11 +75,16 @@ static u32 bcma_core_mips_irqflag(struct
+               return dev->core_index;
+       flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
+-      return flag & 0x1F;
++      if (flag)
++              return flag & 0x1F;
++      else
++              return 0x3f;
+ }
+ /* Get the MIPS IRQ assignment for a specified device.
+  * If unassigned, 0 is returned.
++ * If disabled, 5 is returned.
++ * If not supported, 6 is returned.
+  */
+ unsigned int bcma_core_mips_irq(struct bcma_device *dev)
+ {
+@@ -88,13 +93,18 @@ unsigned int bcma_core_mips_irq(struct b
+       unsigned int irq;
+       irqflag = bcma_core_mips_irqflag(dev);
++      if (irqflag == 0x3f)
++              return 6;
+       for (irq = 1; irq <= 4; irq++)
+               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
+                   (1 << irqflag))
+                       return irq;
+-      return 0;
++      if ((1 << irqflag) & bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)))
++              return 0;
++
++      return 5;
+ }
+ EXPORT_SYMBOL(bcma_core_mips_irq);
+@@ -115,7 +125,7 @@ static void bcma_core_mips_set_irq(struc
+               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
+                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
+                           ~(1 << irqflag));
+-      else
++      else if (oldirq != 5)
+               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
+       /* assign the new one */
index cd28c66b47764ce8f6e04597c62546b8f6b3c95b..90d05bc8fd781fd4fbd10764cd7165e2f9ed0d70 100644 (file)
        cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
 --- a/drivers/bcma/driver_mips.c
 +++ b/drivers/bcma/driver_mips.c
-@@ -81,7 +81,7 @@ static u32 bcma_core_mips_irqflag(struct
/* Get the MIPS IRQ assignment for a specified device.
-  * If unassigned, 0 is returned.
+@@ -86,7 +86,7 @@ static u32 bcma_core_mips_irqflag(struct
 * If disabled, 5 is returned.
+  * If not supported, 6 is returned.
   */
 -unsigned int bcma_core_mips_irq(struct bcma_device *dev)
 +static unsigned int bcma_core_mips_irq(struct bcma_device *dev)
  {
        struct bcma_device *mdev = dev->bus->drv_mips.core;
        u32 irqflag;
-@@ -96,7 +96,12 @@ unsigned int bcma_core_mips_irq(struct b
+@@ -106,7 +106,12 @@ unsigned int bcma_core_mips_irq(struct b
  
-       return 0;
+       return 5;
  }
 -EXPORT_SYMBOL(bcma_core_mips_irq);
 +