1955c01806f6376f159c0e0b4b8d4f76749543d7
[openwrt.git] / target / linux / bcm53xx / patches-4.4 / 088-PCI-iproc-Allow-multiple-devices-except-on-PAXC.patch
1 From 46560388c476c8471fde7712c10f9fad8d0d1875 Mon Sep 17 00:00:00 2001
2 From: Ray Jui <rjui@broadcom.com>
3 Date: Wed, 27 Jan 2016 16:52:24 -0600
4 Subject: [PATCH] PCI: iproc: Allow multiple devices except on PAXC
5
6 Commit 943ebae781f5 ("PCI: iproc: Add PAXC interface support") only allowed
7 device 0, which is a regression on BCMA-based platforms.
8
9 All systems support only one device, a Root Port at 00:00.0, on the root
10 bus.  PAXC-based systems support only the Root Port (00:00.0) and a single
11 device (with multiple functions) below it, e.g., 01:00.0, 01:00.1, etc.
12 Non-PAXC systems support arbitrary devices below the Root Port.
13
14 [bhelgaas: changelog, fold in removal of MAX_NUM_PAXC_PF check]
15 Fixes: 943ebae781f5 ("PCI: iproc: Add PAXC interface support")
16 Reported-by: Rafal Milecki <zajec5@gmail.com>
17 Signed-off-by: Ray Jui <rjui@broadcom.com>
18 Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
19 ---
20  drivers/pci/host/pcie-iproc.c | 29 +++++++++++------------------
21  1 file changed, 11 insertions(+), 18 deletions(-)
22
23 --- a/drivers/pci/host/pcie-iproc.c
24 +++ b/drivers/pci/host/pcie-iproc.c
25 @@ -64,7 +64,6 @@
26  #define OARR_SIZE_CFG                BIT(OARR_SIZE_CFG_SHIFT)
27  
28  #define MAX_NUM_OB_WINDOWS           2
29 -#define MAX_NUM_PAXC_PF              4
30  
31  #define IPROC_PCIE_REG_INVALID 0xffff
32  
33 @@ -170,20 +169,6 @@ static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
34         writel(val, pcie->base + offset + (window * 8));
35  }
36  
37 -static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie,
38 -                                             unsigned int slot,
39 -                                             unsigned int fn)
40 -{
41 -       if (slot > 0)
42 -               return false;
43 -
44 -       /* PAXC can only support limited number of functions */
45 -       if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF)
46 -               return false;
47 -
48 -       return true;
49 -}
50 -
51  /**
52   * Note access to the configuration registers are protected at the higher layer
53   * by 'pci_lock' in drivers/pci/access.c
54 @@ -199,11 +184,11 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
55         u32 val;
56         u16 offset;
57  
58 -       if (!iproc_pcie_device_is_valid(pcie, slot, fn))
59 -               return NULL;
60 -
61         /* root complex access */
62         if (busno == 0) {
63 +               if (slot > 0 || fn > 0)
64 +                       return NULL;
65 +
66                 iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
67                                      where & CFG_IND_ADDR_MASK);
68                 offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
69 @@ -213,6 +198,14 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
70                         return (pcie->base + offset);
71         }
72  
73 +       /*
74 +        * PAXC is connected to an internally emulated EP within the SoC.  It
75 +        * allows only one device.
76 +        */
77 +       if (pcie->type == IPROC_PCIE_PAXC)
78 +               if (slot > 0)
79 +                       return NULL;
80 +
81         /* EP device access */
82         val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
83                 (slot << CFG_ADDR_DEV_NUM_SHIFT) |