From 928bea964827d7824b548c1f8e06eccbbc4d0d7d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 22 Jul 2013 14:37:17 -0700 Subject: PCI: Delay enabling bridges until they're needed We currently enable PCI bridges after scanning a bus and assigning resources. This is often done in arch code. This patch changes this so we don't enable a bridge until necessary, i.e., until we enable a PCI device behind the bridge. We do this in the generic pci_enable_device() path, so this also removes the arch-specific code to enable bridges. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/pci/pci.c') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e37fea6e178d..44a1a8a0ad7b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1145,6 +1145,24 @@ int pci_reenable_device(struct pci_dev *dev) return 0; } +static void pci_enable_bridge(struct pci_dev *dev) +{ + int retval; + + if (!dev) + return; + + pci_enable_bridge(dev->bus->self); + + if (pci_is_enabled(dev)) + return; + retval = pci_enable_device(dev); + if (retval) + dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", + retval); + pci_set_master(dev); +} + static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) { int err; @@ -1165,6 +1183,8 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */ + pci_enable_bridge(dev->bus->self); + /* only skip sriov related */ for (i = 0; i <= PCI_ROM_RESOURCE; i++) if (dev->resource[i].flags & flags) -- cgit v1.2.3