base-files: define yes/no as valid boolean options
[openwrt.git] / target / linux / mvebu / patches-3.10 / 0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch
1 From 10f725e3a9e73aab2e5601206c88cf9cbc599243 Mon Sep 17 00:00:00 2001
2 From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
3 Date: Thu, 23 May 2013 16:32:52 +0200
4 Subject: [PATCH 016/203] pci: mvebu: allow the enumeration of devices beyond
5  physical bridges
6
7 Until now, the Marvell PCIe driver was only allowing the enumeration
8 of the devices in the secondary bus of the emulated PCI-to-PCI
9 bridge. This works fine when a PCIe device is directly connected into
10 a PCIe slot of the Marvell board.
11
12 However, when the device connected in the PCIe slot is a physical PCIe
13 bridge, beyond which a real PCIe device is connected, it no longer
14 worked, as the driver was preventing the Linux PCI core from seeing
15 such devices.
16
17 This commit fixes that by ensuring that configuration transactions on
18 subordinate busses are properly forwarded on the right PCIe interface.
19
20 Thanks to this patch, a PCIe card beyond a PCIe bridge, itself beyond
21 the emulated PCI-to-PCI bridge is properly detected, with the
22 following layout:
23
24 -[0000:00]-+-01.0-[01]----00.0
25            +-09.0-[02-07]----00.0-[03-07]--+-01.0-[04]--
26            |                               +-05.0-[05]--
27            |                               +-07.0-[06]--
28            |                               \-09.0-[07]----00.0
29            \-0a.0-[08]----00.0
30
31 Where the PCIe interface that sits beyond the emulated PCI-to-PCI
32 bridge at 09.0 allows to access the secondary bus 02, on which there
33 is a PCIe bridge that allows to access the 3 to 7 busses, that are
34 subordinates to this bridge. And on one of this bus (bus 7), there is
35 one real PCIe device connected.
36
37 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
38 Acked-by: Bjorn Helgaas <bhelgaas@google.com>
39 Signed-off-by: Jason Cooper <jason@lakedaemon.net>
40 ---
41  drivers/pci/host/pci-mvebu.c | 31 ++++++++++++++++++++++++++++---
42  1 file changed, 28 insertions(+), 3 deletions(-)
43
44 --- a/drivers/pci/host/pci-mvebu.c
45 +++ b/drivers/pci/host/pci-mvebu.c
46 @@ -554,7 +554,8 @@ mvebu_pcie_find_port(struct mvebu_pcie *
47                 if (bus->number == 0 && port->devfn == devfn)
48                         return port;
49                 if (bus->number != 0 &&
50 -                   port->bridge.secondary_bus == bus->number)
51 +                   bus->number >= port->bridge.secondary_bus &&
52 +                   bus->number <= port->bridge.subordinate_bus)
53                         return port;
54         }
55  
56 @@ -578,7 +579,18 @@ static int mvebu_pcie_wr_conf(struct pci
57         if (bus->number == 0)
58                 return mvebu_sw_pci_bridge_write(port, where, size, val);
59  
60 -       if (!port->haslink || PCI_SLOT(devfn) != 0)
61 +       if (!port->haslink)
62 +               return PCIBIOS_DEVICE_NOT_FOUND;
63 +
64 +       /*
65 +        * On the secondary bus, we don't want to expose any other
66 +        * device than the device physically connected in the PCIe
67 +        * slot, visible in slot 0. In slot 1, there's a special
68 +        * Marvell device that only makes sense when the Armada is
69 +        * used as a PCIe endpoint.
70 +        */
71 +       if (bus->number == port->bridge.secondary_bus &&
72 +           PCI_SLOT(devfn) != 0)
73                 return PCIBIOS_DEVICE_NOT_FOUND;
74  
75         /* Access the real PCIe interface */
76 @@ -609,7 +621,20 @@ static int mvebu_pcie_rd_conf(struct pci
77         if (bus->number == 0)
78                 return mvebu_sw_pci_bridge_read(port, where, size, val);
79  
80 -       if (!port->haslink || PCI_SLOT(devfn) != 0) {
81 +       if (!port->haslink) {
82 +               *val = 0xffffffff;
83 +               return PCIBIOS_DEVICE_NOT_FOUND;
84 +       }
85 +
86 +       /*
87 +        * On the secondary bus, we don't want to expose any other
88 +        * device than the device physically connected in the PCIe
89 +        * slot, visible in slot 0. In slot 1, there's a special
90 +        * Marvell device that only makes sense when the Armada is
91 +        * used as a PCIe endpoint.
92 +        */
93 +       if (bus->number == port->bridge.secondary_bus &&
94 +           PCI_SLOT(devfn) != 0) {
95                 *val = 0xffffffff;
96                 return PCIBIOS_DEVICE_NOT_FOUND;
97         }