aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-3.10/0016-pci-mvebu-allow-the-enumeration-of-devices-beyond-ph.patch
diff options
context:
space:
mode:
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.patch97
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 0000000000..bda383a105
--- /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;
+ }