summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/power.c')
-rw-r--r--drivers/acpi/power.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 9466f56b938f..b820528a5fa3 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -299,9 +299,22 @@ static int acpi_power_on(struct acpi_power_resource *resource)
return result;
}
+static int __acpi_power_off(struct acpi_power_resource *resource)
+{
+ acpi_status status;
+
+ status = acpi_evaluate_object(resource->device.handle, "_OFF",
+ NULL, NULL);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned off\n",
+ resource->name));
+ return 0;
+}
+
static int acpi_power_off(struct acpi_power_resource *resource)
{
- acpi_status status = AE_OK;
int result = 0;
mutex_lock(&resource->resource_lock);
@@ -317,17 +330,12 @@ static int acpi_power_off(struct acpi_power_resource *resource)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Power resource [%s] still in use\n",
resource->name));
- goto unlock;
+ } else {
+ result = __acpi_power_off(resource);
+ if (result)
+ resource->ref_count++;
}
- status = acpi_evaluate_object(resource->device.handle, "_OFF", NULL, NULL);
- if (ACPI_FAILURE(status))
- result = -ENODEV;
- else
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Power resource [%s] turned off\n",
- resource->name));
-
unlock:
mutex_unlock(&resource->resource_lock);
@@ -851,10 +859,17 @@ void acpi_resume_power_resources(void)
mutex_lock(&resource->resource_lock);
result = acpi_power_get_state(resource->device.handle, &state);
- if (!result && state == ACPI_POWER_RESOURCE_STATE_OFF
+ if (result)
+ continue;
+
+ if (state == ACPI_POWER_RESOURCE_STATE_OFF
&& resource->ref_count) {
dev_info(&resource->device.dev, "Turning ON\n");
__acpi_power_on(resource);
+ } else if (state == ACPI_POWER_RESOURCE_STATE_ON
+ && !resource->ref_count) {
+ dev_info(&resource->device.dev, "Turning OFF\n");
+ __acpi_power_off(resource);
}
mutex_unlock(&resource->resource_lock);