aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-25 19:00:19 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-03 18:17:48 -0500
commit92858c476ec4e99cf0425f05dee109b6a55eb6f8 (patch)
treef2ab9eff4f07f28bfaf345d8db44f4db7c74cf0e /drivers/acpi
parent0a9efc4d91df7b18fb3e97c24ee85a1529618899 (diff)
ACPI / PM: Resume runtime-suspended devices later during system suspend
Runtime-suspended devices are resumed during system suspend by acpi_subsys_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>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/device_pm.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index c14a00d3dca6..d047739f3380 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -901,15 +901,30 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
901int acpi_subsys_prepare(struct device *dev) 901int acpi_subsys_prepare(struct device *dev)
902{ 902{
903 /* 903 /*
904 * Follow PCI and resume devices suspended at run time before running 904 * Devices having power.ignore_children set may still be necessary for
905 * their system suspend callbacks. 905 * suspending their children in the next phase of device suspend.
906 */ 906 */
907 pm_runtime_resume(dev); 907 if (dev->power.ignore_children)
908 pm_runtime_resume(dev);
909
908 return pm_generic_prepare(dev); 910 return pm_generic_prepare(dev);
909} 911}
910EXPORT_SYMBOL_GPL(acpi_subsys_prepare); 912EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
911 913
912/** 914/**
915 * acpi_subsys_suspend - Run the device driver's suspend callback.
916 * @dev: Device to handle.
917 *
918 * Follow PCI and resume devices suspended at run time before running their
919 * system suspend callbacks.
920 */
921int acpi_subsys_suspend(struct device *dev)
922{
923 pm_runtime_resume(dev);
924 return pm_generic_suspend(dev);
925}
926
927/**
913 * acpi_subsys_suspend_late - Suspend device using ACPI. 928 * acpi_subsys_suspend_late - Suspend device using ACPI.
914 * @dev: Device to suspend. 929 * @dev: Device to suspend.
915 * 930 *
@@ -937,6 +952,23 @@ int acpi_subsys_resume_early(struct device *dev)
937 return ret ? ret : pm_generic_resume_early(dev); 952 return ret ? ret : pm_generic_resume_early(dev);
938} 953}
939EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); 954EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
955
956/**
957 * acpi_subsys_freeze - Run the device driver's freeze callback.
958 * @dev: Device to handle.
959 */
960int acpi_subsys_freeze(struct device *dev)
961{
962 /*
963 * This used to be done in acpi_subsys_prepare() for all devices and
964 * some drivers may depend on it, so do it here. Ideally, however,
965 * runtime-suspended devices should not be touched during freeze/thaw
966 * transitions.
967 */
968 pm_runtime_resume(dev);
969 return pm_generic_freeze(dev);
970}
971
940#endif /* CONFIG_PM_SLEEP */ 972#endif /* CONFIG_PM_SLEEP */
941 973
942static struct dev_pm_domain acpi_general_pm_domain = { 974static struct dev_pm_domain acpi_general_pm_domain = {
@@ -947,8 +979,11 @@ static struct dev_pm_domain acpi_general_pm_domain = {
947#endif 979#endif
948#ifdef CONFIG_PM_SLEEP 980#ifdef CONFIG_PM_SLEEP
949 .prepare = acpi_subsys_prepare, 981 .prepare = acpi_subsys_prepare,
982 .suspend = acpi_subsys_suspend,
950 .suspend_late = acpi_subsys_suspend_late, 983 .suspend_late = acpi_subsys_suspend_late,
951 .resume_early = acpi_subsys_resume_early, 984 .resume_early = acpi_subsys_resume_early,
985 .freeze = acpi_subsys_freeze,
986 .poweroff = acpi_subsys_suspend,
952 .poweroff_late = acpi_subsys_suspend_late, 987 .poweroff_late = acpi_subsys_suspend_late,
953 .restore_early = acpi_subsys_resume_early, 988 .restore_early = acpi_subsys_resume_early,
954#endif 989#endif