diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 4383a36fd6ca..41e5c45e38b5 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -379,6 +380,13 @@ void pci_bus_add_device(struct pci_dev *dev) put_device(&pdev->dev); } + /* + * Enable runtime PM, which potentially allows the device to + * suspend immediately, only after the PCI state has been + * configured completely. + */ + pm_runtime_enable(&dev->dev); + if (!dn || of_device_is_available(dn)) pci_dev_allow_binding(dev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 86ccbd0efb49..d5f4b52899ad 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3199,8 +3199,14 @@ void pci_pm_init(struct pci_dev *dev) poweron: pci_pm_power_up_and_verify_state(dev); pm_runtime_forbid(&dev->dev); + + /* + * Runtime PM will be enabled for the device when it has been fully + * configured, but since its parent and suppliers may suspend in + * the meantime, prevent them from doing so by changing the + * device's runtime PM status to "active". + */ pm_runtime_set_active(&dev->dev); - pm_runtime_enable(&dev->dev); } static unsigned long pci_ea_flags(struct pci_dev *dev, u8 prop)