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 606f8733a776..eff696f2b6bb 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) | |||
205 | * Get device's current power state if it's unknown | 205 | * Get device's current power state if it's unknown |
206 | * This means device power state isn't initialized or previous setting failed | 206 | * This means device power state isn't initialized or previous setting failed |
207 | */ | 207 | */ |
208 | if (device->power.state == ACPI_STATE_UNKNOWN) | 208 | if (!device->flags.force_power_state) { |
209 | acpi_bus_get_power(device->handle, &device->power.state); | 209 | if (device->power.state == ACPI_STATE_UNKNOWN) |
210 | if (state == device->power.state) { | 210 | acpi_bus_get_power(device->handle, &device->power.state); |
211 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 211 | if (state == device->power.state) { |
212 | state)); | 212 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
213 | return_VALUE(0); | 213 | state)); |
214 | return_VALUE(0); | ||
215 | } | ||
214 | } | 216 | } |
215 | if (!device->power.states[state].flags.valid) { | 217 | if (!device->power.states[state].flags.valid) { |
216 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n", | 218 | 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 e8165c4f162a..1cd25784b7a4 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -48,6 +48,8 @@ MODULE_LICENSE("GPL"); | |||
48 | 48 | ||
49 | static int acpi_fan_add(struct acpi_device *device); | 49 | static int acpi_fan_add(struct acpi_device *device); |
50 | static int acpi_fan_remove(struct acpi_device *device, int type); | 50 | static int acpi_fan_remove(struct acpi_device *device, int type); |
51 | static int acpi_fan_suspend(struct acpi_device *device, int state); | ||
52 | static int acpi_fan_resume(struct acpi_device *device, int state); | ||
51 | 53 | ||
52 | static struct acpi_driver acpi_fan_driver = { | 54 | static struct acpi_driver acpi_fan_driver = { |
53 | .name = ACPI_FAN_DRIVER_NAME, | 55 | .name = ACPI_FAN_DRIVER_NAME, |
@@ -56,6 +58,8 @@ static struct acpi_driver acpi_fan_driver = { | |||
56 | .ops = { | 58 | .ops = { |
57 | .add = acpi_fan_add, | 59 | .add = acpi_fan_add, |
58 | .remove = acpi_fan_remove, | 60 | .remove = acpi_fan_remove, |
61 | .suspend = acpi_fan_suspend, | ||
62 | .resume = acpi_fan_resume, | ||
59 | }, | 63 | }, |
60 | }; | 64 | }; |
61 | 65 | ||
@@ -206,6 +210,10 @@ static int acpi_fan_add(struct acpi_device *device) | |||
206 | goto end; | 210 | goto end; |
207 | } | 211 | } |
208 | 212 | ||
213 | device->flags.force_power_state = 1; | ||
214 | acpi_bus_set_power(device->handle, state); | ||
215 | device->flags.force_power_state = 0; | ||
216 | |||
209 | result = acpi_fan_add_fs(device); | 217 | result = acpi_fan_add_fs(device); |
210 | if (result) | 218 | if (result) |
211 | goto end; | 219 | goto end; |
@@ -239,6 +247,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
239 | return_VALUE(0); | 247 | return_VALUE(0); |
240 | } | 248 | } |
241 | 249 | ||
250 | static int acpi_fan_suspend(struct acpi_device *device, int state) | ||
251 | { | ||
252 | if (!device) | ||
253 | return -EINVAL; | ||
254 | |||
255 | acpi_bus_set_power(device->handle, ACPI_STATE_D0); | ||
256 | |||
257 | return AE_OK; | ||
258 | } | ||
259 | |||
260 | static int acpi_fan_resume(struct acpi_device *device, int state) | ||
261 | { | ||
262 | int result = 0; | ||
263 | int power_state = 0; | ||
264 | |||
265 | if (!device) | ||
266 | return -EINVAL; | ||
267 | |||
268 | result = acpi_bus_get_power(device->handle, &power_state); | ||
269 | if (result) { | ||
270 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
271 | "Error reading fan power state\n")); | ||
272 | return result; | ||
273 | } | ||
274 | |||
275 | device->flags.force_power_state = 1; | ||
276 | acpi_bus_set_power(device->handle, power_state); | ||
277 | device->flags.force_power_state = 0; | ||
278 | |||
279 | return result; | ||
280 | } | ||
281 | |||
242 | static int __init acpi_fan_init(void) | 282 | static int __init acpi_fan_init(void) |
243 | { | 283 | { |
244 | int result = 0; | 284 | int result = 0; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0de199aa6b94..7f8ed9dbc7b2 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -169,7 +169,8 @@ struct acpi_device_flags { | |||
169 | u32 power_manageable:1; | 169 | u32 power_manageable:1; |
170 | u32 performance_manageable:1; | 170 | u32 performance_manageable:1; |
171 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ | 171 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ |
172 | u32 reserved:20; | 172 | u32 force_power_state:1; |
173 | u32 reserved:19; | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | /* File System */ | 176 | /* File System */ |