aboutsummaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki2012-11-15 00:13:50 +0100
committerRafael J. Wysocki2012-11-15 00:13:50 +0100
commitdea553e3fc63c5e53a3f8741f0c9f840660cf06e (patch)
tree3f87bc48f50c318f248934e74de8206a8597480f /drivers/acpi
parent77b67063bb6bce6d475e910d3b886a606d0d91f7 (diff)
parent7e4d68443a80574392d1027ff34992ab945934a6 (diff)
Merge branch 'pm-qos' into acpi-dev-pm
Material in the 'acpi-dev-pm' branch depends on 'pm-qos' commits.
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/sleep.c21
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';