bcm53xx: use the final fix for iproc bcma regression
[openwrt/svn-archive/archive.git] / target / linux / bcm53xx / patches-4.1 / 041-PCI-iproc-Allow-multiple-devices-except-on-PAXC.patch
diff --git a/target/linux/bcm53xx/patches-4.1/041-PCI-iproc-Allow-multiple-devices-except-on-PAXC.patch b/target/linux/bcm53xx/patches-4.1/041-PCI-iproc-Allow-multiple-devices-except-on-PAXC.patch
new file mode 100644 (file)
index 0000000..1955c01
--- /dev/null
@@ -0,0 +1,83 @@
+From 46560388c476c8471fde7712c10f9fad8d0d1875 Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Wed, 27 Jan 2016 16:52:24 -0600
+Subject: [PATCH] PCI: iproc: Allow multiple devices except on PAXC
+
+Commit 943ebae781f5 ("PCI: iproc: Add PAXC interface support") only allowed
+device 0, which is a regression on BCMA-based platforms.
+
+All systems support only one device, a Root Port at 00:00.0, on the root
+bus.  PAXC-based systems support only the Root Port (00:00.0) and a single
+device (with multiple functions) below it, e.g., 01:00.0, 01:00.1, etc.
+Non-PAXC systems support arbitrary devices below the Root Port.
+
+[bhelgaas: changelog, fold in removal of MAX_NUM_PAXC_PF check]
+Fixes: 943ebae781f5 ("PCI: iproc: Add PAXC interface support")
+Reported-by: Rafal Milecki <zajec5@gmail.com>
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/host/pcie-iproc.c | 29 +++++++++++------------------
+ 1 file changed, 11 insertions(+), 18 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc.c
++++ b/drivers/pci/host/pcie-iproc.c
+@@ -64,7 +64,6 @@
+ #define OARR_SIZE_CFG                BIT(OARR_SIZE_CFG_SHIFT)
+ #define MAX_NUM_OB_WINDOWS           2
+-#define MAX_NUM_PAXC_PF              4
+ #define IPROC_PCIE_REG_INVALID 0xffff
+@@ -170,20 +169,6 @@ static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
+       writel(val, pcie->base + offset + (window * 8));
+ }
+-static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie,
+-                                            unsigned int slot,
+-                                            unsigned int fn)
+-{
+-      if (slot > 0)
+-              return false;
+-
+-      /* PAXC can only support limited number of functions */
+-      if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF)
+-              return false;
+-
+-      return true;
+-}
+-
+ /**
+  * Note access to the configuration registers are protected at the higher layer
+  * by 'pci_lock' in drivers/pci/access.c
+@@ -199,11 +184,11 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
+       u32 val;
+       u16 offset;
+-      if (!iproc_pcie_device_is_valid(pcie, slot, fn))
+-              return NULL;
+-
+       /* root complex access */
+       if (busno == 0) {
++              if (slot > 0 || fn > 0)
++                      return NULL;
++
+               iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
+                                    where & CFG_IND_ADDR_MASK);
+               offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
+@@ -213,6 +198,14 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
+                       return (pcie->base + offset);
+       }
++      /*
++       * PAXC is connected to an internally emulated EP within the SoC.  It
++       * allows only one device.
++       */
++      if (pcie->type == IPROC_PCIE_PAXC)
++              if (slot > 0)
++                      return NULL;
++
+       /* EP device access */
+       val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
+               (slot << CFG_ADDR_DEV_NUM_SHIFT) |