diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2012-11-29 21:40:32 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2012-11-29 21:40:32 +0100 |
commit | c8b6817103b23ed42114516fea901c2f61271506 (patch) | |
tree | f3a54c55a37cfa02496de62c0f0b89f2a52dc219 /drivers/acpi | |
parent | 9489e9dcae718d5fde988e4a684a0f55b5f94d17 (diff) | |
parent | 35546bd477146b75ae2a9ff2cb9bfcdb0f701015 (diff) | |
download | linux-c8b6817103b23ed42114516fea901c2f61271506.tar.bz2 |
Merge branch 'pm-qos'
* pm-qos:
PM / QoS: Handle device PM QoS flags while removing constraints
PM / QoS: Resume device before exposing/hiding PM QoS flags
PM / QoS: Document request manipulation requirement for flags
PM / QoS: Fix a free error in the dev_pm_qos_constraints_destroy()
PM / QoS: Fix the return value of dev_pm_qos_update_request()
PM / ACPI: Take device PM QoS flags into account
PM / Domains: Check device PM QoS flags in pm_genpd_poweroff()
PM / QoS: Make it possible to expose PM QoS device flags to user space
PM / QoS: Introduce PM QoS device flags support
PM / QoS: Prepare struct dev_pm_qos_request for more request types
PM / QoS: Introduce request and constraint data types for PM QoS flags
PM / QoS: Prepare device structure for adding more constraint types
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/sleep.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index fdcdbb652915..69134653909c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -19,6 +19,7 @@ #include <linux/acpi.h> #include <linux/module.h> #include <linux/pm_runtime.h> +#include <linux/pm_qos.h> #include <asm/io.h> @@ -711,6 +712,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) struct acpi_device *adev; char acpi_method[] = "_SxD"; unsigned long long d_min, d_max; + bool wakeup = false; if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3) return -EINVAL; @@ -718,6 +720,13 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) printk(KERN_DEBUG "ACPI handle has no context!\n"); return -ENODEV; } + if (d_max_in > ACPI_STATE_D3_HOT) { + enum pm_qos_flags_status stat; + + stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF); + if (stat == PM_QOS_FLAGS_ALL) + d_max_in = ACPI_STATE_D3_HOT; + } acpi_method[2] = '0' + acpi_target_sleep_state; /* @@ -737,8 +746,14 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer * provided -- that's our fault recovery, we ignore retval. */ - if (acpi_target_sleep_state > ACPI_STATE_S0) + if (acpi_target_sleep_state > ACPI_STATE_S0) { acpi_evaluate_integer(handle, acpi_method, NULL, &d_min); + wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid + && adev->wakeup.sleep_state >= acpi_target_sleep_state; + } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) != + PM_QOS_FLAGS_NONE) { + wakeup = adev->wakeup.flags.valid; + } /* * If _PRW says we can wake up the system from the target sleep state, @@ -747,9 +762,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) * (ACPI 3.x), it should return the maximum (lowest power) D-state that * can wake the system. _S0W may be valid, too. */ - if (acpi_target_sleep_state == ACPI_STATE_S0 || - (device_may_wakeup(dev) && adev->wakeup.flags.valid && - adev->wakeup.sleep_state >= acpi_target_sleep_state)) { + if (wakeup) { acpi_status status; acpi_method[3] = 'W'; |