aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/wmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/wmi.c')
-rw-r--r--drivers/platform/x86/wmi.c385
1 files changed, 168 insertions, 217 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index b2978a04317f..f23d5a84e7b1 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -27,6 +27,8 @@
27 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28 */ 28 */
29 29
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
30#include <linux/kernel.h> 32#include <linux/kernel.h>
31#include <linux/init.h> 33#include <linux/init.h>
32#include <linux/types.h> 34#include <linux/types.h>
@@ -44,9 +46,8 @@ MODULE_LICENSE("GPL");
44 46
45#define ACPI_WMI_CLASS "wmi" 47#define ACPI_WMI_CLASS "wmi"
46 48
47#define PREFIX "ACPI: WMI: "
48
49static DEFINE_MUTEX(wmi_data_lock); 49static DEFINE_MUTEX(wmi_data_lock);
50static LIST_HEAD(wmi_block_list);
50 51
51struct guid_block { 52struct guid_block {
52 char guid[16]; 53 char guid[16];
@@ -67,10 +68,9 @@ struct wmi_block {
67 acpi_handle handle; 68 acpi_handle handle;
68 wmi_notify_handler handler; 69 wmi_notify_handler handler;
69 void *handler_data; 70 void *handler_data;
70 struct device *dev; 71 struct device dev;
71}; 72};
72 73
73static struct wmi_block wmi_blocks;
74 74
75/* 75/*
76 * If the GUID data block is marked as expensive, we must enable and 76 * If the GUID data block is marked as expensive, we must enable and
@@ -110,7 +110,7 @@ static struct acpi_driver acpi_wmi_driver = {
110 .add = acpi_wmi_add, 110 .add = acpi_wmi_add,
111 .remove = acpi_wmi_remove, 111 .remove = acpi_wmi_remove,
112 .notify = acpi_wmi_notify, 112 .notify = acpi_wmi_notify,
113 }, 113 },
114}; 114};
115 115
116/* 116/*
@@ -128,30 +128,18 @@ static struct acpi_driver acpi_wmi_driver = {
128 */ 128 */
129static int wmi_parse_hexbyte(const u8 *src) 129static int wmi_parse_hexbyte(const u8 *src)
130{ 130{
131 unsigned int x; /* For correct wrapping */
132 int h; 131 int h;
132 int value;
133 133
134 /* high part */ 134 /* high part */
135 x = src[0]; 135 h = value = hex_to_bin(src[0]);
136 if (x - '0' <= '9' - '0') { 136 if (value < 0)
137 h = x - '0';
138 } else if (x - 'a' <= 'f' - 'a') {
139 h = x - 'a' + 10;
140 } else if (x - 'A' <= 'F' - 'A') {
141 h = x - 'A' + 10;
142 } else {
143 return -1; 137 return -1;
144 }
145 h <<= 4;
146 138
147 /* low part */ 139 /* low part */
148 x = src[1]; 140 value = hex_to_bin(src[1]);
149 if (x - '0' <= '9' - '0') 141 if (value >= 0)
150 return h | (x - '0'); 142 return (h << 4) | value;
151 if (x - 'a' <= 'f' - 'a')
152 return h | (x - 'a' + 10);
153 if (x - 'A' <= 'F' - 'A')
154 return h | (x - 'A' + 10);
155 return -1; 143 return -1;
156} 144}
157 145
@@ -232,7 +220,7 @@ static int wmi_gtoa(const char *in, char *out)
232 for (i = 10; i <= 15; i++) 220 for (i = 10; i <= 15; i++)
233 out += sprintf(out, "%02X", in[i] & 0xFF); 221 out += sprintf(out, "%02X", in[i] & 0xFF);
234 222
235 out = '\0'; 223 *out = '\0';
236 return 0; 224 return 0;
237} 225}
238 226
@@ -246,7 +234,7 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)
246 wmi_parse_guid(guid_string, tmp); 234 wmi_parse_guid(guid_string, tmp);
247 wmi_swap_bytes(tmp, guid_input); 235 wmi_swap_bytes(tmp, guid_input);
248 236
249 list_for_each(p, &wmi_blocks.list) { 237 list_for_each(p, &wmi_block_list) {
250 wblock = list_entry(p, struct wmi_block, list); 238 wblock = list_entry(p, struct wmi_block, list);
251 block = &wblock->gblock; 239 block = &wblock->gblock;
252 240
@@ -487,30 +475,29 @@ const struct acpi_buffer *in)
487} 475}
488EXPORT_SYMBOL_GPL(wmi_set_block); 476EXPORT_SYMBOL_GPL(wmi_set_block);
489 477
490static void wmi_dump_wdg(struct guid_block *g) 478static void wmi_dump_wdg(const struct guid_block *g)
491{ 479{
492 char guid_string[37]; 480 char guid_string[37];
493 481
494 wmi_gtoa(g->guid, guid_string); 482 wmi_gtoa(g->guid, guid_string);
495 printk(KERN_INFO PREFIX "%s:\n", guid_string); 483
496 printk(KERN_INFO PREFIX "\tobject_id: %c%c\n", 484 pr_info("%s:\n", guid_string);
497 g->object_id[0], g->object_id[1]); 485 pr_info("\tobject_id: %c%c\n", g->object_id[0], g->object_id[1]);
498 printk(KERN_INFO PREFIX "\tnotify_id: %02X\n", g->notify_id); 486 pr_info("\tnotify_id: %02X\n", g->notify_id);
499 printk(KERN_INFO PREFIX "\treserved: %02X\n", g->reserved); 487 pr_info("\treserved: %02X\n", g->reserved);
500 printk(KERN_INFO PREFIX "\tinstance_count: %d\n", g->instance_count); 488 pr_info("\tinstance_count: %d\n", g->instance_count);
501 printk(KERN_INFO PREFIX "\tflags: %#x", g->flags); 489 pr_info("\tflags: %#x", g->flags);
502 if (g->flags) { 490 if (g->flags) {
503 printk(" ");
504 if (g->flags & ACPI_WMI_EXPENSIVE) 491 if (g->flags & ACPI_WMI_EXPENSIVE)
505 printk("ACPI_WMI_EXPENSIVE "); 492 pr_cont(" ACPI_WMI_EXPENSIVE");
506 if (g->flags & ACPI_WMI_METHOD) 493 if (g->flags & ACPI_WMI_METHOD)
507 printk("ACPI_WMI_METHOD "); 494 pr_cont(" ACPI_WMI_METHOD");
508 if (g->flags & ACPI_WMI_STRING) 495 if (g->flags & ACPI_WMI_STRING)
509 printk("ACPI_WMI_STRING "); 496 pr_cont(" ACPI_WMI_STRING");
510 if (g->flags & ACPI_WMI_EVENT) 497 if (g->flags & ACPI_WMI_EVENT)
511 printk("ACPI_WMI_EVENT "); 498 pr_cont(" ACPI_WMI_EVENT");
512 } 499 }
513 printk("\n"); 500 pr_cont("\n");
514 501
515} 502}
516 503
@@ -522,7 +509,7 @@ static void wmi_notify_debug(u32 value, void *context)
522 509
523 status = wmi_get_event_data(value, &response); 510 status = wmi_get_event_data(value, &response);
524 if (status != AE_OK) { 511 if (status != AE_OK) {
525 printk(KERN_INFO "wmi: bad event status 0x%x\n", status); 512 pr_info("bad event status 0x%x\n", status);
526 return; 513 return;
527 } 514 }
528 515
@@ -531,22 +518,22 @@ static void wmi_notify_debug(u32 value, void *context)
531 if (!obj) 518 if (!obj)
532 return; 519 return;
533 520
534 printk(KERN_INFO PREFIX "DEBUG Event "); 521 pr_info("DEBUG Event ");
535 switch(obj->type) { 522 switch(obj->type) {
536 case ACPI_TYPE_BUFFER: 523 case ACPI_TYPE_BUFFER:
537 printk("BUFFER_TYPE - length %d\n", obj->buffer.length); 524 pr_cont("BUFFER_TYPE - length %d\n", obj->buffer.length);
538 break; 525 break;
539 case ACPI_TYPE_STRING: 526 case ACPI_TYPE_STRING:
540 printk("STRING_TYPE - %s\n", obj->string.pointer); 527 pr_cont("STRING_TYPE - %s\n", obj->string.pointer);
541 break; 528 break;
542 case ACPI_TYPE_INTEGER: 529 case ACPI_TYPE_INTEGER:
543 printk("INTEGER_TYPE - %llu\n", obj->integer.value); 530 pr_cont("INTEGER_TYPE - %llu\n", obj->integer.value);
544 break; 531 break;
545 case ACPI_TYPE_PACKAGE: 532 case ACPI_TYPE_PACKAGE:
546 printk("PACKAGE_TYPE - %d elements\n", obj->package.count); 533 pr_cont("PACKAGE_TYPE - %d elements\n", obj->package.count);
547 break; 534 break;
548 default: 535 default:
549 printk("object type 0x%X\n", obj->type); 536 pr_cont("object type 0x%X\n", obj->type);
550 } 537 }
551 kfree(obj); 538 kfree(obj);
552} 539}
@@ -562,21 +549,34 @@ acpi_status wmi_install_notify_handler(const char *guid,
562wmi_notify_handler handler, void *data) 549wmi_notify_handler handler, void *data)
563{ 550{
564 struct wmi_block *block; 551 struct wmi_block *block;
565 acpi_status status; 552 acpi_status status = AE_NOT_EXIST;
553 char tmp[16], guid_input[16];
554 struct list_head *p;
566 555
567 if (!guid || !handler) 556 if (!guid || !handler)
568 return AE_BAD_PARAMETER; 557 return AE_BAD_PARAMETER;
569 558
570 if (!find_guid(guid, &block)) 559 wmi_parse_guid(guid, tmp);
571 return AE_NOT_EXIST; 560 wmi_swap_bytes(tmp, guid_input);
572 561
573 if (block->handler && block->handler != wmi_notify_debug) 562 list_for_each(p, &wmi_block_list) {
574 return AE_ALREADY_ACQUIRED; 563 acpi_status wmi_status;
564 block = list_entry(p, struct wmi_block, list);
575 565
576 block->handler = handler; 566 if (memcmp(block->gblock.guid, guid_input, 16) == 0) {
577 block->handler_data = data; 567 if (block->handler &&
568 block->handler != wmi_notify_debug)
569 return AE_ALREADY_ACQUIRED;
578 570
579 status = wmi_method_enable(block, 1); 571 block->handler = handler;
572 block->handler_data = data;
573
574 wmi_status = wmi_method_enable(block, 1);
575 if ((wmi_status != AE_OK) ||
576 ((wmi_status == AE_OK) && (status == AE_NOT_EXIST)))
577 status = wmi_status;
578 }
579 }
580 580
581 return status; 581 return status;
582} 582}
@@ -590,24 +590,40 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
590acpi_status wmi_remove_notify_handler(const char *guid) 590acpi_status wmi_remove_notify_handler(const char *guid)
591{ 591{
592 struct wmi_block *block; 592 struct wmi_block *block;
593 acpi_status status = AE_OK; 593 acpi_status status = AE_NOT_EXIST;
594 char tmp[16], guid_input[16];
595 struct list_head *p;
594 596
595 if (!guid) 597 if (!guid)
596 return AE_BAD_PARAMETER; 598 return AE_BAD_PARAMETER;
597 599
598 if (!find_guid(guid, &block)) 600 wmi_parse_guid(guid, tmp);
599 return AE_NOT_EXIST; 601 wmi_swap_bytes(tmp, guid_input);
600 602
601 if (!block->handler || block->handler == wmi_notify_debug) 603 list_for_each(p, &wmi_block_list) {
602 return AE_NULL_ENTRY; 604 acpi_status wmi_status;
605 block = list_entry(p, struct wmi_block, list);
603 606
604 if (debug_event) { 607 if (memcmp(block->gblock.guid, guid_input, 16) == 0) {
605 block->handler = wmi_notify_debug; 608 if (!block->handler ||
606 } else { 609 block->handler == wmi_notify_debug)
607 status = wmi_method_enable(block, 0); 610 return AE_NULL_ENTRY;
608 block->handler = NULL; 611
609 block->handler_data = NULL; 612 if (debug_event) {
613 block->handler = wmi_notify_debug;
614 status = AE_OK;
615 } else {
616 wmi_status = wmi_method_enable(block, 0);
617 block->handler = NULL;
618 block->handler_data = NULL;
619 if ((wmi_status != AE_OK) ||
620 ((wmi_status == AE_OK) &&
621 (status == AE_NOT_EXIST)))
622 status = wmi_status;
623 }
624 }
610 } 625 }
626
611 return status; 627 return status;
612} 628}
613EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); 629EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
@@ -633,7 +649,7 @@ acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
633 params[0].type = ACPI_TYPE_INTEGER; 649 params[0].type = ACPI_TYPE_INTEGER;
634 params[0].integer.value = event; 650 params[0].integer.value = event;
635 651
636 list_for_each(p, &wmi_blocks.list) { 652 list_for_each(p, &wmi_block_list) {
637 wblock = list_entry(p, struct wmi_block, list); 653 wblock = list_entry(p, struct wmi_block, list);
638 gblock = &wblock->gblock; 654 gblock = &wblock->gblock;
639 655
@@ -662,7 +678,7 @@ EXPORT_SYMBOL_GPL(wmi_has_guid);
662/* 678/*
663 * sysfs interface 679 * sysfs interface
664 */ 680 */
665static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, 681static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
666 char *buf) 682 char *buf)
667{ 683{
668 char guid_string[37]; 684 char guid_string[37];
@@ -676,7 +692,11 @@ static ssize_t show_modalias(struct device *dev, struct device_attribute *attr,
676 692
677 return sprintf(buf, "wmi:%s\n", guid_string); 693 return sprintf(buf, "wmi:%s\n", guid_string);
678} 694}
679static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); 695
696static struct device_attribute wmi_dev_attrs[] = {
697 __ATTR_RO(modalias),
698 __ATTR_NULL
699};
680 700
681static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) 701static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
682{ 702{
@@ -702,108 +722,51 @@ static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
702 722
703static void wmi_dev_free(struct device *dev) 723static void wmi_dev_free(struct device *dev)
704{ 724{
705 kfree(dev); 725 struct wmi_block *wmi_block = container_of(dev, struct wmi_block, dev);
726
727 kfree(wmi_block);
706} 728}
707 729
708static struct class wmi_class = { 730static struct class wmi_class = {
709 .name = "wmi", 731 .name = "wmi",
710 .dev_release = wmi_dev_free, 732 .dev_release = wmi_dev_free,
711 .dev_uevent = wmi_dev_uevent, 733 .dev_uevent = wmi_dev_uevent,
734 .dev_attrs = wmi_dev_attrs,
712}; 735};
713 736
714static int wmi_create_devs(void) 737static int wmi_create_device(const struct guid_block *gblock,
738 struct wmi_block *wblock, acpi_handle handle)
715{ 739{
716 int result;
717 char guid_string[37]; 740 char guid_string[37];
718 struct guid_block *gblock;
719 struct wmi_block *wblock;
720 struct list_head *p;
721 struct device *guid_dev;
722
723 /* Create devices for all the GUIDs */
724 list_for_each(p, &wmi_blocks.list) {
725 wblock = list_entry(p, struct wmi_block, list);
726
727 guid_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
728 if (!guid_dev)
729 return -ENOMEM;
730
731 wblock->dev = guid_dev;
732
733 guid_dev->class = &wmi_class;
734 dev_set_drvdata(guid_dev, wblock);
735
736 gblock = &wblock->gblock;
737 741
738 wmi_gtoa(gblock->guid, guid_string); 742 wblock->dev.class = &wmi_class;
739 dev_set_name(guid_dev, guid_string);
740 743
741 result = device_register(guid_dev); 744 wmi_gtoa(gblock->guid, guid_string);
742 if (result) 745 dev_set_name(&wblock->dev, guid_string);
743 return result;
744 746
745 result = device_create_file(guid_dev, &dev_attr_modalias); 747 dev_set_drvdata(&wblock->dev, wblock);
746 if (result)
747 return result;
748 }
749 748
750 return 0; 749 return device_register(&wblock->dev);
751} 750}
752 751
753static void wmi_remove_devs(void) 752static void wmi_free_devices(void)
754{ 753{
755 struct guid_block *gblock; 754 struct wmi_block *wblock, *next;
756 struct wmi_block *wblock;
757 struct list_head *p;
758 struct device *guid_dev;
759 755
760 /* Delete devices for all the GUIDs */ 756 /* Delete devices for all the GUIDs */
761 list_for_each(p, &wmi_blocks.list) { 757 list_for_each_entry_safe(wblock, next, &wmi_block_list, list)
762 wblock = list_entry(p, struct wmi_block, list); 758 if (wblock->dev.class)
763 759 device_unregister(&wblock->dev);
764 guid_dev = wblock->dev;
765 gblock = &wblock->gblock;
766
767 device_remove_file(guid_dev, &dev_attr_modalias);
768
769 device_unregister(guid_dev);
770 }
771}
772
773static void wmi_class_exit(void)
774{
775 wmi_remove_devs();
776 class_unregister(&wmi_class);
777}
778
779static int wmi_class_init(void)
780{
781 int ret;
782
783 ret = class_register(&wmi_class);
784 if (ret)
785 return ret;
786
787 ret = wmi_create_devs();
788 if (ret)
789 wmi_class_exit();
790
791 return ret;
792} 760}
793 761
794static bool guid_already_parsed(const char *guid_string) 762static bool guid_already_parsed(const char *guid_string)
795{ 763{
796 struct guid_block *gblock;
797 struct wmi_block *wblock; 764 struct wmi_block *wblock;
798 struct list_head *p;
799 765
800 list_for_each(p, &wmi_blocks.list) { 766 list_for_each_entry(wblock, &wmi_block_list, list)
801 wblock = list_entry(p, struct wmi_block, list); 767 if (memcmp(wblock->gblock.guid, guid_string, 16) == 0)
802 gblock = &wblock->gblock;
803
804 if (strncmp(gblock->guid, guid_string, 16) == 0)
805 return true; 768 return true;
806 } 769
807 return false; 770 return false;
808} 771}
809 772
@@ -814,68 +777,67 @@ static acpi_status parse_wdg(acpi_handle handle)
814{ 777{
815 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 778 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
816 union acpi_object *obj; 779 union acpi_object *obj;
817 struct guid_block *gblock; 780 const struct guid_block *gblock;
818 struct wmi_block *wblock; 781 struct wmi_block *wblock;
819 char guid_string[37];
820 acpi_status status; 782 acpi_status status;
783 int retval;
821 u32 i, total; 784 u32 i, total;
822 785
823 status = acpi_evaluate_object(handle, "_WDG", NULL, &out); 786 status = acpi_evaluate_object(handle, "_WDG", NULL, &out);
824
825 if (ACPI_FAILURE(status)) 787 if (ACPI_FAILURE(status))
826 return status; 788 return -ENXIO;
827 789
828 obj = (union acpi_object *) out.pointer; 790 obj = (union acpi_object *) out.pointer;
791 if (!obj)
792 return -ENXIO;
829 793
830 if (obj->type != ACPI_TYPE_BUFFER) 794 if (obj->type != ACPI_TYPE_BUFFER) {
831 return AE_ERROR; 795 retval = -ENXIO;
832
833 total = obj->buffer.length / sizeof(struct guid_block);
834
835 gblock = kmemdup(obj->buffer.pointer, obj->buffer.length, GFP_KERNEL);
836 if (!gblock) {
837 status = AE_NO_MEMORY;
838 goto out_free_pointer; 796 goto out_free_pointer;
839 } 797 }
840 798
799 gblock = (const struct guid_block *)obj->buffer.pointer;
800 total = obj->buffer.length / sizeof(struct guid_block);
801
841 for (i = 0; i < total; i++) { 802 for (i = 0; i < total; i++) {
803 if (debug_dump_wdg)
804 wmi_dump_wdg(&gblock[i]);
805
806 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
807 if (!wblock)
808 return AE_NO_MEMORY;
809
810 wblock->handle = handle;
811 wblock->gblock = gblock[i];
812
842 /* 813 /*
843 Some WMI devices, like those for nVidia hooks, have a 814 Some WMI devices, like those for nVidia hooks, have a
844 duplicate GUID. It's not clear what we should do in this 815 duplicate GUID. It's not clear what we should do in this
845 case yet, so for now, we'll just ignore the duplicate. 816 case yet, so for now, we'll just ignore the duplicate
846 Anyone who wants to add support for that device can come 817 for device creation.
847 up with a better workaround for the mess then.
848 */ 818 */
849 if (guid_already_parsed(gblock[i].guid) == true) { 819 if (!guid_already_parsed(gblock[i].guid)) {
850 wmi_gtoa(gblock[i].guid, guid_string); 820 retval = wmi_create_device(&gblock[i], wblock, handle);
851 printk(KERN_INFO PREFIX "Skipping duplicate GUID %s\n", 821 if (retval) {
852 guid_string); 822 wmi_free_devices();
853 continue; 823 goto out_free_pointer;
824 }
854 } 825 }
855 if (debug_dump_wdg)
856 wmi_dump_wdg(&gblock[i]);
857 826
858 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); 827 list_add_tail(&wblock->list, &wmi_block_list);
859 if (!wblock) {
860 status = AE_NO_MEMORY;
861 goto out_free_gblock;
862 }
863 828
864 wblock->gblock = gblock[i];
865 wblock->handle = handle;
866 if (debug_event) { 829 if (debug_event) {
867 wblock->handler = wmi_notify_debug; 830 wblock->handler = wmi_notify_debug;
868 status = wmi_method_enable(wblock, 1); 831 wmi_method_enable(wblock, 1);
869 } 832 }
870 list_add_tail(&wblock->list, &wmi_blocks.list);
871 } 833 }
872 834
873out_free_gblock: 835 retval = 0;
874 kfree(gblock); 836
875out_free_pointer: 837out_free_pointer:
876 kfree(out.pointer); 838 kfree(out.pointer);
877 839
878 return status; 840 return retval;
879} 841}
880 842
881/* 843/*
@@ -929,7 +891,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
929 struct list_head *p; 891 struct list_head *p;
930 char guid_string[37]; 892 char guid_string[37];
931 893
932 list_for_each(p, &wmi_blocks.list) { 894 list_for_each(p, &wmi_block_list) {
933 wblock = list_entry(p, struct wmi_block, list); 895 wblock = list_entry(p, struct wmi_block, list);
934 block = &wblock->gblock; 896 block = &wblock->gblock;
935 897
@@ -939,8 +901,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event)
939 wblock->handler(event, wblock->handler_data); 901 wblock->handler(event, wblock->handler_data);
940 if (debug_event) { 902 if (debug_event) {
941 wmi_gtoa(wblock->gblock.guid, guid_string); 903 wmi_gtoa(wblock->gblock.guid, guid_string);
942 printk(KERN_INFO PREFIX "DEBUG Event GUID:" 904 pr_info("DEBUG Event GUID: %s\n", guid_string);
943 " %s\n", guid_string);
944 } 905 }
945 906
946 acpi_bus_generate_netlink_event( 907 acpi_bus_generate_netlink_event(
@@ -955,6 +916,7 @@ static int acpi_wmi_remove(struct acpi_device *device, int type)
955{ 916{
956 acpi_remove_address_space_handler(device->handle, 917 acpi_remove_address_space_handler(device->handle,
957 ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); 918 ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
919 wmi_free_devices();
958 920
959 return 0; 921 return 0;
960} 922}
@@ -962,68 +924,57 @@ static int acpi_wmi_remove(struct acpi_device *device, int type)
962static int acpi_wmi_add(struct acpi_device *device) 924static int acpi_wmi_add(struct acpi_device *device)
963{ 925{
964 acpi_status status; 926 acpi_status status;
965 int result = 0; 927 int error;
966 928
967 status = acpi_install_address_space_handler(device->handle, 929 status = acpi_install_address_space_handler(device->handle,
968 ACPI_ADR_SPACE_EC, 930 ACPI_ADR_SPACE_EC,
969 &acpi_wmi_ec_space_handler, 931 &acpi_wmi_ec_space_handler,
970 NULL, NULL); 932 NULL, NULL);
971 if (ACPI_FAILURE(status))
972 return -ENODEV;
973
974 status = parse_wdg(device->handle);
975 if (ACPI_FAILURE(status)) { 933 if (ACPI_FAILURE(status)) {
976 printk(KERN_ERR PREFIX "Error installing EC region handler\n"); 934 pr_err("Error installing EC region handler\n");
977 return -ENODEV; 935 return -ENODEV;
978 } 936 }
979 937
980 return result; 938 error = parse_wdg(device->handle);
939 if (error) {
940 acpi_remove_address_space_handler(device->handle,
941 ACPI_ADR_SPACE_EC,
942 &acpi_wmi_ec_space_handler);
943 pr_err("Failed to parse WDG method\n");
944 return error;
945 }
946
947 return 0;
981} 948}
982 949
983static int __init acpi_wmi_init(void) 950static int __init acpi_wmi_init(void)
984{ 951{
985 int result; 952 int error;
986
987 INIT_LIST_HEAD(&wmi_blocks.list);
988 953
989 if (acpi_disabled) 954 if (acpi_disabled)
990 return -ENODEV; 955 return -ENODEV;
991 956
992 result = acpi_bus_register_driver(&acpi_wmi_driver); 957 error = class_register(&wmi_class);
993 958 if (error)
994 if (result < 0) { 959 return error;
995 printk(KERN_INFO PREFIX "Error loading mapper\n");
996 return -ENODEV;
997 }
998 960
999 result = wmi_class_init(); 961 error = acpi_bus_register_driver(&acpi_wmi_driver);
1000 if (result) { 962 if (error) {
1001 acpi_bus_unregister_driver(&acpi_wmi_driver); 963 pr_err("Error loading mapper\n");
1002 return result; 964 class_unregister(&wmi_class);
965 return error;
1003 } 966 }
1004 967
1005 printk(KERN_INFO PREFIX "Mapper loaded\n"); 968 pr_info("Mapper loaded\n");
1006 969 return 0;
1007 return result;
1008} 970}
1009 971
1010static void __exit acpi_wmi_exit(void) 972static void __exit acpi_wmi_exit(void)
1011{ 973{
1012 struct list_head *p, *tmp;
1013 struct wmi_block *wblock;
1014
1015 wmi_class_exit();
1016
1017 acpi_bus_unregister_driver(&acpi_wmi_driver); 974 acpi_bus_unregister_driver(&acpi_wmi_driver);
975 class_unregister(&wmi_class);
1018 976
1019 list_for_each_safe(p, tmp, &wmi_blocks.list) { 977 pr_info("Mapper unloaded\n");
1020 wblock = list_entry(p, struct wmi_block, list);
1021
1022 list_del(p);
1023 kfree(wblock);
1024 }
1025
1026 printk(KERN_INFO PREFIX "Mapper unloaded\n");
1027} 978}
1028 979
1029subsys_initcall(acpi_wmi_init); 980subsys_initcall(acpi_wmi_init);