From b2caa2e0b54d5247cacd81415901cf87463cede6 Mon Sep 17 00:00:00 2001
From: hauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Wed, 25 Apr 2012 20:32:17 +0000
Subject: brcm47xx: BCMA - Modified PCI CFG space access

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



git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31481 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../patches-3.2/240-bcma-pcie-config-access.patch  | 104 +++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 target/linux/brcm47xx/patches-3.2/240-bcma-pcie-config-access.patch

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
index 000000000..874c249b0
--- /dev/null
+++ b/target/linux/brcm47xx/patches-3.2/240-bcma-pcie-config-access.patch
@@ -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);
+ 
-- 
cgit v1.2.3