diff options
| -rw-r--r-- | drivers/acpi/device_pm.c | 43 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 4 | ||||
| -rw-r--r-- | include/acpi/acpi_bus.h | 3 |
3 files changed, 42 insertions, 8 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index d047739f3380..9e5fd9c440b7 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
| @@ -900,18 +900,46 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early); | |||
| 900 | */ | 900 | */ |
| 901 | int acpi_subsys_prepare(struct device *dev) | 901 | int acpi_subsys_prepare(struct device *dev) |
| 902 | { | 902 | { |
| 903 | /* | 903 | struct acpi_device *adev = ACPI_COMPANION(dev); |
| 904 | * Devices having power.ignore_children set may still be necessary for | 904 | u32 sys_target; |
| 905 | * suspending their children in the next phase of device suspend. | 905 | int ret, state; |
| 906 | */ | 906 | |
| 907 | if (dev->power.ignore_children) | 907 | ret = pm_generic_prepare(dev); |
| 908 | pm_runtime_resume(dev); | 908 | if (ret < 0) |
| 909 | return ret; | ||
| 910 | |||
| 911 | if (!adev || !pm_runtime_suspended(dev) | ||
| 912 | || device_may_wakeup(dev) != !!adev->wakeup.prepare_count) | ||
| 913 | return 0; | ||
| 914 | |||
| 915 | sys_target = acpi_target_system_state(); | ||
| 916 | if (sys_target == ACPI_STATE_S0) | ||
| 917 | return 1; | ||
| 909 | 918 | ||
| 910 | return pm_generic_prepare(dev); | 919 | if (adev->power.flags.dsw_present) |
| 920 | return 0; | ||
| 921 | |||
| 922 | ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state); | ||
| 923 | return !ret && state == adev->power.state; | ||
| 911 | } | 924 | } |
| 912 | EXPORT_SYMBOL_GPL(acpi_subsys_prepare); | 925 | EXPORT_SYMBOL_GPL(acpi_subsys_prepare); |
| 913 | 926 | ||
| 914 | /** | 927 | /** |
| 928 | * acpi_subsys_complete - Finalize device's resume during system resume. | ||
| 929 | * @dev: Device to handle. | ||
| 930 | */ | ||
| 931 | static void acpi_subsys_complete(struct device *dev) | ||
| 932 | { | ||
| 933 | /* | ||
| 934 | * If the device had been runtime-suspended before the system went into | ||
| 935 | * the sleep state it is going out of and it has never been resumed till | ||
| 936 | * now, resume it in case the firmware powered it up. | ||
| 937 | */ | ||
| 938 | if (dev->power.direct_complete) | ||
| 939 | pm_request_resume(dev); | ||
| 940 | } | ||
| 941 | |||
| 942 | /** | ||
| 915 | * acpi_subsys_suspend - Run the device driver's suspend callback. | 943 | * acpi_subsys_suspend - Run the device driver's suspend callback. |
| 916 | * @dev: Device to handle. | 944 | * @dev: Device to handle. |
| 917 | * | 945 | * |
| @@ -979,6 +1007,7 @@ static struct dev_pm_domain acpi_general_pm_domain = { | |||
| 979 | #endif | 1007 | #endif |
| 980 | #ifdef CONFIG_PM_SLEEP | 1008 | #ifdef CONFIG_PM_SLEEP |
| 981 | .prepare = acpi_subsys_prepare, | 1009 | .prepare = acpi_subsys_prepare, |
| 1010 | .complete = acpi_subsys_complete, | ||
| 982 | .suspend = acpi_subsys_suspend, | 1011 | .suspend = acpi_subsys_suspend, |
| 983 | .suspend_late = acpi_subsys_suspend_late, | 1012 | .suspend_late = acpi_subsys_suspend_late, |
| 984 | .resume_early = acpi_subsys_resume_early, | 1013 | .resume_early = acpi_subsys_resume_early, |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7efe546a8c42..df6e4c924b35 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -1551,9 +1551,13 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) | |||
| 1551 | */ | 1551 | */ |
| 1552 | if (acpi_has_method(device->handle, "_PSC")) | 1552 | if (acpi_has_method(device->handle, "_PSC")) |
| 1553 | device->power.flags.explicit_get = 1; | 1553 | device->power.flags.explicit_get = 1; |
| 1554 | |||
| 1554 | if (acpi_has_method(device->handle, "_IRC")) | 1555 | if (acpi_has_method(device->handle, "_IRC")) |
| 1555 | device->power.flags.inrush_current = 1; | 1556 | device->power.flags.inrush_current = 1; |
| 1556 | 1557 | ||
| 1558 | if (acpi_has_method(device->handle, "_DSW")) | ||
| 1559 | device->power.flags.dsw_present = 1; | ||
| 1560 | |||
| 1557 | /* | 1561 | /* |
| 1558 | * Enumerate supported power management states | 1562 | * Enumerate supported power management states |
| 1559 | */ | 1563 | */ |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 84a2e29a2314..7417a16c8d86 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -261,7 +261,8 @@ struct acpi_device_power_flags { | |||
| 261 | u32 inrush_current:1; /* Serialize Dx->D0 */ | 261 | u32 inrush_current:1; /* Serialize Dx->D0 */ |
| 262 | u32 power_removed:1; /* Optimize Dx->D0 */ | 262 | u32 power_removed:1; /* Optimize Dx->D0 */ |
| 263 | u32 ignore_parent:1; /* Power is independent of parent power state */ | 263 | u32 ignore_parent:1; /* Power is independent of parent power state */ |
| 264 | u32 reserved:27; | 264 | u32 dsw_present:1; /* _DSW present? */ |
| 265 | u32 reserved:26; | ||
| 265 | }; | 266 | }; |
| 266 | 267 | ||
| 267 | struct acpi_device_power_state { | 268 | struct acpi_device_power_state { |
