diff options
-rw-r--r-- | drivers/acpi/bus.c | 2 | ||||
-rw-r--r-- | drivers/acpi/fan.c | 40 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 3 |
3 files changed, 43 insertions, 2 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d7a115c362d1..f4487c38d9f2 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -200,7 +200,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
200 | * Get device's current power state | 200 | * Get device's current power state |
201 | */ | 201 | */ |
202 | acpi_bus_get_power(device->handle, &device->power.state); | 202 | acpi_bus_get_power(device->handle, &device->power.state); |
203 | if (state == device->power.state) { | 203 | if ((state == device->power.state) && !device->flags.force_power_state) { |
204 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 204 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
205 | state)); | 205 | state)); |
206 | return 0; | 206 | return 0; |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index a5a5532db268..a6e149d692cb 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -47,6 +47,8 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | static int acpi_fan_add(struct acpi_device *device); | 48 | static int acpi_fan_add(struct acpi_device *device); |
49 | static int acpi_fan_remove(struct acpi_device *device, int type); | 49 | static int acpi_fan_remove(struct acpi_device *device, int type); |
50 | static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state); | ||
51 | static int acpi_fan_resume(struct acpi_device *device); | ||
50 | 52 | ||
51 | static const struct acpi_device_id fan_device_ids[] = { | 53 | static const struct acpi_device_id fan_device_ids[] = { |
52 | {"PNP0C0B", 0}, | 54 | {"PNP0C0B", 0}, |
@@ -61,6 +63,8 @@ static struct acpi_driver acpi_fan_driver = { | |||
61 | .ops = { | 63 | .ops = { |
62 | .add = acpi_fan_add, | 64 | .add = acpi_fan_add, |
63 | .remove = acpi_fan_remove, | 65 | .remove = acpi_fan_remove, |
66 | .suspend = acpi_fan_suspend, | ||
67 | .resume = acpi_fan_resume, | ||
64 | }, | 68 | }, |
65 | }; | 69 | }; |
66 | 70 | ||
@@ -191,6 +195,10 @@ static int acpi_fan_add(struct acpi_device *device) | |||
191 | goto end; | 195 | goto end; |
192 | } | 196 | } |
193 | 197 | ||
198 | device->flags.force_power_state = 1; | ||
199 | acpi_bus_set_power(device->handle, state); | ||
200 | device->flags.force_power_state = 0; | ||
201 | |||
194 | result = acpi_fan_add_fs(device); | 202 | result = acpi_fan_add_fs(device); |
195 | if (result) | 203 | if (result) |
196 | goto end; | 204 | goto end; |
@@ -216,6 +224,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
216 | return 0; | 224 | return 0; |
217 | } | 225 | } |
218 | 226 | ||
227 | static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) | ||
228 | { | ||
229 | if (!device) | ||
230 | return -EINVAL; | ||
231 | |||
232 | acpi_bus_set_power(device->handle, ACPI_STATE_D0); | ||
233 | |||
234 | return AE_OK; | ||
235 | } | ||
236 | |||
237 | static int acpi_fan_resume(struct acpi_device *device) | ||
238 | { | ||
239 | int result = 0; | ||
240 | int power_state = 0; | ||
241 | |||
242 | if (!device) | ||
243 | return -EINVAL; | ||
244 | |||
245 | result = acpi_bus_get_power(device->handle, &power_state); | ||
246 | if (result) { | ||
247 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
248 | "Error reading fan power state\n")); | ||
249 | return result; | ||
250 | } | ||
251 | |||
252 | device->flags.force_power_state = 1; | ||
253 | acpi_bus_set_power(device->handle, power_state); | ||
254 | device->flags.force_power_state = 0; | ||
255 | |||
256 | return result; | ||
257 | } | ||
258 | |||
219 | static int __init acpi_fan_init(void) | 259 | static int __init acpi_fan_init(void) |
220 | { | 260 | { |
221 | int result = 0; | 261 | int result = 0; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 19c3ead2a90b..7b74b60a68a4 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -168,7 +168,8 @@ struct acpi_device_flags { | |||
168 | u32 power_manageable:1; | 168 | u32 power_manageable:1; |
169 | u32 performance_manageable:1; | 169 | u32 performance_manageable:1; |
170 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ | 170 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ |
171 | u32 reserved:20; | 171 | u32 force_power_state:1; |
172 | u32 reserved:19; | ||
172 | }; | 173 | }; |
173 | 174 | ||
174 | /* File System */ | 175 | /* File System */ |