aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/fan.c40
-rw-r--r--include/acpi/acpi_bus.h3
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
48static int acpi_fan_add(struct acpi_device *device); 48static int acpi_fan_add(struct acpi_device *device);
49static int acpi_fan_remove(struct acpi_device *device, int type); 49static int acpi_fan_remove(struct acpi_device *device, int type);
50static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
51static int acpi_fan_resume(struct acpi_device *device);
50 52
51static const struct acpi_device_id fan_device_ids[] = { 53static 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
227static 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
237static 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
219static int __init acpi_fan_init(void) 259static 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 */