diff options
Diffstat (limited to 'drivers/pci/probe.c')
| -rw-r--r-- | drivers/pci/probe.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b6536ed599c3..95a91778bb5d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -9,6 +9,8 @@ #include <linux/pci.h> #include <linux/msi.h> #include <linux/of_pci.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/pci_hotplug.h> #include <linux/slab.h> #include <linux/module.h> @@ -2494,6 +2496,36 @@ 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) +{ + struct pci_host_bridge *host = pci_find_host_bridge(bus); + struct platform_device *pdev; + struct device_node *np; + + np = of_pci_find_child_device(dev_of_node(&bus->dev), devfn); + if (!np || of_find_device_by_node(np)) + return; + + /* + * First check whether the pwrctrl device really needs to be created or + * not. This is decided based on at least one of the power supplies + * being defined in the devicetree node of the device. + */ + if (!of_pci_supply_present(np)) { + pr_debug("PCI/pwrctrl: Skipping OF node: %s\n", np->name); + return; + } + + /* 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); +} + +/* * Read the config data for a PCI device, sanity-check it, * and fill in the dev structure. */ @@ -2502,6 +2534,8 @@ 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); + if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) return NULL; |
