Enable use of IRQ6 for PCIE core on 4716 (Linksys E3000), correct
resetting of previous IRQ (oldirq), and insure that
bcma_core_set_mips_irq is called for PCIE, Chipcommon and I2S cores.

Signed-off-by: Nathan Hintz <[email protected]>

--- /dev/null
+++ target/linux/brcm47xx/patches-3.6/236-bcma-fix-irq-assignment.patch
@@ -0,0 +1,132 @@
+--- a/drivers/bcma/driver_mips.c
++++ b/drivers/bcma/driver_mips.c
+@@ -65,6 +65,10 @@ static const u32 ipsflag_irq_shift[] = {
+       BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
+ };
+ 
++#define IRQ_FLAG_MASK         0x1F
++#define INVALID_IRQ_FLAG      0x3F
++#define IRQ_NOT_ASSIGNED      5
++#define IRQ_NOT_REQUIRED      6
+ static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
+ {
+       u32 flag;
+@@ -75,11 +79,14 @@ 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 & IRQ_FLAG_MASK;
++      else
++              return INVALID_IRQ_FLAG;
+ }
+ 
+ /* Get the MIPS IRQ assignment for a specified device.
+- * If unassigned, 0 is returned.
++ * If unassigned, 5 is returned; if no IRQ is required, 6 is returned
+  */
+ static unsigned int bcma_core_mips_irq(struct bcma_device *dev)
+ {
+@@ -88,22 +95,25 @@ static unsigned int bcma_core_mips_irq(s
+       unsigned int irq;
+ 
+       irqflag = bcma_core_mips_irqflag(dev);
++      if (irqflag == INVALID_IRQ_FLAG)
++              return IRQ_NOT_REQUIRED;
+ 
+-      for (irq = 1; irq <= 4; irq++)
++      for (irq = 0; irq <= 4; irq++)
+               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
+                   (1 << irqflag))
+                       return irq;
+ 
+-      return 0;
++      return IRQ_NOT_ASSIGNED;
+ }
+ 
+ unsigned int bcma_core_irq(struct bcma_device *dev)
+ {
+-      return bcma_core_mips_irq(dev) + 2;
++      unsigned int irq = bcma_core_mips_irq(dev);
++      return (irq > 4) ? 0 : (irq + 2);
+ }
+ EXPORT_SYMBOL(bcma_core_irq);
+ 
+-static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
++static bool bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
+ {
+       unsigned int oldirq = bcma_core_mips_irq(dev);
+       struct bcma_bus *bus = dev->bus;
+@@ -111,7 +121,8 @@ static void bcma_core_mips_set_irq(struc
+       u32 irqflag;
+ 
+       irqflag = bcma_core_mips_irqflag(dev);
+-      BUG_ON(oldirq == 6);
++      if (irqflag == INVALID_IRQ_FLAG)
++              return false;
+ 
+       dev->irq = irq + 2;
+ 
+@@ -120,8 +131,8 @@ 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
+-              bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
++      else if (oldirq <= 4)
++              bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
+ 
+       /* assign the new one */
+       if (irq == 0) {
+@@ -150,7 +161,9 @@ static void bcma_core_mips_set_irq(struc
+       }
+ 
+       bcma_info(bus, "set_irq: core 0x%04x, irq %d => %d\n",
+-                dev->id.id, oldirq + 2, irq + 2);
++                dev->id.id, (oldirq > 4) ? 0 : (oldirq + 2), irq + 2);
++
++      return true;
+ }
+ 
+ static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int 
irq)
+@@ -266,7 +279,7 @@ void bcma_core_mips_init(struct bcma_drv
+ 
+       /* Assign IRQs to all cores on the bus */
+       list_for_each_entry(core, &bus->cores, list) {
+-              int mips_irq;
++              unsigned int mips_irq;
+               if (core->irq)
+                       continue;
+ 
+@@ -275,8 +288,7 @@ void bcma_core_mips_init(struct bcma_drv
+                       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:
+@@ -288,9 +300,17 @@ void bcma_core_mips_init(struct bcma_drv
+                       /* 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++);
++                      if (mcore->assigned_irqs <= 4) {
++                              if (bcma_core_mips_set_irq(core,
++                                                         
mcore->assigned_irqs))
++                                      mcore->assigned_irqs++;
++                      } else {
++                              bcma_core_mips_set_irq(core, 0);
++                      }
++                      break;
++              case BCMA_CORE_CHIPCOMMON:
++              case BCMA_CORE_I2S:
++                      bcma_core_mips_set_irq(core, 0);
+                       break;
+               }
+       }

_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to