From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> 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.] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> --- drivers/acpi/device_pm.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) Index: linux-pm/drivers/acpi/device_pm.c =================================================================== --- linux-pm.orig/drivers/acpi/device_pm.c +++ linux-pm/drivers/acpi/device_pm.c @@ -936,7 +936,8 @@ static bool acpi_dev_needs_resume(struct u32 sys_target = acpi_target_system_state(); int ret, state; - if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count) + if (!pm_runtime_suspended(dev) || !adev || + device_may_wakeup(dev) != !!adev->wakeup.prepare_count) return true; if (sys_target == ACPI_STATE_S0) @@ -968,9 +969,6 @@ int acpi_subsys_prepare(struct device *d if (!ret && dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_PREPARE)) return 0; - if (!adev || !pm_runtime_suspended(dev)) - return 0; - return !acpi_dev_needs_resume(dev, adev); } EXPORT_SYMBOL_GPL(acpi_subsys_prepare); @@ -996,12 +994,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_complete); * acpi_subsys_suspend - Run the device driver's suspend callback. * @dev: Device to handle. * - * Follow PCI and resume devices suspended at run time before running their - * system suspend callbacks. + * Follow PCI and resume devices from runtime suspend before running their + * system suspend callbacks, unless the driver can cope with runtime-suspended + * devices during system suspend and there are no ACPI-specific reasons for + * resuming them. */ int acpi_subsys_suspend(struct device *dev) { - pm_runtime_resume(dev); + if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) || + acpi_dev_needs_resume(dev, ACPI_COMPANION(dev))) + pm_runtime_resume(dev); + return pm_generic_suspend(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_suspend); @@ -1047,7 +1050,9 @@ int acpi_subsys_freeze(struct device *de * runtime-suspended devices should not be touched during freeze/thaw * transitions. */ - pm_runtime_resume(dev); + if (!dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND)) + pm_runtime_resume(dev); + return pm_generic_freeze(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_freeze);