|
@@ -543,6 +543,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
|
|
|
unsigned long long ret;
|
|
|
int d_min, d_max;
|
|
|
bool wakeup = false;
|
|
|
+ bool has_sxd = false;
|
|
|
acpi_status status;
|
|
|
|
|
|
/*
|
|
@@ -581,6 +582,10 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
|
|
|
else
|
|
|
return -ENODATA;
|
|
|
}
|
|
|
+
|
|
|
+ if (status == AE_OK)
|
|
|
+ has_sxd = true;
|
|
|
+
|
|
|
d_min = ret;
|
|
|
wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
|
|
|
&& adev->wakeup.sleep_state >= target_state;
|
|
@@ -599,7 +604,11 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
|
|
|
method[3] = 'W';
|
|
|
status = acpi_evaluate_integer(handle, method, NULL, &ret);
|
|
|
if (status == AE_NOT_FOUND) {
|
|
|
- if (target_state > ACPI_STATE_S0)
|
|
|
+ /* No _SxW. In this case, the ACPI spec says that we
|
|
|
+ * must not go into any power state deeper than the
|
|
|
+ * value returned from _SxD.
|
|
|
+ */
|
|
|
+ if (has_sxd && target_state > ACPI_STATE_S0)
|
|
|
d_max = d_min;
|
|
|
} else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) {
|
|
|
/* Fall back to D3cold if ret is not a valid state. */
|