===================================================================
@@ -64,6 +64,7 @@ struct acpi_power_resource {
unsigned int ref_count;
bool wakeup_enabled;
struct mutex resource_lock;
+ bool suspended;
};
struct acpi_power_resource_entry {
@@ -839,6 +840,37 @@ int acpi_add_power_resource(acpi_handle
}
#ifdef CONFIG_ACPI_SLEEP
+void acpi_suspend_power_resources(u32 acpi_state)
+{
+ struct acpi_power_resource *resource;
+
+ mutex_lock(&power_resource_list_lock);
+
+ list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
+ int result, state;
+
+ mutex_lock(&resource->resource_lock);
+
+ result = acpi_power_get_state(resource->device.handle, &state);
+ if (result) {
+ mutex_unlock(&resource->resource_lock);
+ continue;
+ }
+
+ if (state == ACPI_POWER_RESOURCE_STATE_ON
+ && resource->system_level < acpi_state) {
+ dev_info(&resource->device.dev, "Turning OFF\n");
+ __acpi_power_off(resource);
+ resource->ref_count++;
+ resource->suspended = true;
+ }
+
+ mutex_unlock(&resource->resource_lock);
+ }
+
+ mutex_unlock(&power_resource_list_lock);
+}
+
void acpi_resume_power_resources(void)
{
struct acpi_power_resource *resource;
@@ -860,6 +892,10 @@ void acpi_resume_power_resources(void)
&& resource->ref_count) {
dev_info(&resource->device.dev, "Turning ON\n");
__acpi_power_on(resource);
+ if (resource->suspended) {
+ resource->ref_count--;
+ resource->suspended = false;
+ }
}
mutex_unlock(&resource->resource_lock);
===================================================================
@@ -5,6 +5,7 @@ extern void acpi_disable_wakeup_devices(
extern struct list_head acpi_wakeup_device_list;
extern struct mutex acpi_device_lock;
+extern void acpi_suspend_power_resources(u32 acpi_state);
extern void acpi_resume_power_resources(void);
extern void acpi_turn_off_unused_power_resources(void);