aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-25 19:00:30 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-03 18:18:16 -0500
commit7cd0602d7836c0056fe9bdab014d5ac5ec5cb291 (patch)
tree26439c4d133faad178777b94c5fde732e7619eee /drivers/pci/pci-driver.c
parent92858c476ec4e99cf0425f05dee109b6a55eb6f8 (diff)
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: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 25f0bc659164..d911e0c1f359 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -616,15 +616,11 @@ static int pci_pm_prepare(struct device *dev)
616 int error = 0; 616 int error = 0;
617 617
618 /* 618 /*
619 * PCI devices suspended at run time need to be resumed at this 619 * Devices having power.ignore_children set may still be necessary for
620 * point, because in general it is necessary to reconfigure them for 620 * suspending their children in the next phase of device suspend.
621 * system suspend. Namely, if the device is supposed to wake up the
622 * system from the sleep state, we may need to reconfigure it for this
623 * purpose. In turn, if the device is not supposed to wake up the
624 * system from the sleep state, we'll have to prevent it from signaling
625 * wake-up.
626 */ 621 */
627 pm_runtime_resume(dev); 622 if (dev->power.ignore_children)
623 pm_runtime_resume(dev);
628 624
629 if (drv && drv->pm && drv->pm->prepare) 625 if (drv && drv->pm && drv->pm->prepare)
630 error = drv->pm->prepare(dev); 626 error = drv->pm->prepare(dev);
@@ -654,6 +650,16 @@ static int pci_pm_suspend(struct device *dev)
654 goto Fixup; 650 goto Fixup;
655 } 651 }
656 652
653 /*
654 * PCI devices suspended at run time need to be resumed at this point,
655 * because in general it is necessary to reconfigure them for system
656 * suspend. Namely, if the device is supposed to wake up the system
657 * from the sleep state, we may need to reconfigure it for this purpose.
658 * In turn, if the device is not supposed to wake up the system from the
659 * sleep state, we'll have to prevent it from signaling wake-up.
660 */
661 pm_runtime_resume(dev);
662
657 pci_dev->state_saved = false; 663 pci_dev->state_saved = false;
658 if (pm->suspend) { 664 if (pm->suspend) {
659 pci_power_t prev = pci_dev->current_state; 665 pci_power_t prev = pci_dev->current_state;
@@ -808,6 +814,14 @@ static int pci_pm_freeze(struct device *dev)
808 return 0; 814 return 0;
809 } 815 }
810 816
817 /*
818 * This used to be done in pci_pm_prepare() for all devices and some
819 * drivers may depend on it, so do it here. Ideally, runtime-suspended
820 * devices should not be touched during freeze/thaw transitions,
821 * however.
822 */
823 pm_runtime_resume(dev);
824
811 pci_dev->state_saved = false; 825 pci_dev->state_saved = false;
812 if (pm->freeze) { 826 if (pm->freeze) {
813 int error; 827 int error;
@@ -915,6 +929,9 @@ static int pci_pm_poweroff(struct device *dev)
915 goto Fixup; 929 goto Fixup;
916 } 930 }
917 931
932 /* The reason to do that is the same as in pci_pm_suspend(). */
933 pm_runtime_resume(dev);
934
918 pci_dev->state_saved = false; 935 pci_dev->state_saved = false;
919 if (pm->poweroff) { 936 if (pm->poweroff) {
920 int error; 937 int error;