diff options
author | Yinghai Lu <yinghai@kernel.org> | 2013-09-28 16:13:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-28 16:25:30 -0400 |
commit | f41f064cf4352e6a7fd982f1de8a690897702513 (patch) | |
tree | 4fcdb114235d5453e0c4abaa06a703f424f991d2 /drivers/pci | |
parent | aeebc264575f486c4cadc3f9d02f0049ae790c97 (diff) |
PCI: Workaround missing pci_set_master in pci drivers
Ben Herrenschmidt found that commit 928bea964827 ("PCI: Delay enabling
bridges until they're needed") breaks PCI in some powerpc environments.
The reason is that the PCIe port driver will call pci_enable_device() on
the bridge, so the device is enabled, but skips pci_set_master because
pcie_port_auto and no acpi on powerpc.
Because of that, pci_enable_bridge() later on (called as a result of the
child device driver doing pci_enable_device) will see the bridge as
already enabled and will not call pci_set_master() on it.
Fixed by add checking in pci_enable_bridge, and call pci_set_master
if driver skip that.
That will make the code more robot and wade off problem for missing
pci_set_master in drivers.
Reported-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e8ccf6c0f08a..bdd64b1b4817 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1155,8 +1155,14 @@ static void pci_enable_bridge(struct pci_dev *dev) | |||
1155 | 1155 | ||
1156 | pci_enable_bridge(dev->bus->self); | 1156 | pci_enable_bridge(dev->bus->self); |
1157 | 1157 | ||
1158 | if (pci_is_enabled(dev)) | 1158 | if (pci_is_enabled(dev)) { |
1159 | if (!dev->is_busmaster) { | ||
1160 | dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n"); | ||
1161 | pci_set_master(dev); | ||
1162 | } | ||
1159 | return; | 1163 | return; |
1164 | } | ||
1165 | |||
1160 | retval = pci_enable_device(dev); | 1166 | retval = pci_enable_device(dev); |
1161 | if (retval) | 1167 | if (retval) |
1162 | dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", | 1168 | dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", |