diff options
Diffstat (limited to 'drivers/acpi/sleep.c')
| -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 fdcdbb65291..69134653909 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';  |