Commit 7cd0602d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

PCI / PM: Resume runtime-suspended devices later during system suspend

Runtime-suspended devices are resumed during system suspend by
pci_pm_prepare() for two reasons: First, because they may need
to be reprogrammed in order to change their wakeup settings and,
second, because they may need to be operatonal for their children
to be successfully suspended.  That is a problem, though, if there
are many runtime-suspended devices that need to be resumed this
way during system suspend, because the .prepare() PM callbacks of
devices are executed sequentially and the times taken by them
accumulate, which may increase the total system suspend time quite
a bit.

For this reason, move the resume of runtime-suspended devices up
to the next phase of device suspend (during system suspend), except
for the ones that have power.ignore_children set.  The exception is
made, because the devices with power.ignore_children set may still
be necessary for their children to be successfully suspended (during
system suspend) and they won't be resumed automatically as a result
of the runtime resume of their children.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 92858c47
...@@ -616,15 +616,11 @@ static int pci_pm_prepare(struct device *dev) ...@@ -616,15 +616,11 @@ static int pci_pm_prepare(struct device *dev)
int error = 0; int error = 0;
/* /*
* PCI devices suspended at run time need to be resumed at this * Devices having power.ignore_children set may still be necessary for
* point, because in general it is necessary to reconfigure them for * suspending their children in the next phase of device suspend.
* system suspend. Namely, if the device is supposed to wake up the
* system from the sleep state, we may need to reconfigure it for this
* purpose. In turn, if the device is not supposed to wake up the
* system from the sleep state, we'll have to prevent it from signaling
* wake-up.
*/ */
pm_runtime_resume(dev); if (dev->power.ignore_children)
pm_runtime_resume(dev);
if (drv && drv->pm && drv->pm->prepare) if (drv && drv->pm && drv->pm->prepare)
error = drv->pm->prepare(dev); error = drv->pm->prepare(dev);
...@@ -654,6 +650,16 @@ static int pci_pm_suspend(struct device *dev) ...@@ -654,6 +650,16 @@ static int pci_pm_suspend(struct device *dev)
goto Fixup; goto Fixup;
} }
/*
* PCI devices suspended at run time need to be resumed at this point,
* because in general it is necessary to reconfigure them for system
* suspend. Namely, if the device is supposed to wake up the system
* from the sleep state, we may need to reconfigure it for this purpose.
* In turn, if the device is not supposed to wake up the system from the
* sleep state, we'll have to prevent it from signaling wake-up.
*/
pm_runtime_resume(dev);
pci_dev->state_saved = false; pci_dev->state_saved = false;
if (pm->suspend) { if (pm->suspend) {
pci_power_t prev = pci_dev->current_state; pci_power_t prev = pci_dev->current_state;
...@@ -808,6 +814,14 @@ static int pci_pm_freeze(struct device *dev) ...@@ -808,6 +814,14 @@ static int pci_pm_freeze(struct device *dev)
return 0; return 0;
} }
/*
* This used to be done in pci_pm_prepare() for all devices and some
* drivers may depend on it, so do it here. Ideally, runtime-suspended
* devices should not be touched during freeze/thaw transitions,
* however.
*/
pm_runtime_resume(dev);
pci_dev->state_saved = false; pci_dev->state_saved = false;
if (pm->freeze) { if (pm->freeze) {
int error; int error;
...@@ -915,6 +929,9 @@ static int pci_pm_poweroff(struct device *dev) ...@@ -915,6 +929,9 @@ static int pci_pm_poweroff(struct device *dev)
goto Fixup; goto Fixup;
} }
/* The reason to do that is the same as in pci_pm_suspend(). */
pm_runtime_resume(dev);
pci_dev->state_saved = false; pci_dev->state_saved = false;
if (pm->poweroff) { if (pm->poweroff) {
int error; int error;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment