diff options
-rw-r--r-- | drivers/acpi/bus.c | 14 | ||||
-rw-r--r-- | drivers/acpi/fan.c | 40 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 3 |
3 files changed, 50 insertions, 7 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 606f8733a77..eff696f2b6b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -205,12 +205,14 @@ int acpi_bus_set_power(acpi_handle handle, int state) * Get device's current power state if it's unknown * This means device power state isn't initialized or previous setting failed */ - if (device->power.state == ACPI_STATE_UNKNOWN) - acpi_bus_get_power(device->handle, &device->power.state); - if (state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", - state)); - return_VALUE(0); + if (!device->flags.force_power_state) { + if (device->power.state == ACPI_STATE_UNKNOWN) + acpi_bus_get_power(device->handle, &device->power.state); + if (state == device->power.state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", + state)); + return_VALUE(0); + } } if (!device->power.states[state].flags.valid) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index e8165c4f162..1cd25784b7a 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -48,6 +48,8 @@ MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); static int acpi_fan_remove(struct acpi_device *device, int type); +static int acpi_fan_suspend(struct acpi_device *device, int state); +static int acpi_fan_resume(struct acpi_device *device, int state); static struct acpi_driver acpi_fan_driver = { .name = ACPI_FAN_DRIVER_NAME, @@ -56,6 +58,8 @@ static struct acpi_driver acpi_fan_driver = { .ops = { .add = acpi_fan_add, .remove = acpi_fan_remove, + .suspend = acpi_fan_suspend, + .resume = acpi_fan_resume, }, }; @@ -206,6 +210,10 @@ static int acpi_fan_add(struct acpi_device *device) goto end; } + device->flags.force_power_state = 1; + acpi_bus_set_power(device->handle, state); + device->flags.force_power_state = 0; + result = acpi_fan_add_fs(device); if (result) goto end; @@ -239,6 +247,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type) return_VALUE(0); } +static int acpi_fan_suspend(struct acpi_device *device, int state) +{ + if (!device) + return -EINVAL; + + acpi_bus_set_power(device->handle, ACPI_STATE_D0); + + return AE_OK; +} + +static int acpi_fan_resume(struct acpi_device *device, int state) +{ + int result = 0; + int power_state = 0; + + if (!device) + return -EINVAL; + + result = acpi_bus_get_power(device->handle, &power_state); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Error reading fan power state\n")); + return result; + } + + device->flags.force_power_state = 1; + acpi_bus_set_power(device->handle, power_state); + device->flags.force_power_state = 0; + + return result; +} + static int __init acpi_fan_init(void) { int result = 0; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0de199aa6b9..7f8ed9dbc7b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -169,7 +169,8 @@ struct acpi_device_flags { u32 power_manageable:1; u32 performance_manageable:1; u32 wake_capable:1; /* Wakeup(_PRW) supported? */ - u32 reserved:20; + u32 force_power_state:1; + u32 reserved:19; }; /* File System */ |