aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/internal.h1
-rw-r--r--drivers/acpi/power.c14
-rw-r--r--drivers/acpi/scan.c11
3 files changed, 26 insertions, 0 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 8a6c67c9da4..07f61dbd813 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -55,6 +55,7 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
struct list_head *list);
int acpi_add_power_resource(acpi_handle handle);
void acpi_power_add_remove_device(struct acpi_device *adev, bool add);
+int acpi_power_min_system_level(struct list_head *list);
int acpi_device_sleep_wake(struct acpi_device *dev,
int enable, int sleep_state, int dev_state);
int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 1600f753faf..089a7c39348 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -429,6 +429,20 @@ void acpi_power_add_remove_device(struct acpi_device *adev, bool add)
}
}
+int acpi_power_min_system_level(struct list_head *list)
+{
+ struct acpi_power_resource_entry *entry;
+ int system_level = 5;
+
+ list_for_each_entry(entry, list, node) {
+ struct acpi_power_resource *resource = entry->resource;
+
+ if (system_level > resource->system_level)
+ system_level = resource->system_level;
+ }
+ return system_level;
+}
+
/* --------------------------------------------------------------------------
Device Power Management
-------------------------------------------------------------------------- */
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 0b6a6b4febd..1fc57a349a3 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -950,6 +950,17 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
if (err)
goto out;
+ if (!list_empty(&wakeup->resources)) {
+ int sleep_state;
+
+ sleep_state = acpi_power_min_system_level(&wakeup->resources);
+ if (sleep_state < wakeup->sleep_state) {
+ acpi_handle_warn(handle, "Overriding _PRW sleep state "
+ "(S%d) by S%d from power resources\n",
+ (int)wakeup->sleep_state, sleep_state);
+ wakeup->sleep_state = sleep_state;
+ }
+ }
acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
out: