|
@@ -1224,11 +1224,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;
|
|
@@ -1276,16 +1279,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);
|