aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ac.c20
-rw-r--r--drivers/acpi/battery.c34
-rw-r--r--drivers/acpi/bus.c91
-rw-r--r--drivers/platform/x86/asus-laptop.c23
-rw-r--r--drivers/platform/x86/asus_acpi.c30
-rw-r--r--drivers/platform/x86/eeepc-laptop.c18
-rw-r--r--include/acpi/acpi_bus.h3
7 files changed, 66 insertions, 153 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 88e42abf5d88..0df8fcb687d6 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -61,6 +61,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);
61static int acpi_ac_add(struct acpi_device *device); 61static int acpi_ac_add(struct acpi_device *device);
62static int acpi_ac_remove(struct acpi_device *device, int type); 62static int acpi_ac_remove(struct acpi_device *device, int type);
63static int acpi_ac_resume(struct acpi_device *device); 63static int acpi_ac_resume(struct acpi_device *device);
64static void acpi_ac_notify(struct acpi_device *device, u32 event);
64 65
65static const struct acpi_device_id ac_device_ids[] = { 66static const struct acpi_device_id ac_device_ids[] = {
66 {"ACPI0003", 0}, 67 {"ACPI0003", 0},
@@ -72,10 +73,12 @@ static struct acpi_driver acpi_ac_driver = {
72 .name = "ac", 73 .name = "ac",
73 .class = ACPI_AC_CLASS, 74 .class = ACPI_AC_CLASS,
74 .ids = ac_device_ids, 75 .ids = ac_device_ids,
76 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
75 .ops = { 77 .ops = {
76 .add = acpi_ac_add, 78 .add = acpi_ac_add,
77 .remove = acpi_ac_remove, 79 .remove = acpi_ac_remove,
78 .resume = acpi_ac_resume, 80 .resume = acpi_ac_resume,
81 .notify = acpi_ac_notify,
79 }, 82 },
80}; 83};
81 84
@@ -220,16 +223,14 @@ static int acpi_ac_remove_fs(struct acpi_device *device)
220 Driver Model 223 Driver Model
221 -------------------------------------------------------------------------- */ 224 -------------------------------------------------------------------------- */
222 225
223static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) 226static void acpi_ac_notify(struct acpi_device *device, u32 event)
224{ 227{
225 struct acpi_ac *ac = data; 228 struct acpi_ac *ac = acpi_driver_data(device);
226 struct acpi_device *device = NULL;
227 229
228 230
229 if (!ac) 231 if (!ac)
230 return; 232 return;
231 233
232 device = ac->device;
233 switch (event) { 234 switch (event) {
234 default: 235 default:
235 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 236 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -253,7 +254,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
253static int acpi_ac_add(struct acpi_device *device) 254static int acpi_ac_add(struct acpi_device *device)
254{ 255{
255 int result = 0; 256 int result = 0;
256 acpi_status status = AE_OK;
257 struct acpi_ac *ac = NULL; 257 struct acpi_ac *ac = NULL;
258 258
259 259
@@ -286,13 +286,6 @@ static int acpi_ac_add(struct acpi_device *device)
286 ac->charger.get_property = get_ac_property; 286 ac->charger.get_property = get_ac_property;
287 power_supply_register(&ac->device->dev, &ac->charger); 287 power_supply_register(&ac->device->dev, &ac->charger);
288#endif 288#endif
289 status = acpi_install_notify_handler(device->handle,
290 ACPI_ALL_NOTIFY, acpi_ac_notify,
291 ac);
292 if (ACPI_FAILURE(status)) {
293 result = -ENODEV;
294 goto end;
295 }
296 289
297 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 290 printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
298 acpi_device_name(device), acpi_device_bid(device), 291 acpi_device_name(device), acpi_device_bid(device),
@@ -328,7 +321,6 @@ static int acpi_ac_resume(struct acpi_device *device)
328 321
329static int acpi_ac_remove(struct acpi_device *device, int type) 322static int acpi_ac_remove(struct acpi_device *device, int type)
330{ 323{
331 acpi_status status = AE_OK;
332 struct acpi_ac *ac = NULL; 324 struct acpi_ac *ac = NULL;
333 325
334 326
@@ -337,8 +329,6 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
337 329
338 ac = acpi_driver_data(device); 330 ac = acpi_driver_data(device);
339 331
340 status = acpi_remove_notify_handler(device->handle,
341 ACPI_ALL_NOTIFY, acpi_ac_notify);
342#ifdef CONFIG_ACPI_SYSFS_POWER 332#ifdef CONFIG_ACPI_SYSFS_POWER
343 if (ac->charger.dev) 333 if (ac->charger.dev)
344 power_supply_unregister(&ac->charger); 334 power_supply_unregister(&ac->charger);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index b0de6312919a..58b4517ce712 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -796,13 +796,12 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
796 Driver Interface 796 Driver Interface
797 -------------------------------------------------------------------------- */ 797 -------------------------------------------------------------------------- */
798 798
799static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 799static void acpi_battery_notify(struct acpi_device *device, u32 event)
800{ 800{
801 struct acpi_battery *battery = data; 801 struct acpi_battery *battery = acpi_driver_data(device);
802 struct acpi_device *device; 802
803 if (!battery) 803 if (!battery)
804 return; 804 return;
805 device = battery->device;
806 acpi_battery_update(battery); 805 acpi_battery_update(battery);
807 acpi_bus_generate_proc_event(device, event, 806 acpi_bus_generate_proc_event(device, event,
808 acpi_battery_present(battery)); 807 acpi_battery_present(battery));
@@ -819,7 +818,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
819static int acpi_battery_add(struct acpi_device *device) 818static int acpi_battery_add(struct acpi_device *device)
820{ 819{
821 int result = 0; 820 int result = 0;
822 acpi_status status = 0;
823 struct acpi_battery *battery = NULL; 821 struct acpi_battery *battery = NULL;
824 if (!device) 822 if (!device)
825 return -EINVAL; 823 return -EINVAL;
@@ -834,22 +832,12 @@ static int acpi_battery_add(struct acpi_device *device)
834 acpi_battery_update(battery); 832 acpi_battery_update(battery);
835#ifdef CONFIG_ACPI_PROCFS_POWER 833#ifdef CONFIG_ACPI_PROCFS_POWER
836 result = acpi_battery_add_fs(device); 834 result = acpi_battery_add_fs(device);
837 if (result)
838 goto end;
839#endif 835#endif
840 status = acpi_install_notify_handler(device->handle, 836 if (!result) {
841 ACPI_ALL_NOTIFY, 837 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
842 acpi_battery_notify, battery); 838 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
843 if (ACPI_FAILURE(status)) { 839 device->status.battery_present ? "present" : "absent");
844 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); 840 } else {
845 result = -ENODEV;
846 goto end;
847 }
848 printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
849 ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
850 device->status.battery_present ? "present" : "absent");
851 end:
852 if (result) {
853#ifdef CONFIG_ACPI_PROCFS_POWER 841#ifdef CONFIG_ACPI_PROCFS_POWER
854 acpi_battery_remove_fs(device); 842 acpi_battery_remove_fs(device);
855#endif 843#endif
@@ -860,15 +848,11 @@ static int acpi_battery_add(struct acpi_device *device)
860 848
861static int acpi_battery_remove(struct acpi_device *device, int type) 849static int acpi_battery_remove(struct acpi_device *device, int type)
862{ 850{
863 acpi_status status = 0;
864 struct acpi_battery *battery = NULL; 851 struct acpi_battery *battery = NULL;
865 852
866 if (!device || !acpi_driver_data(device)) 853 if (!device || !acpi_driver_data(device))
867 return -EINVAL; 854 return -EINVAL;
868 battery = acpi_driver_data(device); 855 battery = acpi_driver_data(device);
869 status = acpi_remove_notify_handler(device->handle,
870 ACPI_ALL_NOTIFY,
871 acpi_battery_notify);
872#ifdef CONFIG_ACPI_PROCFS_POWER 856#ifdef CONFIG_ACPI_PROCFS_POWER
873 acpi_battery_remove_fs(device); 857 acpi_battery_remove_fs(device);
874#endif 858#endif
@@ -896,10 +880,12 @@ static struct acpi_driver acpi_battery_driver = {
896 .name = "battery", 880 .name = "battery",
897 .class = ACPI_BATTERY_CLASS, 881 .class = ACPI_BATTERY_CLASS,
898 .ids = battery_device_ids, 882 .ids = battery_device_ids,
883 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
899 .ops = { 884 .ops = {
900 .add = acpi_battery_add, 885 .add = acpi_battery_add,
901 .resume = acpi_battery_resume, 886 .resume = acpi_battery_resume,
902 .remove = acpi_battery_remove, 887 .remove = acpi_battery_remove,
888 .notify = acpi_battery_notify,
903 }, 889 },
904}; 890};
905 891
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ae862f1798dc..2876fc70c3a9 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -450,18 +450,16 @@ int acpi_bus_receive_event(struct acpi_bus_event *event)
450 Notification Handling 450 Notification Handling
451 -------------------------------------------------------------------------- */ 451 -------------------------------------------------------------------------- */
452 452
453static int 453static void acpi_bus_check_device(acpi_handle handle)
454acpi_bus_check_device(struct acpi_device *device, int *status_changed)
455{ 454{
456 acpi_status status = 0; 455 struct acpi_device *device;
456 acpi_status status;
457 struct acpi_device_status old_status; 457 struct acpi_device_status old_status;
458 458
459 459 if (acpi_bus_get_device(handle, &device))
460 return;
460 if (!device) 461 if (!device)
461 return -EINVAL; 462 return;
462
463 if (status_changed)
464 *status_changed = 0;
465 463
466 old_status = device->status; 464 old_status = device->status;
467 465
@@ -471,22 +469,15 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed)
471 */ 469 */
472 if (device->parent && !device->parent->status.present) { 470 if (device->parent && !device->parent->status.present) {
473 device->status = device->parent->status; 471 device->status = device->parent->status;
474 if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { 472 return;
475 if (status_changed)
476 *status_changed = 1;
477 }
478 return 0;
479 } 473 }
480 474
481 status = acpi_bus_get_status(device); 475 status = acpi_bus_get_status(device);
482 if (ACPI_FAILURE(status)) 476 if (ACPI_FAILURE(status))
483 return -ENODEV; 477 return;
484 478
485 if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) 479 if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
486 return 0; 480 return;
487
488 if (status_changed)
489 *status_changed = 1;
490 481
491 /* 482 /*
492 * Device Insertion/Removal 483 * Device Insertion/Removal
@@ -498,33 +489,17 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed)
498 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); 489 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
499 /* TBD: Handle device removal */ 490 /* TBD: Handle device removal */
500 } 491 }
501
502 return 0;
503} 492}
504 493
505static int acpi_bus_check_scope(struct acpi_device *device) 494static void acpi_bus_check_scope(acpi_handle handle)
506{ 495{
507 int result = 0;
508 int status_changed = 0;
509
510
511 if (!device)
512 return -EINVAL;
513
514 /* Status Change? */ 496 /* Status Change? */
515 result = acpi_bus_check_device(device, &status_changed); 497 acpi_bus_check_device(handle);
516 if (result)
517 return result;
518
519 if (!status_changed)
520 return 0;
521 498
522 /* 499 /*
523 * TBD: Enumerate child devices within this device's scope and 500 * TBD: Enumerate child devices within this device's scope and
524 * run acpi_bus_check_device()'s on them. 501 * run acpi_bus_check_device()'s on them.
525 */ 502 */
526
527 return 0;
528} 503}
529 504
530static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); 505static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list);
@@ -547,22 +522,19 @@ EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier);
547 */ 522 */
548static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) 523static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
549{ 524{
550 int result = 0;
551 struct acpi_device *device = NULL; 525 struct acpi_device *device = NULL;
526 struct acpi_driver *driver;
527
528 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n",
529 type, handle));
552 530
553 blocking_notifier_call_chain(&acpi_bus_notify_list, 531 blocking_notifier_call_chain(&acpi_bus_notify_list,
554 type, (void *)handle); 532 type, (void *)handle);
555 533
556 if (acpi_bus_get_device(handle, &device))
557 return;
558
559 switch (type) { 534 switch (type) {
560 535
561 case ACPI_NOTIFY_BUS_CHECK: 536 case ACPI_NOTIFY_BUS_CHECK:
562 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 537 acpi_bus_check_scope(handle);
563 "Received BUS CHECK notification for device [%s]\n",
564 device->pnp.bus_id));
565 result = acpi_bus_check_scope(device);
566 /* 538 /*
567 * TBD: We'll need to outsource certain events to non-ACPI 539 * TBD: We'll need to outsource certain events to non-ACPI
568 * drivers via the device manager (device.c). 540 * drivers via the device manager (device.c).
@@ -570,10 +542,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
570 break; 542 break;
571 543
572 case ACPI_NOTIFY_DEVICE_CHECK: 544 case ACPI_NOTIFY_DEVICE_CHECK:
573 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 545 acpi_bus_check_device(handle);
574 "Received DEVICE CHECK notification for device [%s]\n",
575 device->pnp.bus_id));
576 result = acpi_bus_check_device(device, NULL);
577 /* 546 /*
578 * TBD: We'll need to outsource certain events to non-ACPI 547 * TBD: We'll need to outsource certain events to non-ACPI
579 * drivers via the device manager (device.c). 548 * drivers via the device manager (device.c).
@@ -581,44 +550,26 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
581 break; 550 break;
582 551
583 case ACPI_NOTIFY_DEVICE_WAKE: 552 case ACPI_NOTIFY_DEVICE_WAKE:
584 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
585 "Received DEVICE WAKE notification for device [%s]\n",
586 device->pnp.bus_id));
587 /* TBD */ 553 /* TBD */
588 break; 554 break;
589 555
590 case ACPI_NOTIFY_EJECT_REQUEST: 556 case ACPI_NOTIFY_EJECT_REQUEST:
591 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
592 "Received EJECT REQUEST notification for device [%s]\n",
593 device->pnp.bus_id));
594 /* TBD */ 557 /* TBD */
595 break; 558 break;
596 559
597 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: 560 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
598 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
599 "Received DEVICE CHECK LIGHT notification for device [%s]\n",
600 device->pnp.bus_id));
601 /* TBD: Exactly what does 'light' mean? */ 561 /* TBD: Exactly what does 'light' mean? */
602 break; 562 break;
603 563
604 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 564 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
605 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
606 "Received FREQUENCY MISMATCH notification for device [%s]\n",
607 device->pnp.bus_id));
608 /* TBD */ 565 /* TBD */
609 break; 566 break;
610 567
611 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 568 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
612 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
613 "Received BUS MODE MISMATCH notification for device [%s]\n",
614 device->pnp.bus_id));
615 /* TBD */ 569 /* TBD */
616 break; 570 break;
617 571
618 case ACPI_NOTIFY_POWER_FAULT: 572 case ACPI_NOTIFY_POWER_FAULT:
619 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
620 "Received POWER FAULT notification for device [%s]\n",
621 device->pnp.bus_id));
622 /* TBD */ 573 /* TBD */
623 break; 574 break;
624 575
@@ -629,7 +580,13 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
629 break; 580 break;
630 } 581 }
631 582
632 return; 583 acpi_bus_get_device(handle, &device);
584 if (device) {
585 driver = device->driver;
586 if (driver && driver->ops.notify &&
587 (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
588 driver->ops.notify(device, type);
589 }
633} 590}
634 591
635/* -------------------------------------------------------------------------- 592/* --------------------------------------------------------------------------
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index bfc1a8892a32..eaffe732653a 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -207,13 +207,17 @@ MODULE_DEVICE_TABLE(acpi, asus_device_ids);
207 207
208static int asus_hotk_add(struct acpi_device *device); 208static int asus_hotk_add(struct acpi_device *device);
209static int asus_hotk_remove(struct acpi_device *device, int type); 209static int asus_hotk_remove(struct acpi_device *device, int type);
210static void asus_hotk_notify(struct acpi_device *device, u32 event);
211
210static struct acpi_driver asus_hotk_driver = { 212static struct acpi_driver asus_hotk_driver = {
211 .name = ASUS_HOTK_NAME, 213 .name = ASUS_HOTK_NAME,
212 .class = ASUS_HOTK_CLASS, 214 .class = ASUS_HOTK_CLASS,
213 .ids = asus_device_ids, 215 .ids = asus_device_ids,
216 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
214 .ops = { 217 .ops = {
215 .add = asus_hotk_add, 218 .add = asus_hotk_add,
216 .remove = asus_hotk_remove, 219 .remove = asus_hotk_remove,
220 .notify = asus_hotk_notify,
217 }, 221 },
218}; 222};
219 223
@@ -812,7 +816,7 @@ static int asus_setkeycode(struct input_dev *dev, int scancode, int keycode)
812 return -EINVAL; 816 return -EINVAL;
813} 817}
814 818
815static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) 819static void asus_hotk_notify(struct acpi_device *device, u32 event)
816{ 820{
817 static struct key_entry *key; 821 static struct key_entry *key;
818 u16 count; 822 u16 count;
@@ -1124,7 +1128,6 @@ static int asus_hotk_found;
1124 1128
1125static int asus_hotk_add(struct acpi_device *device) 1129static int asus_hotk_add(struct acpi_device *device)
1126{ 1130{
1127 acpi_status status = AE_OK;
1128 int result; 1131 int result;
1129 1132
1130 if (!device) 1133 if (!device)
@@ -1149,15 +1152,6 @@ static int asus_hotk_add(struct acpi_device *device)
1149 1152
1150 asus_hotk_add_fs(); 1153 asus_hotk_add_fs();
1151 1154
1152 /*
1153 * We install the handler, it will receive the hotk in parameter, so, we
1154 * could add other data to the hotk struct
1155 */
1156 status = acpi_install_notify_handler(hotk->handle, ACPI_ALL_NOTIFY,
1157 asus_hotk_notify, hotk);
1158 if (ACPI_FAILURE(status))
1159 printk(ASUS_ERR "Error installing notify handler\n");
1160
1161 asus_hotk_found = 1; 1155 asus_hotk_found = 1;
1162 1156
1163 /* WLED and BLED are on by default */ 1157 /* WLED and BLED are on by default */
@@ -1198,16 +1192,9 @@ end:
1198 1192
1199static int asus_hotk_remove(struct acpi_device *device, int type) 1193static int asus_hotk_remove(struct acpi_device *device, int type)
1200{ 1194{
1201 acpi_status status = 0;
1202
1203 if (!device || !acpi_driver_data(device)) 1195 if (!device || !acpi_driver_data(device))
1204 return -EINVAL; 1196 return -EINVAL;
1205 1197
1206 status = acpi_remove_notify_handler(hotk->handle, ACPI_ALL_NOTIFY,
1207 asus_hotk_notify);
1208 if (ACPI_FAILURE(status))
1209 printk(ASUS_ERR "Error removing notify handler\n");
1210
1211 kfree(hotk->name); 1198 kfree(hotk->name);
1212 kfree(hotk); 1199 kfree(hotk);
1213 1200
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index ba1f7497e4b9..ddf5240ade8c 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -455,6 +455,8 @@ static struct asus_hotk *hotk;
455 */ 455 */
456static int asus_hotk_add(struct acpi_device *device); 456static int asus_hotk_add(struct acpi_device *device);
457static int asus_hotk_remove(struct acpi_device *device, int type); 457static int asus_hotk_remove(struct acpi_device *device, int type);
458static void asus_hotk_notify(struct acpi_device *device, u32 event);
459
458static const struct acpi_device_id asus_device_ids[] = { 460static const struct acpi_device_id asus_device_ids[] = {
459 {"ATK0100", 0}, 461 {"ATK0100", 0},
460 {"", 0}, 462 {"", 0},
@@ -465,9 +467,11 @@ static struct acpi_driver asus_hotk_driver = {
465 .name = "asus_acpi", 467 .name = "asus_acpi",
466 .class = ACPI_HOTK_CLASS, 468 .class = ACPI_HOTK_CLASS,
467 .ids = asus_device_ids, 469 .ids = asus_device_ids,
470 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
468 .ops = { 471 .ops = {
469 .add = asus_hotk_add, 472 .add = asus_hotk_add,
470 .remove = asus_hotk_remove, 473 .remove = asus_hotk_remove,
474 .notify = asus_hotk_notify,
471 }, 475 },
472}; 476};
473 477
@@ -1101,12 +1105,20 @@ static int asus_hotk_remove_fs(struct acpi_device *device)
1101 return 0; 1105 return 0;
1102} 1106}
1103 1107
1104static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) 1108static void asus_hotk_notify(struct acpi_device *device, u32 event)
1105{ 1109{
1106 /* TODO Find a better way to handle events count. */ 1110 /* TODO Find a better way to handle events count. */
1107 if (!hotk) 1111 if (!hotk)
1108 return; 1112 return;
1109 1113
1114 /*
1115 * The BIOS *should* be sending us device events, but apparently
1116 * Asus uses system events instead, so just ignore any device
1117 * events we get.
1118 */
1119 if (event > ACPI_MAX_SYS_NOTIFY)
1120 return;
1121
1110 if ((event & ~((u32) BR_UP)) < 16) 1122 if ((event & ~((u32) BR_UP)) < 16)
1111 hotk->brightness = (event & ~((u32) BR_UP)); 1123 hotk->brightness = (event & ~((u32) BR_UP));
1112 else if ((event & ~((u32) BR_DOWN)) < 16) 1124 else if ((event & ~((u32) BR_DOWN)) < 16)
@@ -1346,15 +1358,6 @@ static int asus_hotk_add(struct acpi_device *device)
1346 if (result) 1358 if (result)
1347 goto end; 1359 goto end;
1348 1360
1349 /*
1350 * We install the handler, it will receive the hotk in parameter, so, we
1351 * could add other data to the hotk struct
1352 */
1353 status = acpi_install_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
1354 asus_hotk_notify, hotk);
1355 if (ACPI_FAILURE(status))
1356 printk(KERN_ERR " Error installing notify handler\n");
1357
1358 /* For laptops without GPLV: init the hotk->brightness value */ 1361 /* For laptops without GPLV: init the hotk->brightness value */
1359 if ((!hotk->methods->brightness_get) 1362 if ((!hotk->methods->brightness_get)
1360 && (!hotk->methods->brightness_status) 1363 && (!hotk->methods->brightness_status)
@@ -1389,16 +1392,9 @@ end:
1389 1392
1390static int asus_hotk_remove(struct acpi_device *device, int type) 1393static int asus_hotk_remove(struct acpi_device *device, int type)
1391{ 1394{
1392 acpi_status status = 0;
1393
1394 if (!device || !acpi_driver_data(device)) 1395 if (!device || !acpi_driver_data(device))
1395 return -EINVAL; 1396 return -EINVAL;
1396 1397
1397 status = acpi_remove_notify_handler(hotk->handle, ACPI_SYSTEM_NOTIFY,
1398 asus_hotk_notify);
1399 if (ACPI_FAILURE(status))
1400 printk(KERN_ERR "Asus ACPI: Error removing notify handler\n");
1401
1402 asus_hotk_remove_fs(device); 1398 asus_hotk_remove_fs(device);
1403 1399
1404 kfree(hotk); 1400 kfree(hotk);
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 8153b3e59189..46b5aa5e85f0 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -181,6 +181,7 @@ static struct key_entry eeepc_keymap[] = {
181static int eeepc_hotk_add(struct acpi_device *device); 181static int eeepc_hotk_add(struct acpi_device *device);
182static int eeepc_hotk_remove(struct acpi_device *device, int type); 182static int eeepc_hotk_remove(struct acpi_device *device, int type);
183static int eeepc_hotk_resume(struct acpi_device *device); 183static int eeepc_hotk_resume(struct acpi_device *device);
184static void eeepc_hotk_notify(struct acpi_device *device, u32 event);
184 185
185static const struct acpi_device_id eeepc_device_ids[] = { 186static const struct acpi_device_id eeepc_device_ids[] = {
186 {EEEPC_HOTK_HID, 0}, 187 {EEEPC_HOTK_HID, 0},
@@ -192,10 +193,12 @@ static struct acpi_driver eeepc_hotk_driver = {
192 .name = EEEPC_HOTK_NAME, 193 .name = EEEPC_HOTK_NAME,
193 .class = EEEPC_HOTK_CLASS, 194 .class = EEEPC_HOTK_CLASS,
194 .ids = eeepc_device_ids, 195 .ids = eeepc_device_ids,
196 .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
195 .ops = { 197 .ops = {
196 .add = eeepc_hotk_add, 198 .add = eeepc_hotk_add,
197 .remove = eeepc_hotk_remove, 199 .remove = eeepc_hotk_remove,
198 .resume = eeepc_hotk_resume, 200 .resume = eeepc_hotk_resume,
201 .notify = eeepc_hotk_notify,
199 }, 202 },
200}; 203};
201 204
@@ -558,7 +561,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
558 eeepc_rfkill_hotplug(); 561 eeepc_rfkill_hotplug();
559} 562}
560 563
561static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 564static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
562{ 565{
563 static struct key_entry *key; 566 static struct key_entry *key;
564 u16 count; 567 u16 count;
@@ -566,6 +569,8 @@ static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
566 569
567 if (!ehotk) 570 if (!ehotk)
568 return; 571 return;
572 if (event > ACPI_MAX_SYS_NOTIFY)
573 return;
569 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) 574 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
570 brn = notify_brn(); 575 brn = notify_brn();
571 count = ehotk->event_count[event % 128]++; 576 count = ehotk->event_count[event % 128]++;
@@ -646,7 +651,6 @@ static void eeepc_unregister_rfkill_notifier(char *node)
646 651
647static int eeepc_hotk_add(struct acpi_device *device) 652static int eeepc_hotk_add(struct acpi_device *device)
648{ 653{
649 acpi_status status = AE_OK;
650 int result; 654 int result;
651 655
652 if (!device) 656 if (!device)
@@ -664,10 +668,6 @@ static int eeepc_hotk_add(struct acpi_device *device)
664 result = eeepc_hotk_check(); 668 result = eeepc_hotk_check();
665 if (result) 669 if (result)
666 goto ehotk_fail; 670 goto ehotk_fail;
667 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
668 eeepc_hotk_notify, ehotk);
669 if (ACPI_FAILURE(status))
670 printk(EEEPC_ERR "Error installing notify handler\n");
671 671
672 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); 672 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6");
673 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); 673 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
@@ -725,14 +725,8 @@ static int eeepc_hotk_add(struct acpi_device *device)
725 725
726static int eeepc_hotk_remove(struct acpi_device *device, int type) 726static int eeepc_hotk_remove(struct acpi_device *device, int type)
727{ 727{
728 acpi_status status = 0;
729
730 if (!device || !acpi_driver_data(device)) 728 if (!device || !acpi_driver_data(device))
731 return -EINVAL; 729 return -EINVAL;
732 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
733 eeepc_hotk_notify);
734 if (ACPI_FAILURE(status))
735 printk(EEEPC_ERR "Error removing notify handler\n");
736 730
737 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); 731 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
738 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); 732 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index bf1f43bd9016..c65e4ce6c3af 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -114,10 +114,13 @@ struct acpi_device_ops {
114 acpi_op_notify notify; 114 acpi_op_notify notify;
115}; 115};
116 116
117#define ACPI_DRIVER_ALL_NOTIFY_EVENTS 0x1 /* system AND device events */
118
117struct acpi_driver { 119struct acpi_driver {
118 char name[80]; 120 char name[80];
119 char class[80]; 121 char class[80];
120 const struct acpi_device_id *ids; /* Supported Hardware IDs */ 122 const struct acpi_device_id *ids; /* Supported Hardware IDs */
123 unsigned int flags;
121 struct acpi_device_ops ops; 124 struct acpi_device_ops ops;
122 struct device_driver drv; 125 struct device_driver drv;
123 struct module *owner; 126 struct module *owner;