Skip to content

Commit

Permalink
PCI: Workaround missing pci_set_master in pci drivers
Browse files Browse the repository at this point in the history
Ben Herrenschmidt found that commit 928bea9 ("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>
  • Loading branch information
Yinghai Lu authored and Linus Torvalds committed Sep 28, 2013
1 parent aeebc26 commit f41f064
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,8 +1155,14 @@ static void pci_enable_bridge(struct pci_dev *dev)

pci_enable_bridge(dev->bus->self);

if (pci_is_enabled(dev))
if (pci_is_enabled(dev)) {
if (!dev->is_busmaster) {
dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n");
pci_set_master(dev);
}
return;
}

retval = pci_enable_device(dev);
if (retval)
dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
Expand Down

0 comments on commit f41f064

Please sign in to comment.