brcm47xx: BCMA - Modified PCI CFG space access
authorHauke Mehrtens <hauke@hauke-m.de>
Wed, 25 Apr 2012 20:32:17 +0000 (20:32 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Wed, 25 Apr 2012 20:32:17 +0000 (20:32 +0000)
The existing code (prior to the patch) does an "ioremap_nocache" on a
subset of a memory region that I think has already been mapped, and then
un-maps that smaller region when it is finished.

Thanks Nathan Hintz for the patch

SVN-Revision: 31481

target/linux/brcm47xx/patches-3.2/240-bcma-pcie-config-access.patch [new file with mode: 0644]

diff --git a/target/linux/brcm47xx/patches-3.2/240-bcma-pcie-config-access.patch b/target/linux/brcm47xx/patches-3.2/240-bcma-pcie-config-access.patch
new file mode 100644 (file)
index 0000000..874c249
--- /dev/null
@@ -0,0 +1,104 @@
+--- a/drivers/bcma/driver_pci_host.c
++++ b/drivers/bcma/driver_pci_host.c
+@@ -99,19 +99,19 @@ static int bcma_extpci_read_config(struc
+       if (dev == 0) {
+               /* we support only two functions on device 0 */
+               if (func > 1)
+-                      return -EINVAL;
++                      goto out;
+               /* accesses to config registers with offsets >= 256
+                * requires indirect access.
+                */
+               if (off >= PCI_CONFIG_SPACE_SIZE) {
+                       addr = (func << 12);
+-                      addr |= (off & 0x0FFF);
++                      addr |= (off & 0x0FFC);
+                       val = bcma_pcie_read_config(pc, addr);
+               } else {
+                       addr = BCMA_CORE_PCI_PCICFG0;
+                       addr |= (func << 8);
+-                      addr |= (off & 0xfc);
++                      addr |= (off & 0xFC);
+                       val = pcicore_read32(pc, addr);
+               }
+       } else {
+@@ -127,8 +127,6 @@ static int bcma_extpci_read_config(struc
+                       val = 0xffffffff;
+                       goto unmap;
+               }
+-
+-              val = readl(mmio);
+       }
+       val >>= (8 * (off & 3));
+@@ -156,7 +154,7 @@ static int bcma_extpci_write_config(stru
+                                  const void *buf, int len)
+ {
+       int err = -EINVAL;
+-      u32 addr = 0, val = 0;
++      u32 addr, val;
+       void __iomem *mmio = 0;
+       u16 chipid = pc->core->bus->chipinfo.id;
+@@ -164,16 +162,22 @@ static int bcma_extpci_write_config(stru
+       if (unlikely(len != 1 && len != 2 && len != 4))
+               goto out;
+       if (dev == 0) {
++              /* we support only two functions on device 0 */
++              if (func > 1)
++                      goto out;
++
+               /* accesses to config registers with offsets >= 256
+                * requires indirect access.
+                */
+-              if (off < PCI_CONFIG_SPACE_SIZE) {
+-                      addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
++              if (off >= PCI_CONFIG_SPACE_SIZE) {
++                      addr = (func << 12);
++                      addr |= (off & 0x0FFC);
++                      val = bcma_pcie_read_config(pc, addr);
++              } else {
++                      addr = BCMA_CORE_PCI_PCICFG0;
+                       addr |= (func << 8);
+-                      addr |= (off & 0xfc);
+-                      mmio = ioremap_nocache(addr, sizeof(val));
+-                      if (!mmio)
+-                              goto out;
++                      addr |= (off & 0xFC);
++                      val = pcicore_read32(pc, addr);
+               }
+       } else {
+               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
+@@ -192,12 +196,10 @@ static int bcma_extpci_write_config(stru
+       switch (len) {
+       case 1:
+-              val = readl(mmio);
+               val &= ~(0xFF << (8 * (off & 3)));
+               val |= *((const u8 *)buf) << (8 * (off & 3));
+               break;
+       case 2:
+-              val = readl(mmio);
+               val &= ~(0xFFFF << (8 * (off & 3)));
+               val |= *((const u16 *)buf) << (8 * (off & 3));
+               break;
+@@ -205,13 +207,14 @@ static int bcma_extpci_write_config(stru
+               val = *((const u32 *)buf);
+               break;
+       }
+-      if (dev == 0 && !addr) {
++      if (dev == 0) {
+               /* accesses to config registers with offsets >= 256
+                * requires indirect access.
+                */
+-              addr = (func << 12);
+-              addr |= (off & 0x0FFF);
+-              bcma_pcie_write_config(pc, addr, val);
++              if (off >= PCI_CONFIG_SPACE_SIZE)
++                      bcma_pcie_write_config(pc, addr, val);
++              else
++                      pcicore_write32(pc, addr, val);
+       } else {
+               writel(val, mmio);