aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig8
-rw-r--r--drivers/acpi/battery.c164
-rw-r--r--drivers/acpi/bus.c8
-rw-r--r--drivers/acpi/button.c37
-rw-r--r--drivers/acpi/ec.c146
-rw-r--r--drivers/acpi/fan.c72
-rw-r--r--drivers/acpi/power.c63
-rw-r--r--drivers/acpi/sleep/main.c5
8 files changed, 236 insertions, 267 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 5d0e26a5c34c..ecd87d7aa9f6 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -88,7 +88,8 @@ config ACPI_PROC_EVENT
88 88
89config ACPI_AC 89config ACPI_AC
90 tristate "AC Adapter" 90 tristate "AC Adapter"
91 depends on X86 && POWER_SUPPLY 91 depends on X86
92 select POWER_SUPPLY
92 default y 93 default y
93 help 94 help
94 This driver adds support for the AC Adapter object, which indicates 95 This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +98,8 @@ config ACPI_AC
97 98
98config ACPI_BATTERY 99config ACPI_BATTERY
99 tristate "Battery" 100 tristate "Battery"
100 depends on X86 && POWER_SUPPLY 101 depends on X86
102 select POWER_SUPPLY
101 default y 103 default y
102 help 104 help
103 This driver adds support for battery information through 105 This driver adds support for battery information through
@@ -352,7 +354,7 @@ config ACPI_HOTPLUG_MEMORY
352config ACPI_SBS 354config ACPI_SBS
353 tristate "Smart Battery System" 355 tristate "Smart Battery System"
354 depends on X86 356 depends on X86
355 depends on POWER_SUPPLY 357 select POWER_SUPPLY
356 help 358 help
357 This driver adds support for the Smart Battery System, another 359 This driver adds support for the Smart Battery System, another
358 type of access to battery information, found on some laptops. 360 type of access to battery information, found on some laptops.
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 681e26b56b11..c2ce0ad21693 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -125,11 +125,15 @@ static int acpi_battery_technology(struct acpi_battery *battery)
125 return POWER_SUPPLY_TECHNOLOGY_NiMH; 125 return POWER_SUPPLY_TECHNOLOGY_NiMH;
126 if (!strcasecmp("LION", battery->type)) 126 if (!strcasecmp("LION", battery->type))
127 return POWER_SUPPLY_TECHNOLOGY_LION; 127 return POWER_SUPPLY_TECHNOLOGY_LION;
128 if (!strcasecmp("LI-ION", battery->type))
129 return POWER_SUPPLY_TECHNOLOGY_LION;
128 if (!strcasecmp("LiP", battery->type)) 130 if (!strcasecmp("LiP", battery->type))
129 return POWER_SUPPLY_TECHNOLOGY_LIPO; 131 return POWER_SUPPLY_TECHNOLOGY_LIPO;
130 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 132 return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
131} 133}
132 134
135static int acpi_battery_update(struct acpi_battery *battery);
136
133static int acpi_battery_get_property(struct power_supply *psy, 137static int acpi_battery_get_property(struct power_supply *psy,
134 enum power_supply_property psp, 138 enum power_supply_property psp,
135 union power_supply_propval *val) 139 union power_supply_propval *val)
@@ -139,6 +143,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
139 if ((!acpi_battery_present(battery)) && 143 if ((!acpi_battery_present(battery)) &&
140 psp != POWER_SUPPLY_PROP_PRESENT) 144 psp != POWER_SUPPLY_PROP_PRESENT)
141 return -ENODEV; 145 return -ENODEV;
146 acpi_battery_update(battery);
142 switch (psp) { 147 switch (psp) {
143 case POWER_SUPPLY_PROP_STATUS: 148 case POWER_SUPPLY_PROP_STATUS:
144 if (battery->state & 0x01) 149 if (battery->state & 0x01)
@@ -257,7 +262,7 @@ static int extract_package(struct acpi_battery *battery,
257 union acpi_object *package, 262 union acpi_object *package,
258 struct acpi_offsets *offsets, int num) 263 struct acpi_offsets *offsets, int num)
259{ 264{
260 int i, *x; 265 int i;
261 union acpi_object *element; 266 union acpi_object *element;
262 if (package->type != ACPI_TYPE_PACKAGE) 267 if (package->type != ACPI_TYPE_PACKAGE)
263 return -EFAULT; 268 return -EFAULT;
@@ -266,16 +271,21 @@ static int extract_package(struct acpi_battery *battery,
266 return -EFAULT; 271 return -EFAULT;
267 element = &package->package.elements[i]; 272 element = &package->package.elements[i];
268 if (offsets[i].mode) { 273 if (offsets[i].mode) {
269 if (element->type != ACPI_TYPE_STRING && 274 u8 *ptr = (u8 *)battery + offsets[i].offset;
270 element->type != ACPI_TYPE_BUFFER) 275 if (element->type == ACPI_TYPE_STRING ||
271 return -EFAULT; 276 element->type == ACPI_TYPE_BUFFER)
272 strncpy((u8 *)battery + offsets[i].offset, 277 strncpy(ptr, element->string.pointer, 32);
273 element->string.pointer, 32); 278 else if (element->type == ACPI_TYPE_INTEGER) {
279 strncpy(ptr, (u8 *)&element->integer.value,
280 sizeof(acpi_integer));
281 ptr[sizeof(acpi_integer)] = 0;
282 } else return -EFAULT;
274 } else { 283 } else {
275 if (element->type != ACPI_TYPE_INTEGER) 284 if (element->type == ACPI_TYPE_INTEGER) {
276 return -EFAULT; 285 int *x = (int *)((u8 *)battery +
277 x = (int *)((u8 *)battery + offsets[i].offset); 286 offsets[i].offset);
278 *x = element->integer.value; 287 *x = element->integer.value;
288 } else return -EFAULT;
279 } 289 }
280 } 290 }
281 return 0; 291 return 0;
@@ -385,29 +395,81 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
385 return acpi_battery_set_alarm(battery); 395 return acpi_battery_set_alarm(battery);
386} 396}
387 397
398static ssize_t acpi_battery_alarm_show(struct device *dev,
399 struct device_attribute *attr,
400 char *buf)
401{
402 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
403 return sprintf(buf, "%d\n", battery->alarm * 1000);
404}
405
406static ssize_t acpi_battery_alarm_store(struct device *dev,
407 struct device_attribute *attr,
408 const char *buf, size_t count)
409{
410 unsigned long x;
411 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
412 if (sscanf(buf, "%ld\n", &x) == 1)
413 battery->alarm = x/1000;
414 if (acpi_battery_present(battery))
415 acpi_battery_set_alarm(battery);
416 return count;
417}
418
419static struct device_attribute alarm_attr = {
420 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
421 .show = acpi_battery_alarm_show,
422 .store = acpi_battery_alarm_store,
423};
424
425static int sysfs_add_battery(struct acpi_battery *battery)
426{
427 int result;
428
429 battery->update_time = 0;
430 result = acpi_battery_get_info(battery);
431 acpi_battery_init_alarm(battery);
432 if (result)
433 return result;
434 if (battery->power_unit) {
435 battery->bat.properties = charge_battery_props;
436 battery->bat.num_properties =
437 ARRAY_SIZE(charge_battery_props);
438 } else {
439 battery->bat.properties = energy_battery_props;
440 battery->bat.num_properties =
441 ARRAY_SIZE(energy_battery_props);
442 }
443
444 battery->bat.name = acpi_device_bid(battery->device);
445 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
446 battery->bat.get_property = acpi_battery_get_property;
447
448 result = power_supply_register(&battery->device->dev, &battery->bat);
449 if (result)
450 return result;
451 return device_create_file(battery->bat.dev, &alarm_attr);
452}
453
454static void sysfs_remove_battery(struct acpi_battery *battery)
455{
456 if (!battery->bat.dev)
457 return;
458 device_remove_file(battery->bat.dev, &alarm_attr);
459 power_supply_unregister(&battery->bat);
460}
461
388static int acpi_battery_update(struct acpi_battery *battery) 462static int acpi_battery_update(struct acpi_battery *battery)
389{ 463{
390 int saved_present = acpi_battery_present(battery);
391 int result = acpi_battery_get_status(battery); 464 int result = acpi_battery_get_status(battery);
392 if (result || !acpi_battery_present(battery)) 465 if (result)
393 return result; 466 return result;
394 if (saved_present != acpi_battery_present(battery) || 467 if (!acpi_battery_present(battery)) {
395 !battery->update_time) { 468 sysfs_remove_battery(battery);
396 battery->update_time = 0; 469 return 0;
397 result = acpi_battery_get_info(battery);
398 if (result)
399 return result;
400 if (battery->power_unit) {
401 battery->bat.properties = charge_battery_props;
402 battery->bat.num_properties =
403 ARRAY_SIZE(charge_battery_props);
404 } else {
405 battery->bat.properties = energy_battery_props;
406 battery->bat.num_properties =
407 ARRAY_SIZE(energy_battery_props);
408 }
409 acpi_battery_init_alarm(battery);
410 } 470 }
471 if (!battery->bat.dev)
472 sysfs_add_battery(battery);
411 return acpi_battery_get_state(battery); 473 return acpi_battery_get_state(battery);
412} 474}
413 475
@@ -554,10 +616,6 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
554 616
555 if (!battery || (count > sizeof(alarm_string) - 1)) 617 if (!battery || (count > sizeof(alarm_string) - 1))
556 return -EINVAL; 618 return -EINVAL;
557 if (result) {
558 result = -ENODEV;
559 goto end;
560 }
561 if (!acpi_battery_present(battery)) { 619 if (!acpi_battery_present(battery)) {
562 result = -ENODEV; 620 result = -ENODEV;
563 goto end; 621 goto end;
@@ -688,33 +746,6 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
688 746
689#endif 747#endif
690 748
691static ssize_t acpi_battery_alarm_show(struct device *dev,
692 struct device_attribute *attr,
693 char *buf)
694{
695 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
696 return sprintf(buf, "%d\n", battery->alarm * 1000);
697}
698
699static ssize_t acpi_battery_alarm_store(struct device *dev,
700 struct device_attribute *attr,
701 const char *buf, size_t count)
702{
703 unsigned long x;
704 struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
705 if (sscanf(buf, "%ld\n", &x) == 1)
706 battery->alarm = x/1000;
707 if (acpi_battery_present(battery))
708 acpi_battery_set_alarm(battery);
709 return count;
710}
711
712static struct device_attribute alarm_attr = {
713 .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
714 .show = acpi_battery_alarm_show,
715 .store = acpi_battery_alarm_store,
716};
717
718/* -------------------------------------------------------------------------- 749/* --------------------------------------------------------------------------
719 Driver Interface 750 Driver Interface
720 -------------------------------------------------------------------------- */ 751 -------------------------------------------------------------------------- */
@@ -732,7 +763,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
732 acpi_bus_generate_netlink_event(device->pnp.device_class, 763 acpi_bus_generate_netlink_event(device->pnp.device_class,
733 device->dev.bus_id, event, 764 device->dev.bus_id, event,
734 acpi_battery_present(battery)); 765 acpi_battery_present(battery));
735 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); 766 /* acpi_batter_update could remove power_supply object */
767 if (battery->bat.dev)
768 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
736} 769}
737 770
738static int acpi_battery_add(struct acpi_device *device) 771static int acpi_battery_add(struct acpi_device *device)
@@ -756,11 +789,6 @@ static int acpi_battery_add(struct acpi_device *device)
756 if (result) 789 if (result)
757 goto end; 790 goto end;
758#endif 791#endif
759 battery->bat.name = acpi_device_bid(device);
760 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
761 battery->bat.get_property = acpi_battery_get_property;
762 result = power_supply_register(&battery->device->dev, &battery->bat);
763 result = device_create_file(battery->bat.dev, &alarm_attr);
764 status = acpi_install_notify_handler(device->handle, 792 status = acpi_install_notify_handler(device->handle,
765 ACPI_ALL_NOTIFY, 793 ACPI_ALL_NOTIFY,
766 acpi_battery_notify, battery); 794 acpi_battery_notify, battery);
@@ -796,10 +824,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
796#ifdef CONFIG_ACPI_PROCFS 824#ifdef CONFIG_ACPI_PROCFS
797 acpi_battery_remove_fs(device); 825 acpi_battery_remove_fs(device);
798#endif 826#endif
799 if (battery->bat.dev) { 827 sysfs_remove_battery(battery);
800 device_remove_file(battery->bat.dev, &alarm_attr);
801 power_supply_unregister(&battery->bat);
802 }
803 mutex_destroy(&battery->lock); 828 mutex_destroy(&battery->lock);
804 kfree(battery); 829 kfree(battery);
805 return 0; 830 return 0;
@@ -813,6 +838,7 @@ static int acpi_battery_resume(struct acpi_device *device)
813 return -EINVAL; 838 return -EINVAL;
814 battery = acpi_driver_data(device); 839 battery = acpi_driver_data(device);
815 battery->update_time = 0; 840 battery->update_time = 0;
841 acpi_battery_update(battery);
816 return 0; 842 return 0;
817} 843}
818 844
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index fb2cff9a2d24..49d432d0a12c 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -198,12 +198,10 @@ int acpi_bus_set_power(acpi_handle handle, int state)
198 return -ENODEV; 198 return -ENODEV;
199 } 199 }
200 /* 200 /*
201 * Get device's current power state if it's unknown 201 * Get device's current power state
202 * This means device power state isn't initialized or previous setting failed
203 */ 202 */
204 if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state) 203 acpi_bus_get_power(device->handle, &device->power.state);
205 acpi_bus_get_power(device->handle, &device->power.state); 204 if (state == device->power.state) {
206 if ((state == device->power.state) && !device->flags.force_power_state) {
207 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", 205 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
208 state)); 206 state));
209 return 0; 207 return 0;
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 301e832e6961..24a7865a57cb 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
78 78
79static int acpi_button_add(struct acpi_device *device); 79static int acpi_button_add(struct acpi_device *device);
80static int acpi_button_remove(struct acpi_device *device, int type); 80static int acpi_button_remove(struct acpi_device *device, int type);
81static int acpi_button_resume(struct acpi_device *device);
81static int acpi_button_info_open_fs(struct inode *inode, struct file *file); 82static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
82static int acpi_button_state_open_fs(struct inode *inode, struct file *file); 83static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
83 84
@@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
87 .ids = button_device_ids, 88 .ids = button_device_ids,
88 .ops = { 89 .ops = {
89 .add = acpi_button_add, 90 .add = acpi_button_add,
91 .resume = acpi_button_resume,
90 .remove = acpi_button_remove, 92 .remove = acpi_button_remove,
91 }, 93 },
92}; 94};
@@ -253,6 +255,19 @@ static int acpi_button_remove_fs(struct acpi_device *device)
253/* -------------------------------------------------------------------------- 255/* --------------------------------------------------------------------------
254 Driver Interface 256 Driver Interface
255 -------------------------------------------------------------------------- */ 257 -------------------------------------------------------------------------- */
258static int acpi_lid_send_state(struct acpi_button *button)
259{
260 unsigned long state;
261 acpi_status status;
262
263 status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
264 &state);
265 if (ACPI_FAILURE(status))
266 return -ENODEV;
267 /* input layer checks if event is redundant */
268 input_report_switch(button->input, SW_LID, !state);
269 return 0;
270}
256 271
257static void acpi_button_notify(acpi_handle handle, u32 event, void *data) 272static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
258{ 273{
@@ -265,15 +280,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
265 switch (event) { 280 switch (event) {
266 case ACPI_BUTTON_NOTIFY_STATUS: 281 case ACPI_BUTTON_NOTIFY_STATUS:
267 input = button->input; 282 input = button->input;
268
269 if (button->type == ACPI_BUTTON_TYPE_LID) { 283 if (button->type == ACPI_BUTTON_TYPE_LID) {
270 struct acpi_handle *handle = button->device->handle; 284 acpi_lid_send_state(button);
271 unsigned long state;
272
273 if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
274 NULL, &state)))
275 input_report_switch(input, SW_LID, !state);
276
277 } else { 285 } else {
278 int keycode = test_bit(KEY_SLEEP, input->keybit) ? 286 int keycode = test_bit(KEY_SLEEP, input->keybit) ?
279 KEY_SLEEP : KEY_POWER; 287 KEY_SLEEP : KEY_POWER;
@@ -336,6 +344,17 @@ static int acpi_button_install_notify_handlers(struct acpi_button *button)
336 return ACPI_FAILURE(status) ? -ENODEV : 0; 344 return ACPI_FAILURE(status) ? -ENODEV : 0;
337} 345}
338 346
347static int acpi_button_resume(struct acpi_device *device)
348{
349 struct acpi_button *button;
350 if (!device)
351 return -EINVAL;
352 button = acpi_driver_data(device);
353 if (button && button->type == ACPI_BUTTON_TYPE_LID)
354 return acpi_lid_send_state(button);
355 return 0;
356}
357
339static void acpi_button_remove_notify_handlers(struct acpi_button *button) 358static void acpi_button_remove_notify_handlers(struct acpi_button *button)
340{ 359{
341 switch (button->type) { 360 switch (button->type) {
@@ -453,6 +472,8 @@ static int acpi_button_add(struct acpi_device *device)
453 error = input_register_device(input); 472 error = input_register_device(input);
454 if (error) 473 if (error)
455 goto err_remove_handlers; 474 goto err_remove_handlers;
475 if (button->type == ACPI_BUTTON_TYPE_LID)
476 acpi_lid_send_state(button);
456 477
457 if (device->wakeup.flags.valid) { 478 if (device->wakeup.flags.valid) {
458 /* Button's GPE is run-wake GPE */ 479 /* Button's GPE is run-wake GPE */
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 7b4178393e34..06b78e5e33a1 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -65,16 +65,18 @@ enum ec_command {
65/* EC events */ 65/* EC events */
66enum ec_event { 66enum ec_event {
67 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ 67 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
68 ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ 68 ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
69}; 69};
70 70
71#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ 71#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
72#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ 72#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
73 73
74static enum ec_mode { 74enum {
75 EC_INTR = 1, /* Output buffer full */ 75 EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
76 EC_POLL, /* Input buffer empty */ 76 EC_FLAGS_QUERY_PENDING, /* Query is pending */
77} acpi_ec_mode = EC_INTR; 77 EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
78 EC_FLAGS_ONLY_IBF_GPE, /* Expect GPE only for IBF = 0 event */
79};
78 80
79static int acpi_ec_remove(struct acpi_device *device, int type); 81static int acpi_ec_remove(struct acpi_device *device, int type);
80static int acpi_ec_start(struct acpi_device *device); 82static int acpi_ec_start(struct acpi_device *device);
@@ -116,9 +118,8 @@ static struct acpi_ec {
116 unsigned long command_addr; 118 unsigned long command_addr;
117 unsigned long data_addr; 119 unsigned long data_addr;
118 unsigned long global_lock; 120 unsigned long global_lock;
121 unsigned long flags;
119 struct mutex lock; 122 struct mutex lock;
120 atomic_t query_pending;
121 atomic_t event_count;
122 wait_queue_head_t wait; 123 wait_queue_head_t wait;
123 struct list_head list; 124 struct list_head list;
124 u8 handlers_installed; 125 u8 handlers_installed;
@@ -148,45 +149,54 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
148 outb(data, ec->data_addr); 149 outb(data, ec->data_addr);
149} 150}
150 151
151static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event, 152static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
152 unsigned old_count)
153{ 153{
154 u8 status = acpi_ec_read_status(ec); 154 if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
155 if (old_count == atomic_read(&ec->event_count))
156 return 0; 155 return 0;
157 if (event == ACPI_EC_EVENT_OBF_1) { 156 if (event == ACPI_EC_EVENT_OBF_1) {
158 if (status & ACPI_EC_FLAG_OBF) 157 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
159 return 1; 158 return 1;
160 } else if (event == ACPI_EC_EVENT_IBF_0) { 159 } else if (event == ACPI_EC_EVENT_IBF_0) {
161 if (!(status & ACPI_EC_FLAG_IBF)) 160 if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
162 return 1; 161 return 1;
163 } 162 }
164 163
165 return 0; 164 return 0;
166} 165}
167 166
168static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, 167static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
169 unsigned count, int force_poll)
170{ 168{
171 if (unlikely(force_poll) || acpi_ec_mode == EC_POLL) { 169 if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
170 likely(!force_poll)) {
171 if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
172 msecs_to_jiffies(ACPI_EC_DELAY)))
173 return 0;
174 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
175 if (acpi_ec_check_status(ec, event)) {
176 if (event == ACPI_EC_EVENT_OBF_1) {
177 /* miss OBF = 1 GPE, don't expect it anymore */
178 printk(KERN_INFO PREFIX "missing OBF_1 confirmation,"
179 "switching to degraded mode.\n");
180 set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags);
181 } else {
182 /* missing GPEs, switch back to poll mode */
183 printk(KERN_INFO PREFIX "missing IBF_1 confirmations,"
184 "switch off interrupt mode.\n");
185 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
186 }
187 return 0;
188 }
189 } else {
172 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); 190 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
191 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
173 while (time_before(jiffies, delay)) { 192 while (time_before(jiffies, delay)) {
174 if (acpi_ec_check_status(ec, event, 0)) 193 if (acpi_ec_check_status(ec, event))
175 return 0; 194 return 0;
176 } 195 }
177 } else { 196 }
178 if (wait_event_timeout(ec->wait, 197 printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
179 acpi_ec_check_status(ec, event, count),
180 msecs_to_jiffies(ACPI_EC_DELAY)) ||
181 acpi_ec_check_status(ec, event, 0)) {
182 return 0;
183 } else {
184 printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
185 " status = %d, expect_event = %d\n", 198 " status = %d, expect_event = %d\n",
186 acpi_ec_read_status(ec), event); 199 acpi_ec_read_status(ec), event);
187 }
188 }
189
190 return -ETIME; 200 return -ETIME;
191} 201}
192 202
@@ -196,39 +206,42 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
196 int force_poll) 206 int force_poll)
197{ 207{
198 int result = 0; 208 int result = 0;
199 unsigned count = atomic_read(&ec->event_count); 209 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
200 acpi_ec_write_cmd(ec, command); 210 acpi_ec_write_cmd(ec, command);
201 211
202 for (; wdata_len > 0; --wdata_len) { 212 for (; wdata_len > 0; --wdata_len) {
203 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll); 213 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
204 if (result) { 214 if (result) {
205 printk(KERN_ERR PREFIX 215 printk(KERN_ERR PREFIX
206 "write_cmd timeout, command = %d\n", command); 216 "write_cmd timeout, command = %d\n", command);
207 goto end; 217 goto end;
208 } 218 }
209 count = atomic_read(&ec->event_count); 219 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
210 acpi_ec_write_data(ec, *(wdata++)); 220 acpi_ec_write_data(ec, *(wdata++));
211 } 221 }
212 222
213 if (!rdata_len) { 223 if (!rdata_len) {
214 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll); 224 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
215 if (result) { 225 if (result) {
216 printk(KERN_ERR PREFIX 226 printk(KERN_ERR PREFIX
217 "finish-write timeout, command = %d\n", command); 227 "finish-write timeout, command = %d\n", command);
218 goto end; 228 goto end;
219 } 229 }
220 } else if (command == ACPI_EC_COMMAND_QUERY) { 230 } else if (command == ACPI_EC_COMMAND_QUERY)
221 atomic_set(&ec->query_pending, 0); 231 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
222 }
223 232
224 for (; rdata_len > 0; --rdata_len) { 233 for (; rdata_len > 0; --rdata_len) {
225 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count, force_poll); 234 if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags))
235 force_poll = 1;
236 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
226 if (result) { 237 if (result) {
227 printk(KERN_ERR PREFIX "read timeout, command = %d\n", 238 printk(KERN_ERR PREFIX "read timeout, command = %d\n",
228 command); 239 command);
229 goto end; 240 goto end;
230 } 241 }
231 count = atomic_read(&ec->event_count); 242 /* Don't expect GPE after last read */
243 if (rdata_len > 1)
244 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
232 *(rdata++) = acpi_ec_read_data(ec); 245 *(rdata++) = acpi_ec_read_data(ec);
233 } 246 }
234 end: 247 end:
@@ -258,10 +271,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
258 } 271 }
259 } 272 }
260 273
261 /* Make sure GPE is enabled before doing transaction */ 274 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
262 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
263
264 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
265 if (status) { 275 if (status) {
266 printk(KERN_ERR PREFIX 276 printk(KERN_ERR PREFIX
267 "input buffer is not empty, aborting transaction\n"); 277 "input buffer is not empty, aborting transaction\n");
@@ -435,9 +445,9 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
435 445
436void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) 446void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
437{ 447{
438 struct acpi_ec_query_handler *handler; 448 struct acpi_ec_query_handler *handler, *tmp;
439 mutex_lock(&ec->lock); 449 mutex_lock(&ec->lock);
440 list_for_each_entry(handler, &ec->list, node) { 450 list_for_each_entry_safe(handler, tmp, &ec->list, node) {
441 if (query_bit == handler->query_bit) { 451 if (query_bit == handler->query_bit) {
442 list_del(&handler->node); 452 list_del(&handler->node);
443 kfree(handler); 453 kfree(handler);
@@ -476,23 +486,24 @@ static void acpi_ec_gpe_query(void *ec_cxt)
476static u32 acpi_ec_gpe_handler(void *data) 486static u32 acpi_ec_gpe_handler(void *data)
477{ 487{
478 acpi_status status = AE_OK; 488 acpi_status status = AE_OK;
479 u8 value;
480 struct acpi_ec *ec = data; 489 struct acpi_ec *ec = data;
481 490
482 atomic_inc(&ec->event_count); 491 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
483 492 if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
484 if (acpi_ec_mode == EC_INTR) {
485 wake_up(&ec->wait); 493 wake_up(&ec->wait);
486 }
487 494
488 value = acpi_ec_read_status(ec); 495 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) {
489 if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { 496 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
490 atomic_set(&ec->query_pending, 1); 497 status = acpi_os_execute(OSL_EC_BURST_HANDLER,
491 status = 498 acpi_ec_gpe_query, ec);
492 acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); 499 } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) {
500 /* this is non-query, must be confirmation */
501 printk(KERN_INFO PREFIX "non-query interrupt received,"
502 " switching to interrupt mode\n");
503 set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
493 } 504 }
494 505
495 return status == AE_OK ? 506 return ACPI_SUCCESS(status) ?
496 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 507 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
497} 508}
498 509
@@ -641,13 +652,10 @@ static struct acpi_ec *make_acpi_ec(void)
641 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); 652 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
642 if (!ec) 653 if (!ec)
643 return NULL; 654 return NULL;
644 655 ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
645 atomic_set(&ec->query_pending, 1);
646 atomic_set(&ec->event_count, 1);
647 mutex_init(&ec->lock); 656 mutex_init(&ec->lock);
648 init_waitqueue_head(&ec->wait); 657 init_waitqueue_head(&ec->wait);
649 INIT_LIST_HEAD(&ec->list); 658 INIT_LIST_HEAD(&ec->list);
650
651 return ec; 659 return ec;
652} 660}
653 661
@@ -741,6 +749,8 @@ static int acpi_ec_add(struct acpi_device *device)
741 acpi_ec_add_fs(device); 749 acpi_ec_add_fs(device);
742 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", 750 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
743 ec->gpe, ec->command_addr, ec->data_addr); 751 ec->gpe, ec->command_addr, ec->data_addr);
752 printk(KERN_INFO PREFIX "driver started in %s mode\n",
753 (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll");
744 return 0; 754 return 0;
745} 755}
746 756
@@ -833,7 +843,7 @@ static int acpi_ec_start(struct acpi_device *device)
833 ret = ec_install_handlers(ec); 843 ret = ec_install_handlers(ec);
834 844
835 /* EC is fully operational, allow queries */ 845 /* EC is fully operational, allow queries */
836 atomic_set(&ec->query_pending, 0); 846 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
837 return ret; 847 return ret;
838} 848}
839 849
@@ -924,20 +934,4 @@ static void __exit acpi_ec_exit(void)
924 934
925 return; 935 return;
926} 936}
927#endif /* 0 */ 937#endif /* 0 */
928
929static int __init acpi_ec_set_intr_mode(char *str)
930{
931 int intr;
932
933 if (!get_option(&str, &intr))
934 return 0;
935
936 acpi_ec_mode = (intr) ? EC_INTR : EC_POLL;
937
938 printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
939
940 return 1;
941}
942
943__setup("ec_intr=", acpi_ec_set_intr_mode);
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index c81f6bdb68b8..a5a5532db268 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -47,8 +47,6 @@ 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);
52 50
53static const struct acpi_device_id fan_device_ids[] = { 51static const struct acpi_device_id fan_device_ids[] = {
54 {"PNP0C0B", 0}, 52 {"PNP0C0B", 0},
@@ -63,15 +61,9 @@ static struct acpi_driver acpi_fan_driver = {
63 .ops = { 61 .ops = {
64 .add = acpi_fan_add, 62 .add = acpi_fan_add,
65 .remove = acpi_fan_remove, 63 .remove = acpi_fan_remove,
66 .suspend = acpi_fan_suspend,
67 .resume = acpi_fan_resume,
68 }, 64 },
69}; 65};
70 66
71struct acpi_fan {
72 struct acpi_device * device;
73};
74
75/* -------------------------------------------------------------------------- 67/* --------------------------------------------------------------------------
76 FS Interface (/proc) 68 FS Interface (/proc)
77 -------------------------------------------------------------------------- */ 69 -------------------------------------------------------------------------- */
@@ -80,12 +72,12 @@ static struct proc_dir_entry *acpi_fan_dir;
80 72
81static int acpi_fan_read_state(struct seq_file *seq, void *offset) 73static int acpi_fan_read_state(struct seq_file *seq, void *offset)
82{ 74{
83 struct acpi_fan *fan = seq->private; 75 struct acpi_device *device = seq->private;
84 int state = 0; 76 int state = 0;
85 77
86 78
87 if (fan) { 79 if (device) {
88 if (acpi_bus_get_power(fan->device->handle, &state)) 80 if (acpi_bus_get_power(device->handle, &state))
89 seq_printf(seq, "status: ERROR\n"); 81 seq_printf(seq, "status: ERROR\n");
90 else 82 else
91 seq_printf(seq, "status: %s\n", 83 seq_printf(seq, "status: %s\n",
@@ -105,11 +97,10 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
105{ 97{
106 int result = 0; 98 int result = 0;
107 struct seq_file *m = file->private_data; 99 struct seq_file *m = file->private_data;
108 struct acpi_fan *fan = m->private; 100 struct acpi_device *device = m->private;
109 char state_string[12] = { '\0' }; 101 char state_string[12] = { '\0' };
110 102
111 103 if (count > sizeof(state_string) - 1)
112 if (!fan || (count > sizeof(state_string) - 1))
113 return -EINVAL; 104 return -EINVAL;
114 105
115 if (copy_from_user(state_string, buffer, count)) 106 if (copy_from_user(state_string, buffer, count))
@@ -117,7 +108,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
117 108
118 state_string[count] = '\0'; 109 state_string[count] = '\0';
119 110
120 result = acpi_bus_set_power(fan->device->handle, 111 result = acpi_bus_set_power(device->handle,
121 simple_strtoul(state_string, NULL, 0)); 112 simple_strtoul(state_string, NULL, 0));
122 if (result) 113 if (result)
123 return result; 114 return result;
@@ -158,7 +149,7 @@ static int acpi_fan_add_fs(struct acpi_device *device)
158 return -ENODEV; 149 return -ENODEV;
159 else { 150 else {
160 entry->proc_fops = &acpi_fan_state_ops; 151 entry->proc_fops = &acpi_fan_state_ops;
161 entry->data = acpi_driver_data(device); 152 entry->data = device;
162 entry->owner = THIS_MODULE; 153 entry->owner = THIS_MODULE;
163 } 154 }
164 155
@@ -191,14 +182,8 @@ static int acpi_fan_add(struct acpi_device *device)
191 if (!device) 182 if (!device)
192 return -EINVAL; 183 return -EINVAL;
193 184
194 fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL);
195 if (!fan)
196 return -ENOMEM;
197
198 fan->device = device;
199 strcpy(acpi_device_name(device), "Fan"); 185 strcpy(acpi_device_name(device), "Fan");
200 strcpy(acpi_device_class(device), ACPI_FAN_CLASS); 186 strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
201 acpi_driver_data(device) = fan;
202 187
203 result = acpi_bus_get_power(device->handle, &state); 188 result = acpi_bus_get_power(device->handle, &state);
204 if (result) { 189 if (result) {
@@ -206,10 +191,6 @@ static int acpi_fan_add(struct acpi_device *device)
206 goto end; 191 goto end;
207 } 192 }
208 193
209 device->flags.force_power_state = 1;
210 acpi_bus_set_power(device->handle, state);
211 device->flags.force_power_state = 0;
212
213 result = acpi_fan_add_fs(device); 194 result = acpi_fan_add_fs(device);
214 if (result) 195 if (result)
215 goto end; 196 goto end;
@@ -227,53 +208,14 @@ static int acpi_fan_add(struct acpi_device *device)
227 208
228static int acpi_fan_remove(struct acpi_device *device, int type) 209static int acpi_fan_remove(struct acpi_device *device, int type)
229{ 210{
230 struct acpi_fan *fan = NULL;
231
232
233 if (!device || !acpi_driver_data(device)) 211 if (!device || !acpi_driver_data(device))
234 return -EINVAL; 212 return -EINVAL;
235 213
236 fan = acpi_driver_data(device);
237
238 acpi_fan_remove_fs(device); 214 acpi_fan_remove_fs(device);
239 215
240 kfree(fan);
241
242 return 0; 216 return 0;
243} 217}
244 218
245static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
246{
247 if (!device)
248 return -EINVAL;
249
250 acpi_bus_set_power(device->handle, ACPI_STATE_D0);
251
252 return AE_OK;
253}
254
255static int acpi_fan_resume(struct acpi_device *device)
256{
257 int result = 0;
258 int power_state = 0;
259
260 if (!device)
261 return -EINVAL;
262
263 result = acpi_bus_get_power(device->handle, &power_state);
264 if (result) {
265 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
266 "Error reading fan power state\n"));
267 return result;
268 }
269
270 device->flags.force_power_state = 1;
271 acpi_bus_set_power(device->handle, power_state);
272 device->flags.force_power_state = 0;
273
274 return result;
275}
276
277static int __init acpi_fan_init(void) 219static int __init acpi_fan_init(void)
278{ 220{
279 int result = 0; 221 int result = 0;
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 57b9a2998fd0..af1769a20c7a 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -86,7 +86,6 @@ struct acpi_power_resource {
86 acpi_bus_id name; 86 acpi_bus_id name;
87 u32 system_level; 87 u32 system_level;
88 u32 order; 88 u32 order;
89 int state;
90 struct mutex resource_lock; 89 struct mutex resource_lock;
91 struct list_head reference; 90 struct list_head reference;
92}; 91};
@@ -128,33 +127,31 @@ acpi_power_get_context(acpi_handle handle,
128 return 0; 127 return 0;
129} 128}
130 129
131static int acpi_power_get_state(struct acpi_power_resource *resource) 130static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
132{ 131{
133 acpi_status status = AE_OK; 132 acpi_status status = AE_OK;
134 unsigned long sta = 0; 133 unsigned long sta = 0;
135 134
136 135
137 if (!resource) 136 if (!resource || !state)
138 return -EINVAL; 137 return -EINVAL;
139 138
140 status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta); 139 status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
141 if (ACPI_FAILURE(status)) 140 if (ACPI_FAILURE(status))
142 return -ENODEV; 141 return -ENODEV;
143 142
144 if (sta & 0x01) 143 *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
145 resource->state = ACPI_POWER_RESOURCE_STATE_ON; 144 ACPI_POWER_RESOURCE_STATE_OFF;
146 else
147 resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
148 145
149 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", 146 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
150 resource->name, resource->state ? "on" : "off")); 147 resource->name, state ? "on" : "off"));
151 148
152 return 0; 149 return 0;
153} 150}
154 151
155static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) 152static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
156{ 153{
157 int result = 0; 154 int result = 0, state1;
158 struct acpi_power_resource *resource = NULL; 155 struct acpi_power_resource *resource = NULL;
159 u32 i = 0; 156 u32 i = 0;
160 157
@@ -168,11 +165,11 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
168 result = acpi_power_get_context(list->handles[i], &resource); 165 result = acpi_power_get_context(list->handles[i], &resource);
169 if (result) 166 if (result)
170 return result; 167 return result;
171 result = acpi_power_get_state(resource); 168 result = acpi_power_get_state(resource, &state1);
172 if (result) 169 if (result)
173 return result; 170 return result;
174 171
175 *state = resource->state; 172 *state = state1;
176 173
177 if (*state != ACPI_POWER_RESOURCE_STATE_ON) 174 if (*state != ACPI_POWER_RESOURCE_STATE_ON)
178 break; 175 break;
@@ -186,7 +183,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
186 183
187static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) 184static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
188{ 185{
189 int result = 0; 186 int result = 0, state;
190 int found = 0; 187 int found = 0;
191 acpi_status status = AE_OK; 188 acpi_status status = AE_OK;
192 struct acpi_power_resource *resource = NULL; 189 struct acpi_power_resource *resource = NULL;
@@ -224,20 +221,14 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
224 } 221 }
225 mutex_unlock(&resource->resource_lock); 222 mutex_unlock(&resource->resource_lock);
226 223
227 if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
228 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
229 resource->name));
230 return 0;
231 }
232
233 status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); 224 status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
234 if (ACPI_FAILURE(status)) 225 if (ACPI_FAILURE(status))
235 return -ENODEV; 226 return -ENODEV;
236 227
237 result = acpi_power_get_state(resource); 228 result = acpi_power_get_state(resource, &state);
238 if (result) 229 if (result)
239 return result; 230 return result;
240 if (resource->state != ACPI_POWER_RESOURCE_STATE_ON) 231 if (state != ACPI_POWER_RESOURCE_STATE_ON)
241 return -ENOEXEC; 232 return -ENOEXEC;
242 233
243 /* Update the power resource's _device_ power state */ 234 /* Update the power resource's _device_ power state */
@@ -250,7 +241,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
250 241
251static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) 242static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
252{ 243{
253 int result = 0; 244 int result = 0, state;
254 acpi_status status = AE_OK; 245 acpi_status status = AE_OK;
255 struct acpi_power_resource *resource = NULL; 246 struct acpi_power_resource *resource = NULL;
256 struct list_head *node, *next; 247 struct list_head *node, *next;
@@ -281,20 +272,14 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
281 } 272 }
282 mutex_unlock(&resource->resource_lock); 273 mutex_unlock(&resource->resource_lock);
283 274
284 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
285 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
286 resource->name));
287 return 0;
288 }
289
290 status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL); 275 status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
291 if (ACPI_FAILURE(status)) 276 if (ACPI_FAILURE(status))
292 return -ENODEV; 277 return -ENODEV;
293 278
294 result = acpi_power_get_state(resource); 279 result = acpi_power_get_state(resource, &state);
295 if (result) 280 if (result)
296 return result; 281 return result;
297 if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF) 282 if (state != ACPI_POWER_RESOURCE_STATE_OFF)
298 return -ENOEXEC; 283 return -ENOEXEC;
299 284
300 /* Update the power resource's _device_ power state */ 285 /* Update the power resource's _device_ power state */
@@ -494,7 +479,7 @@ static struct proc_dir_entry *acpi_power_dir;
494static int acpi_power_seq_show(struct seq_file *seq, void *offset) 479static int acpi_power_seq_show(struct seq_file *seq, void *offset)
495{ 480{
496 int count = 0; 481 int count = 0;
497 int result = 0; 482 int result = 0, state;
498 struct acpi_power_resource *resource = NULL; 483 struct acpi_power_resource *resource = NULL;
499 struct list_head *node, *next; 484 struct list_head *node, *next;
500 struct acpi_power_reference *ref; 485 struct acpi_power_reference *ref;
@@ -505,12 +490,12 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
505 if (!resource) 490 if (!resource)
506 goto end; 491 goto end;
507 492
508 result = acpi_power_get_state(resource); 493 result = acpi_power_get_state(resource, &state);
509 if (result) 494 if (result)
510 goto end; 495 goto end;
511 496
512 seq_puts(seq, "state: "); 497 seq_puts(seq, "state: ");
513 switch (resource->state) { 498 switch (state) {
514 case ACPI_POWER_RESOURCE_STATE_ON: 499 case ACPI_POWER_RESOURCE_STATE_ON:
515 seq_puts(seq, "on\n"); 500 seq_puts(seq, "on\n");
516 break; 501 break;
@@ -591,7 +576,7 @@ static int acpi_power_remove_fs(struct acpi_device *device)
591 576
592static int acpi_power_add(struct acpi_device *device) 577static int acpi_power_add(struct acpi_device *device)
593{ 578{
594 int result = 0; 579 int result = 0, state;
595 acpi_status status = AE_OK; 580 acpi_status status = AE_OK;
596 struct acpi_power_resource *resource = NULL; 581 struct acpi_power_resource *resource = NULL;
597 union acpi_object acpi_object; 582 union acpi_object acpi_object;
@@ -622,11 +607,11 @@ static int acpi_power_add(struct acpi_device *device)
622 resource->system_level = acpi_object.power_resource.system_level; 607 resource->system_level = acpi_object.power_resource.system_level;
623 resource->order = acpi_object.power_resource.resource_order; 608 resource->order = acpi_object.power_resource.resource_order;
624 609
625 result = acpi_power_get_state(resource); 610 result = acpi_power_get_state(resource, &state);
626 if (result) 611 if (result)
627 goto end; 612 goto end;
628 613
629 switch (resource->state) { 614 switch (state) {
630 case ACPI_POWER_RESOURCE_STATE_ON: 615 case ACPI_POWER_RESOURCE_STATE_ON:
631 device->power.state = ACPI_STATE_D0; 616 device->power.state = ACPI_STATE_D0;
632 break; 617 break;
@@ -643,7 +628,7 @@ static int acpi_power_add(struct acpi_device *device)
643 goto end; 628 goto end;
644 629
645 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), 630 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
646 acpi_device_bid(device), resource->state ? "on" : "off"); 631 acpi_device_bid(device), state ? "on" : "off");
647 632
648 end: 633 end:
649 if (result) 634 if (result)
@@ -680,7 +665,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
680 665
681static int acpi_power_resume(struct acpi_device *device) 666static int acpi_power_resume(struct acpi_device *device)
682{ 667{
683 int result = 0; 668 int result = 0, state;
684 struct acpi_power_resource *resource = NULL; 669 struct acpi_power_resource *resource = NULL;
685 struct acpi_power_reference *ref; 670 struct acpi_power_reference *ref;
686 671
@@ -689,12 +674,12 @@ static int acpi_power_resume(struct acpi_device *device)
689 674
690 resource = (struct acpi_power_resource *)acpi_driver_data(device); 675 resource = (struct acpi_power_resource *)acpi_driver_data(device);
691 676
692 result = acpi_power_get_state(resource); 677 result = acpi_power_get_state(resource, &state);
693 if (result) 678 if (result)
694 return result; 679 return result;
695 680
696 mutex_lock(&resource->resource_lock); 681 mutex_lock(&resource->resource_lock);
697 if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) && 682 if (state == ACPI_POWER_RESOURCE_STATE_OFF &&
698 !list_empty(&resource->reference)) { 683 !list_empty(&resource->reference)) {
699 ref = container_of(resource->reference.next, struct acpi_power_reference, node); 684 ref = container_of(resource->reference.next, struct acpi_power_reference, node);
700 mutex_unlock(&resource->resource_lock); 685 mutex_unlock(&resource->resource_lock);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index f3d3867303ec..2c0b6630f8ba 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -167,8 +167,8 @@ static void acpi_pm_finish(void)
167{ 167{
168 u32 acpi_state = acpi_target_sleep_state; 168 u32 acpi_state = acpi_target_sleep_state;
169 169
170 acpi_leave_sleep_state(acpi_state);
171 acpi_disable_wakeup_device(acpi_state); 170 acpi_disable_wakeup_device(acpi_state);
171 acpi_leave_sleep_state(acpi_state);
172 172
173 /* reset firmware waking vector */ 173 /* reset firmware waking vector */
174 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 174 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
@@ -272,8 +272,8 @@ static void acpi_hibernation_finish(void)
272 * enable it here. 272 * enable it here.
273 */ 273 */
274 acpi_enable(); 274 acpi_enable();
275 acpi_leave_sleep_state(ACPI_STATE_S4);
276 acpi_disable_wakeup_device(ACPI_STATE_S4); 275 acpi_disable_wakeup_device(ACPI_STATE_S4);
276 acpi_leave_sleep_state(ACPI_STATE_S4);
277 277
278 /* reset firmware waking vector */ 278 /* reset firmware waking vector */
279 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 279 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
@@ -410,6 +410,7 @@ static void acpi_power_off(void)
410 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ 410 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
411 printk("%s called\n", __FUNCTION__); 411 printk("%s called\n", __FUNCTION__);
412 local_irq_disable(); 412 local_irq_disable();
413 acpi_enable_wakeup_device(ACPI_STATE_S5);
413 acpi_enter_sleep_state(ACPI_STATE_S5); 414 acpi_enter_sleep_state(ACPI_STATE_S5);
414} 415}
415 416