diff options
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.10/0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.10/0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch b/target/linux/mvebu/patches-3.10/0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch new file mode 100644 index 0000000..bda383a --- /dev/null +++ b/target/linux/mvebu/patches-3.10/0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch @@ -0,0 +1,97 @@ +From 10f725e3a9e73aab2e5601206c88cf9cbc599243 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Date: Thu, 23 May 2013 16:32:52 +0200 +Subject: [PATCH 016/203] pci: mvebu: allow the enumeration of devices beyond + physical bridges + +Until now, the Marvell PCIe driver was only allowing the enumeration +of the devices in the secondary bus of the emulated PCI-to-PCI +bridge. This works fine when a PCIe device is directly connected into +a PCIe slot of the Marvell board. + +However, when the device connected in the PCIe slot is a physical PCIe +bridge, beyond which a real PCIe device is connected, it no longer +worked, as the driver was preventing the Linux PCI core from seeing +such devices. + +This commit fixes that by ensuring that configuration transactions on +subordinate busses are properly forwarded on the right PCIe interface. + +Thanks to this patch, a PCIe card beyond a PCIe bridge, itself beyond +the emulated PCI-to-PCI bridge is properly detected, with the +following layout: + +-[0000:00]-+-01.0-[01]----00.0 + +-09.0-[02-07]----00.0-[03-07]--+-01.0-[04]-- + | +-05.0-[05]-- + | +-07.0-[06]-- + | \-09.0-[07]----00.0 + \-0a.0-[08]----00.0 + +Where the PCIe interface that sits beyond the emulated PCI-to-PCI +bridge at 09.0 allows to access the secondary bus 02, on which there +is a PCIe bridge that allows to access the 3 to 7 busses, that are +subordinates to this bridge. And on one of this bus (bus 7), there is +one real PCIe device connected. + +Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> +Acked-by: Bjorn Helgaas <bhelgaas@google.com> +Signed-off-by: Jason Cooper <jason@lakedaemon.net> +--- + drivers/pci/host/pci-mvebu.c | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +--- a/drivers/pci/host/pci-mvebu.c ++++ b/drivers/pci/host/pci-mvebu.c +@@ -554,7 +554,8 @@ mvebu_pcie_find_port(struct mvebu_pcie * + if (bus->number == 0 && port->devfn == devfn) + return port; + if (bus->number != 0 && +- port->bridge.secondary_bus == bus->number) ++ bus->number >= port->bridge.secondary_bus && ++ bus->number <= port->bridge.subordinate_bus) + return port; + } + +@@ -578,7 +579,18 @@ static int mvebu_pcie_wr_conf(struct pci + if (bus->number == 0) + return mvebu_sw_pci_bridge_write(port, where, size, val); + +- if (!port->haslink || PCI_SLOT(devfn) != 0) ++ if (!port->haslink) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ /* ++ * On the secondary bus, we don't want to expose any other ++ * device than the device physically connected in the PCIe ++ * slot, visible in slot 0. In slot 1, there's a special ++ * Marvell device that only makes sense when the Armada is ++ * used as a PCIe endpoint. ++ */ ++ if (bus->number == port->bridge.secondary_bus && ++ PCI_SLOT(devfn) != 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Access the real PCIe interface */ +@@ -609,7 +621,20 @@ static int mvebu_pcie_rd_conf(struct pci + if (bus->number == 0) + return mvebu_sw_pci_bridge_read(port, where, size, val); + +- if (!port->haslink || PCI_SLOT(devfn) != 0) { ++ if (!port->haslink) { ++ *val = 0xffffffff; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ ++ /* ++ * On the secondary bus, we don't want to expose any other ++ * device than the device physically connected in the PCIe ++ * slot, visible in slot 0. In slot 1, there's a special ++ * Marvell device that only makes sense when the Armada is ++ * used as a PCIe endpoint. ++ */ ++ if (bus->number == port->bridge.secondary_bus && ++ PCI_SLOT(devfn) != 0) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } |