diff options
Diffstat (limited to 'drivers/acpi/device_pm.c')
-rw-r--r-- | drivers/acpi/device_pm.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index d17fac453a30..764b8dfa04aa 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -966,6 +966,27 @@ int acpi_dev_suspend_late(struct device *dev) } EXPORT_SYMBOL_GPL(acpi_dev_suspend_late); +static bool acpi_dev_needs_resume(struct device *dev, struct acpi_device *adev) +{ + u32 sys_target = acpi_target_system_state(); + int ret, state; + + if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count) + return true; + + if (sys_target == ACPI_STATE_S0) + return false; + + if (adev->power.flags.dsw_present) + return true; + + ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state); + if (ret) + return true; + + return state != adev->power.state; +} + /** * acpi_subsys_prepare - Prepare device for system transition to a sleep state. * @dev: Device to prepare. @@ -973,26 +994,16 @@ EXPORT_SYMBOL_GPL(acpi_dev_suspend_late); int acpi_subsys_prepare(struct device *dev) { struct acpi_device *adev = ACPI_COMPANION(dev); - u32 sys_target; - int ret, state; + int ret; ret = pm_generic_prepare(dev); if (ret < 0) return ret; - if (!adev || !pm_runtime_suspended(dev) - || device_may_wakeup(dev) != !!adev->wakeup.prepare_count) - return 0; - - sys_target = acpi_target_system_state(); - if (sys_target == ACPI_STATE_S0) - return 1; - - if (adev->power.flags.dsw_present) + if (!adev || !pm_runtime_suspended(dev)) return 0; - ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state); - return !ret && state == adev->power.state; + return !acpi_dev_needs_resume(dev, adev); } EXPORT_SYMBOL_GPL(acpi_subsys_prepare); |