summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/probe.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 95a91778bb5d..1191b02ae9f8 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2495,11 +2495,7 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
}
EXPORT_SYMBOL(pci_bus_read_dev_vendor_id);
-/*
- * Create pwrctrl device (if required) for the PCI device to handle the power
- * state.
- */
-static void pci_pwrctrl_create_device(struct pci_bus *bus, int devfn)
+static struct platform_device *pci_pwrctrl_create_device(struct pci_bus *bus, int devfn)
{
struct pci_host_bridge *host = pci_find_host_bridge(bus);
struct platform_device *pdev;
@@ -2507,7 +2503,7 @@ static void pci_pwrctrl_create_device(struct pci_bus *bus, int devfn)
np = of_pci_find_child_device(dev_of_node(&bus->dev), devfn);
if (!np || of_find_device_by_node(np))
- return;
+ return NULL;
/*
* First check whether the pwrctrl device really needs to be created or
@@ -2516,13 +2512,17 @@ static void pci_pwrctrl_create_device(struct pci_bus *bus, int devfn)
*/
if (!of_pci_supply_present(np)) {
pr_debug("PCI/pwrctrl: Skipping OF node: %s\n", np->name);
- return;
+ return NULL;
}
/* Now create the pwrctrl device */
pdev = of_platform_device_create(np, NULL, &host->dev);
- if (!pdev)
- pr_err("PCI/pwrctrl: Failed to create pwrctrl device for OF node: %s\n", np->name);
+ if (!pdev) {
+ pr_err("PCI/pwrctrl: Failed to create pwrctrl device for node: %s\n", np->name);
+ return NULL;
+ }
+
+ return pdev;
}
/*
@@ -2534,7 +2534,14 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
struct pci_dev *dev;
u32 l;
- pci_pwrctrl_create_device(bus, devfn);
+ /*
+ * Create pwrctrl device (if required) for the PCI device to handle the
+ * power state. If the pwrctrl device is created, then skip scanning
+ * further as the pwrctrl core will rescan the bus after powering on
+ * the device.
+ */
+ if (pci_pwrctrl_create_device(bus, devfn))
+ return NULL;
if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
return NULL;