|
@@ -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);
|
|
|
|