aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2013-07-22 17:37:17 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-07-25 14:35:03 -0400
commit928bea964827d7824b548c1f8e06eccbbc4d0d7d (patch)
tree13110a5f05a65aa487cee8be5bd58017986f4929 /drivers/pci/pci.c
parent55ed83a615730c2578da155bc99b68f4417ffe20 (diff)
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 <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c20
1 files changed, 20 insertions, 0 deletions
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)
1145 return 0; 1145 return 0;
1146} 1146}
1147 1147
1148static void pci_enable_bridge(struct pci_dev *dev)
1149{
1150 int retval;
1151
1152 if (!dev)
1153 return;
1154
1155 pci_enable_bridge(dev->bus->self);
1156
1157 if (pci_is_enabled(dev))
1158 return;
1159 retval = pci_enable_device(dev);
1160 if (retval)
1161 dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
1162 retval);
1163 pci_set_master(dev);
1164}
1165
1148static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) 1166static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
1149{ 1167{
1150 int err; 1168 int err;
@@ -1165,6 +1183,8 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
1165 if (atomic_inc_return(&dev->enable_cnt) > 1) 1183 if (atomic_inc_return(&dev->enable_cnt) > 1)
1166 return 0; /* already enabled */ 1184 return 0; /* already enabled */
1167 1185
1186 pci_enable_bridge(dev->bus->self);
1187
1168 /* only skip sriov related */ 1188 /* only skip sriov related */
1169 for (i = 0; i <= PCI_ROM_RESOURCE; i++) 1189 for (i = 0; i <= PCI_ROM_RESOURCE; i++)
1170 if (dev->resource[i].flags & flags) 1190 if (dev->resource[i].flags & flags)