Merge tag 'pci-v4.17-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa...
[muen/linux.git] / drivers / pci / pci-driver.c
index 28cf87a..6ace470 100644 (file)
@@ -1237,11 +1237,14 @@ static int pci_pm_runtime_suspend(struct device *dev)
        int error;
 
        /*
-        * If pci_dev->driver is not set (unbound), the device should
-        * always remain in D0 regardless of the runtime PM status
+        * If pci_dev->driver is not set (unbound), we leave the device in D0,
+        * but it may go to D3cold when the bridge above it runtime suspends.
+        * Save its config space in case that happens.
         */
-       if (!pci_dev->driver)
+       if (!pci_dev->driver) {
+               pci_save_state(pci_dev);
                return 0;
+       }
 
        if (!pm || !pm->runtime_suspend)
                return -ENOSYS;
@@ -1289,16 +1292,18 @@ static int pci_pm_runtime_resume(struct device *dev)
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
        /*
-        * If pci_dev->driver is not set (unbound), the device should
-        * always remain in D0 regardless of the runtime PM status
+        * Restoring config space is necessary even if the device is not bound
+        * to a driver because although we left it in D0, it may have gone to
+        * D3cold when the bridge above it runtime suspended.
         */
+       pci_restore_standard_config(pci_dev);
+
        if (!pci_dev->driver)
                return 0;
 
        if (!pm || !pm->runtime_resume)
                return -ENOSYS;
 
-       pci_restore_standard_config(pci_dev);
        pci_fixup_device(pci_fixup_resume_early, pci_dev);
        pci_enable_wake(pci_dev, PCI_D0, false);
        pci_fixup_device(pci_fixup_resume, pci_dev);