diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-10-27 11:10:16 +0300 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-11-06 15:57:47 +0300 |
commit | 05087360fd7acf2cc9b7bbb243c12765c44c7693 (patch) | |
tree | 51d845be56e5384a1d55344a7f1b97002ffeeafa /drivers/acpi/acpi_lpss.c | |
parent | c4b65157aeefad29b2351a00a010e8c40ce7fd0e (diff) | |
download | linux-05087360fd7acf2cc9b7bbb243c12765c44c7693.tar.xz |
ACPI / PM: Take SMART_SUSPEND driver flag into account
Make the ACPI PM domain take DPM_FLAG_SMART_SUSPEND into account in
its system suspend callbacks.
[Note that the pm_runtime_suspended() check in acpi_dev_needs_resume()
is an optimization, because if is not passed, all of the subsequent
checks may be skipped and some of them are much more overhead in
general.]
Also use the observation that if the device is in runtime suspend
at the beginning of the "late" phase of a system-wide suspend-like
transition, its state cannot change going forward (runtime PM is
disabled for it at that time) until the transition is over and the
subsequent system-wide PM callbacks should be skipped for it (as
they generally assume the device to not be suspended), so add
checks for that in acpi_subsys_suspend_late/noirq() and
acpi_subsys_freeze_late/noirq().
Moreover, if acpi_subsys_resume_noirq() is called during the
subsequent system-wide resume transition and if the device was left
in runtime suspend previously, its runtime PM status needs to be
changed to "active" as it is going to be put into the full-power
state going forward, so add a check for that too in there.
In turn, if acpi_subsys_thaw_noirq() runs after the device has been
left in runtime suspend, the subsequent "thaw" callbacks need
to be skipped for it (as they may not work correctly with a
suspended device), so set the power.direct_complete flag for the
device then to make the PM core skip those callbacks.
On top of the above, make the analogous changes in the acpi_lpss
driver that uses the ACPI PM domain callbacks.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/acpi/acpi_lpss.c')
-rw-r--r-- | drivers/acpi/acpi_lpss.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 04d32bdb5a95..de7385b824e1 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -849,8 +849,12 @@ static int acpi_lpss_resume(struct device *dev) #ifdef CONFIG_PM_SLEEP static int acpi_lpss_suspend_late(struct device *dev) { - int ret = pm_generic_suspend_late(dev); + int ret; + + if (dev_pm_smart_suspend_and_suspended(dev)) + return 0; + ret = pm_generic_suspend_late(dev); return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev)); } @@ -889,10 +893,17 @@ static struct dev_pm_domain acpi_lpss_pm_domain = { .complete = acpi_subsys_complete, .suspend = acpi_subsys_suspend, .suspend_late = acpi_lpss_suspend_late, + .suspend_noirq = acpi_subsys_suspend_noirq, + .resume_noirq = acpi_subsys_resume_noirq, .resume_early = acpi_lpss_resume_early, .freeze = acpi_subsys_freeze, + .freeze_late = acpi_subsys_freeze_late, + .freeze_noirq = acpi_subsys_freeze_noirq, + .thaw_noirq = acpi_subsys_thaw_noirq, .poweroff = acpi_subsys_suspend, .poweroff_late = acpi_lpss_suspend_late, + .poweroff_noirq = acpi_subsys_suspend_noirq, + .restore_noirq = acpi_subsys_resume_noirq, .restore_early = acpi_lpss_resume_early, #endif .runtime_suspend = acpi_lpss_runtime_suspend, |