]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/platform/x86/wmi.c
31c317fb65dc0800b3bbbaeaa1e066e68a22370f
[linux.git] / drivers / platform / x86 / wmi.c
1 /*
2  *  ACPI-WMI mapping driver
3  *
4  *  Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
5  *
6  *  GUID parsing code from ldm.c is:
7  *   Copyright (C) 2001,2002 Richard Russon <ldm@flatcap.org>
8  *   Copyright (c) 2001-2007 Anton Altaparmakov
9  *   Copyright (C) 2001,2002 Jakob Kemi <jakob.kemi@telia.com>
10  *
11  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or (at
16  *  your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful, but
19  *  WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  *  General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License along
24  *  with this program; if not, write to the Free Software Foundation, Inc.,
25  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26  *
27  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28  */
29
30 #define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
31
32 #include <linux/kernel.h>
33 #include <linux/init.h>
34 #include <linux/types.h>
35 #include <linux/device.h>
36 #include <linux/list.h>
37 #include <linux/acpi.h>
38 #include <linux/slab.h>
39 #include <linux/module.h>
40 #include <linux/wmi.h>
41 #include <linux/uuid.h>
42
43 ACPI_MODULE_NAME("wmi");
44 MODULE_AUTHOR("Carlos Corbacho");
45 MODULE_DESCRIPTION("ACPI-WMI Mapping Driver");
46 MODULE_LICENSE("GPL");
47
48 static LIST_HEAD(wmi_block_list);
49
50 struct guid_block {
51         char guid[16];
52         union {
53                 char object_id[2];
54                 struct {
55                         unsigned char notify_id;
56                         unsigned char reserved;
57                 };
58         };
59         u8 instance_count;
60         u8 flags;
61 };
62
63 struct wmi_block {
64         struct wmi_device dev;
65         struct list_head list;
66         struct guid_block gblock;
67         struct acpi_device *acpi_device;
68         wmi_notify_handler handler;
69         void *handler_data;
70 };
71
72
73 /*
74  * If the GUID data block is marked as expensive, we must enable and
75  * explicitily disable data collection.
76  */
77 #define ACPI_WMI_EXPENSIVE   0x1
78 #define ACPI_WMI_METHOD      0x2        /* GUID is a method */
79 #define ACPI_WMI_STRING      0x4        /* GUID takes & returns a string */
80 #define ACPI_WMI_EVENT       0x8        /* GUID is an event */
81
82 static bool debug_event;
83 module_param(debug_event, bool, 0444);
84 MODULE_PARM_DESC(debug_event,
85                  "Log WMI Events [0/1]");
86
87 static bool debug_dump_wdg;
88 module_param(debug_dump_wdg, bool, 0444);
89 MODULE_PARM_DESC(debug_dump_wdg,
90                  "Dump available WMI interfaces [0/1]");
91
92 static int acpi_wmi_remove(struct acpi_device *device);
93 static int acpi_wmi_add(struct acpi_device *device);
94 static void acpi_wmi_notify(struct acpi_device *device, u32 event);
95
96 static const struct acpi_device_id wmi_device_ids[] = {
97         {"PNP0C14", 0},
98         {"pnp0c14", 0},
99         {"", 0},
100 };
101 MODULE_DEVICE_TABLE(acpi, wmi_device_ids);
102
103 static struct acpi_driver acpi_wmi_driver = {
104         .name = "acpi-wmi",
105         .owner = THIS_MODULE,
106         .ids = wmi_device_ids,
107         .ops = {
108                 .add = acpi_wmi_add,
109                 .remove = acpi_wmi_remove,
110                 .notify = acpi_wmi_notify,
111         },
112 };
113
114 /*
115  * GUID parsing functions
116  */
117
118 static bool find_guid(const char *guid_string, struct wmi_block **out)
119 {
120         uuid_le guid_input;
121         struct wmi_block *wblock;
122         struct guid_block *block;
123         struct list_head *p;
124
125         if (uuid_le_to_bin(guid_string, &guid_input))
126                 return false;
127
128         list_for_each(p, &wmi_block_list) {
129                 wblock = list_entry(p, struct wmi_block, list);
130                 block = &wblock->gblock;
131
132                 if (memcmp(block->guid, &guid_input, 16) == 0) {
133                         if (out)
134                                 *out = wblock;
135                         return true;
136                 }
137         }
138         return false;
139 }
140
141 static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable)
142 {
143         struct guid_block *block = NULL;
144         char method[5];
145         acpi_status status;
146         acpi_handle handle;
147
148         block = &wblock->gblock;
149         handle = wblock->acpi_device->handle;
150
151         snprintf(method, 5, "WE%02X", block->notify_id);
152         status = acpi_execute_simple_method(handle, method, enable);
153
154         if (status != AE_OK && status != AE_NOT_FOUND)
155                 return status;
156         else
157                 return AE_OK;
158 }
159
160 /*
161  * Exported WMI functions
162  */
163 /**
164  * wmi_evaluate_method - Evaluate a WMI method
165  * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
166  * @instance: Instance index
167  * @method_id: Method ID to call
168  * &in: Buffer containing input for the method call
169  * &out: Empty buffer to return the method results
170  *
171  * Call an ACPI-WMI method
172  */
173 acpi_status wmi_evaluate_method(const char *guid_string, u8 instance,
174 u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
175 {
176         struct guid_block *block = NULL;
177         struct wmi_block *wblock = NULL;
178         acpi_handle handle;
179         acpi_status status;
180         struct acpi_object_list input;
181         union acpi_object params[3];
182         char method[5] = "WM";
183
184         if (!find_guid(guid_string, &wblock))
185                 return AE_ERROR;
186
187         block = &wblock->gblock;
188         handle = wblock->acpi_device->handle;
189
190         if (!(block->flags & ACPI_WMI_METHOD))
191                 return AE_BAD_DATA;
192
193         if (block->instance_count < instance)
194                 return AE_BAD_PARAMETER;
195
196         input.count = 2;
197         input.pointer = params;
198         params[0].type = ACPI_TYPE_INTEGER;
199         params[0].integer.value = instance;
200         params[1].type = ACPI_TYPE_INTEGER;
201         params[1].integer.value = method_id;
202
203         if (in) {
204                 input.count = 3;
205
206                 if (block->flags & ACPI_WMI_STRING) {
207                         params[2].type = ACPI_TYPE_STRING;
208                 } else {
209                         params[2].type = ACPI_TYPE_BUFFER;
210                 }
211                 params[2].buffer.length = in->length;
212                 params[2].buffer.pointer = in->pointer;
213         }
214
215         strncat(method, block->object_id, 2);
216
217         status = acpi_evaluate_object(handle, method, &input, out);
218
219         return status;
220 }
221 EXPORT_SYMBOL_GPL(wmi_evaluate_method);
222
223 /**
224  * wmi_query_block - Return contents of a WMI block
225  * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
226  * @instance: Instance index
227  * &out: Empty buffer to return the contents of the data block to
228  *
229  * Return the contents of an ACPI-WMI data block to a buffer
230  */
231 acpi_status wmi_query_block(const char *guid_string, u8 instance,
232 struct acpi_buffer *out)
233 {
234         struct guid_block *block = NULL;
235         struct wmi_block *wblock = NULL;
236         acpi_handle handle;
237         acpi_status status, wc_status = AE_ERROR;
238         struct acpi_object_list input;
239         union acpi_object wq_params[1];
240         char method[5];
241         char wc_method[5] = "WC";
242
243         if (!guid_string || !out)
244                 return AE_BAD_PARAMETER;
245
246         if (!find_guid(guid_string, &wblock))
247                 return AE_ERROR;
248
249         block = &wblock->gblock;
250         handle = wblock->acpi_device->handle;
251
252         if (block->instance_count < instance)
253                 return AE_BAD_PARAMETER;
254
255         /* Check GUID is a data block */
256         if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
257                 return AE_ERROR;
258
259         input.count = 1;
260         input.pointer = wq_params;
261         wq_params[0].type = ACPI_TYPE_INTEGER;
262         wq_params[0].integer.value = instance;
263
264         /*
265          * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to
266          * enable collection.
267          */
268         if (block->flags & ACPI_WMI_EXPENSIVE) {
269                 strncat(wc_method, block->object_id, 2);
270
271                 /*
272                  * Some GUIDs break the specification by declaring themselves
273                  * expensive, but have no corresponding WCxx method. So we
274                  * should not fail if this happens.
275                  */
276                 if (acpi_has_method(handle, wc_method))
277                         wc_status = acpi_execute_simple_method(handle,
278                                                                 wc_method, 1);
279         }
280
281         strcpy(method, "WQ");
282         strncat(method, block->object_id, 2);
283
284         status = acpi_evaluate_object(handle, method, &input, out);
285
286         /*
287          * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
288          * the WQxx method failed - we should disable collection anyway.
289          */
290         if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) {
291                 status = acpi_execute_simple_method(handle, wc_method, 0);
292         }
293
294         return status;
295 }
296 EXPORT_SYMBOL_GPL(wmi_query_block);
297
298 /**
299  * wmi_set_block - Write to a WMI block
300  * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
301  * @instance: Instance index
302  * &in: Buffer containing new values for the data block
303  *
304  * Write the contents of the input buffer to an ACPI-WMI data block
305  */
306 acpi_status wmi_set_block(const char *guid_string, u8 instance,
307 const struct acpi_buffer *in)
308 {
309         struct guid_block *block = NULL;
310         struct wmi_block *wblock = NULL;
311         acpi_handle handle;
312         struct acpi_object_list input;
313         union acpi_object params[2];
314         char method[5] = "WS";
315
316         if (!guid_string || !in)
317                 return AE_BAD_DATA;
318
319         if (!find_guid(guid_string, &wblock))
320                 return AE_ERROR;
321
322         block = &wblock->gblock;
323         handle = wblock->acpi_device->handle;
324
325         if (block->instance_count < instance)
326                 return AE_BAD_PARAMETER;
327
328         /* Check GUID is a data block */
329         if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD))
330                 return AE_ERROR;
331
332         input.count = 2;
333         input.pointer = params;
334         params[0].type = ACPI_TYPE_INTEGER;
335         params[0].integer.value = instance;
336
337         if (block->flags & ACPI_WMI_STRING) {
338                 params[1].type = ACPI_TYPE_STRING;
339         } else {
340                 params[1].type = ACPI_TYPE_BUFFER;
341         }
342         params[1].buffer.length = in->length;
343         params[1].buffer.pointer = in->pointer;
344
345         strncat(method, block->object_id, 2);
346
347         return acpi_evaluate_object(handle, method, &input, NULL);
348 }
349 EXPORT_SYMBOL_GPL(wmi_set_block);
350
351 static void wmi_dump_wdg(const struct guid_block *g)
352 {
353         pr_info("%pUL:\n", g->guid);
354         pr_info("\tobject_id: %c%c\n", g->object_id[0], g->object_id[1]);
355         pr_info("\tnotify_id: %02X\n", g->notify_id);
356         pr_info("\treserved: %02X\n", g->reserved);
357         pr_info("\tinstance_count: %d\n", g->instance_count);
358         pr_info("\tflags: %#x", g->flags);
359         if (g->flags) {
360                 if (g->flags & ACPI_WMI_EXPENSIVE)
361                         pr_cont(" ACPI_WMI_EXPENSIVE");
362                 if (g->flags & ACPI_WMI_METHOD)
363                         pr_cont(" ACPI_WMI_METHOD");
364                 if (g->flags & ACPI_WMI_STRING)
365                         pr_cont(" ACPI_WMI_STRING");
366                 if (g->flags & ACPI_WMI_EVENT)
367                         pr_cont(" ACPI_WMI_EVENT");
368         }
369         pr_cont("\n");
370
371 }
372
373 static void wmi_notify_debug(u32 value, void *context)
374 {
375         struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
376         union acpi_object *obj;
377         acpi_status status;
378
379         status = wmi_get_event_data(value, &response);
380         if (status != AE_OK) {
381                 pr_info("bad event status 0x%x\n", status);
382                 return;
383         }
384
385         obj = (union acpi_object *)response.pointer;
386
387         if (!obj)
388                 return;
389
390         pr_info("DEBUG Event ");
391         switch(obj->type) {
392         case ACPI_TYPE_BUFFER:
393                 pr_cont("BUFFER_TYPE - length %d\n", obj->buffer.length);
394                 break;
395         case ACPI_TYPE_STRING:
396                 pr_cont("STRING_TYPE - %s\n", obj->string.pointer);
397                 break;
398         case ACPI_TYPE_INTEGER:
399                 pr_cont("INTEGER_TYPE - %llu\n", obj->integer.value);
400                 break;
401         case ACPI_TYPE_PACKAGE:
402                 pr_cont("PACKAGE_TYPE - %d elements\n", obj->package.count);
403                 break;
404         default:
405                 pr_cont("object type 0x%X\n", obj->type);
406         }
407         kfree(obj);
408 }
409
410 /**
411  * wmi_install_notify_handler - Register handler for WMI events
412  * @handler: Function to handle notifications
413  * @data: Data to be returned to handler when event is fired
414  *
415  * Register a handler for events sent to the ACPI-WMI mapper device.
416  */
417 acpi_status wmi_install_notify_handler(const char *guid,
418 wmi_notify_handler handler, void *data)
419 {
420         struct wmi_block *block;
421         acpi_status status = AE_NOT_EXIST;
422         uuid_le guid_input;
423         struct list_head *p;
424
425         if (!guid || !handler)
426                 return AE_BAD_PARAMETER;
427
428         if (uuid_le_to_bin(guid, &guid_input))
429                 return AE_BAD_PARAMETER;
430
431         list_for_each(p, &wmi_block_list) {
432                 acpi_status wmi_status;
433                 block = list_entry(p, struct wmi_block, list);
434
435                 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
436                         if (block->handler &&
437                             block->handler != wmi_notify_debug)
438                                 return AE_ALREADY_ACQUIRED;
439
440                         block->handler = handler;
441                         block->handler_data = data;
442
443                         wmi_status = wmi_method_enable(block, 1);
444                         if ((wmi_status != AE_OK) ||
445                             ((wmi_status == AE_OK) && (status == AE_NOT_EXIST)))
446                                 status = wmi_status;
447                 }
448         }
449
450         return status;
451 }
452 EXPORT_SYMBOL_GPL(wmi_install_notify_handler);
453
454 /**
455  * wmi_uninstall_notify_handler - Unregister handler for WMI events
456  *
457  * Unregister handler for events sent to the ACPI-WMI mapper device.
458  */
459 acpi_status wmi_remove_notify_handler(const char *guid)
460 {
461         struct wmi_block *block;
462         acpi_status status = AE_NOT_EXIST;
463         uuid_le guid_input;
464         struct list_head *p;
465
466         if (!guid)
467                 return AE_BAD_PARAMETER;
468
469         if (uuid_le_to_bin(guid, &guid_input))
470                 return AE_BAD_PARAMETER;
471
472         list_for_each(p, &wmi_block_list) {
473                 acpi_status wmi_status;
474                 block = list_entry(p, struct wmi_block, list);
475
476                 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
477                         if (!block->handler ||
478                             block->handler == wmi_notify_debug)
479                                 return AE_NULL_ENTRY;
480
481                         if (debug_event) {
482                                 block->handler = wmi_notify_debug;
483                                 status = AE_OK;
484                         } else {
485                                 wmi_status = wmi_method_enable(block, 0);
486                                 block->handler = NULL;
487                                 block->handler_data = NULL;
488                                 if ((wmi_status != AE_OK) ||
489                                     ((wmi_status == AE_OK) &&
490                                      (status == AE_NOT_EXIST)))
491                                         status = wmi_status;
492                         }
493                 }
494         }
495
496         return status;
497 }
498 EXPORT_SYMBOL_GPL(wmi_remove_notify_handler);
499
500 /**
501  * wmi_get_event_data - Get WMI data associated with an event
502  *
503  * @event: Event to find
504  * @out: Buffer to hold event data. out->pointer should be freed with kfree()
505  *
506  * Returns extra data associated with an event in WMI.
507  */
508 acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out)
509 {
510         struct acpi_object_list input;
511         union acpi_object params[1];
512         struct guid_block *gblock;
513         struct wmi_block *wblock;
514         struct list_head *p;
515
516         input.count = 1;
517         input.pointer = params;
518         params[0].type = ACPI_TYPE_INTEGER;
519         params[0].integer.value = event;
520
521         list_for_each(p, &wmi_block_list) {
522                 wblock = list_entry(p, struct wmi_block, list);
523                 gblock = &wblock->gblock;
524
525                 if ((gblock->flags & ACPI_WMI_EVENT) &&
526                         (gblock->notify_id == event))
527                         return acpi_evaluate_object(wblock->acpi_device->handle,
528                                 "_WED", &input, out);
529         }
530
531         return AE_NOT_FOUND;
532 }
533 EXPORT_SYMBOL_GPL(wmi_get_event_data);
534
535 /**
536  * wmi_has_guid - Check if a GUID is available
537  * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
538  *
539  * Check if a given GUID is defined by _WDG
540  */
541 bool wmi_has_guid(const char *guid_string)
542 {
543         return find_guid(guid_string, NULL);
544 }
545 EXPORT_SYMBOL_GPL(wmi_has_guid);
546
547 static struct wmi_block *dev_to_wblock(struct device *dev)
548 {
549         return container_of(dev, struct wmi_block, dev.dev);
550 }
551
552 static struct wmi_device *dev_to_wdev(struct device *dev)
553 {
554         return container_of(dev, struct wmi_device, dev);
555 }
556
557 /*
558  * sysfs interface
559  */
560 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
561                              char *buf)
562 {
563         struct wmi_block *wblock = dev_to_wblock(dev);
564
565         return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid);
566 }
567 static DEVICE_ATTR_RO(modalias);
568
569 static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
570                          char *buf)
571 {
572         struct wmi_block *wblock = dev_to_wblock(dev);
573
574         return sprintf(buf, "%pUL\n", wblock->gblock.guid);
575 }
576 static DEVICE_ATTR_RO(guid);
577
578 static struct attribute *wmi_attrs[] = {
579         &dev_attr_modalias.attr,
580         &dev_attr_guid.attr,
581         NULL,
582 };
583 ATTRIBUTE_GROUPS(wmi);
584
585 static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
586 {
587         struct wmi_block *wblock = dev_to_wblock(dev);
588
589         if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid))
590                 return -ENOMEM;
591
592         if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid))
593                 return -ENOMEM;
594
595         return 0;
596 }
597
598 static void wmi_dev_release(struct device *dev)
599 {
600         struct wmi_block *wblock = dev_to_wblock(dev);
601
602         kfree(wblock);
603 }
604
605 static int wmi_dev_match(struct device *dev, struct device_driver *driver)
606 {
607         struct wmi_driver *wmi_driver =
608                 container_of(driver, struct wmi_driver, driver);
609         struct wmi_block *wblock = dev_to_wblock(dev);
610         const struct wmi_device_id *id = wmi_driver->id_table;
611
612         while (id->guid_string) {
613                 uuid_le driver_guid;
614
615                 if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid)))
616                         continue;
617                 if (!memcmp(&driver_guid, wblock->gblock.guid, 16))
618                         return 1;
619
620                 id++;
621         }
622
623         return 0;
624 }
625
626 static int wmi_dev_probe(struct device *dev)
627 {
628         struct wmi_block *wblock = dev_to_wblock(dev);
629         struct wmi_driver *wdriver =
630                 container_of(dev->driver, struct wmi_driver, driver);
631         int ret = 0;
632
633         if (ACPI_FAILURE(wmi_method_enable(wblock, 1)))
634                 dev_warn(dev, "failed to enable device -- probing anyway\n");
635
636         if (wdriver->probe) {
637                 ret = wdriver->probe(dev_to_wdev(dev));
638                 if (ret != 0 && ACPI_FAILURE(wmi_method_enable(wblock, 0)))
639                         dev_warn(dev, "failed to disable device\n");
640         }
641
642         return ret;
643 }
644
645 static int wmi_dev_remove(struct device *dev)
646 {
647         struct wmi_block *wblock = dev_to_wblock(dev);
648         struct wmi_driver *wdriver =
649                 container_of(dev->driver, struct wmi_driver, driver);
650         int ret = 0;
651
652         if (wdriver->remove)
653                 ret = wdriver->remove(dev_to_wdev(dev));
654
655         if (ACPI_FAILURE(wmi_method_enable(wblock, 0)))
656                 dev_warn(dev, "failed to disable device\n");
657
658         return ret;
659 }
660
661 static struct class wmi_bus_class = {
662         .name = "wmi_bus",
663 };
664
665 static struct bus_type wmi_bus_type = {
666         .name = "wmi",
667         .dev_groups = wmi_groups,
668         .match = wmi_dev_match,
669         .uevent = wmi_dev_uevent,
670         .probe = wmi_dev_probe,
671         .remove = wmi_dev_remove,
672 };
673
674 static int wmi_create_device(struct device *wmi_bus_dev,
675                              const struct guid_block *gblock,
676                              struct wmi_block *wblock,
677                              struct acpi_device *device)
678 {
679         wblock->dev.dev.bus = &wmi_bus_type;
680         wblock->dev.dev.parent = wmi_bus_dev;
681
682         dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid);
683
684         wblock->dev.dev.release = wmi_dev_release;
685
686         return device_register(&wblock->dev.dev);
687 }
688
689 static void wmi_free_devices(struct acpi_device *device)
690 {
691         struct wmi_block *wblock, *next;
692
693         /* Delete devices for all the GUIDs */
694         list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
695                 if (wblock->acpi_device == device) {
696                         list_del(&wblock->list);
697                         if (wblock->dev.dev.bus)
698                                 device_unregister(&wblock->dev.dev);
699                         else
700                                 kfree(wblock);
701                 }
702         }
703 }
704
705 static bool guid_already_parsed(struct acpi_device *device,
706                                 const u8 *guid)
707 {
708         struct wmi_block *wblock;
709
710         list_for_each_entry(wblock, &wmi_block_list, list) {
711                 if (memcmp(wblock->gblock.guid, guid, 16) == 0) {
712                         /*
713                          * Because we historically didn't track the relationship
714                          * between GUIDs and ACPI nodes, we don't know whether
715                          * we need to suppress GUIDs that are unique on a
716                          * given node but duplicated across nodes.
717                          */
718                         dev_warn(&device->dev, "duplicate WMI GUID %pUL (first instance was on %s)\n",
719                                  guid, dev_name(&wblock->acpi_device->dev));
720                         return true;
721                 }
722         }
723
724         return false;
725 }
726
727 /*
728  * Parse the _WDG method for the GUID data blocks
729  */
730 static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
731 {
732         struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
733         union acpi_object *obj;
734         const struct guid_block *gblock;
735         struct wmi_block *wblock;
736         acpi_status status;
737         int retval;
738         u32 i, total;
739
740         status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
741         if (ACPI_FAILURE(status))
742                 return -ENXIO;
743
744         obj = (union acpi_object *) out.pointer;
745         if (!obj)
746                 return -ENXIO;
747
748         if (obj->type != ACPI_TYPE_BUFFER) {
749                 retval = -ENXIO;
750                 goto out_free_pointer;
751         }
752
753         gblock = (const struct guid_block *)obj->buffer.pointer;
754         total = obj->buffer.length / sizeof(struct guid_block);
755
756         for (i = 0; i < total; i++) {
757                 if (debug_dump_wdg)
758                         wmi_dump_wdg(&gblock[i]);
759
760                 /*
761                  * Some WMI devices, like those for nVidia hooks, have a
762                  * duplicate GUID. It's not clear what we should do in this
763                  * case yet, so for now, we'll just ignore the duplicate
764                  * for device creation.
765                  */
766                 if (guid_already_parsed(device, gblock[i].guid))
767                         continue;
768
769                 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
770                 if (!wblock)
771                         return -ENOMEM;
772
773                 wblock->acpi_device = device;
774                 wblock->gblock = gblock[i];
775
776                 retval = wmi_create_device(wmi_bus_dev, &gblock[i],
777                                            wblock, device);
778                 if (retval) {
779                         put_device(&wblock->dev.dev);
780                         wmi_free_devices(device);
781                         goto out_free_pointer;
782                 }
783
784                 list_add_tail(&wblock->list, &wmi_block_list);
785
786                 if (debug_event) {
787                         wblock->handler = wmi_notify_debug;
788                         wmi_method_enable(wblock, 1);
789                 }
790         }
791
792         retval = 0;
793
794 out_free_pointer:
795         kfree(out.pointer);
796
797         return retval;
798 }
799
800 /*
801  * WMI can have EmbeddedControl access regions. In which case, we just want to
802  * hand these off to the EC driver.
803  */
804 static acpi_status
805 acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address,
806                       u32 bits, u64 *value,
807                       void *handler_context, void *region_context)
808 {
809         int result = 0, i = 0;
810         u8 temp = 0;
811
812         if ((address > 0xFF) || !value)
813                 return AE_BAD_PARAMETER;
814
815         if (function != ACPI_READ && function != ACPI_WRITE)
816                 return AE_BAD_PARAMETER;
817
818         if (bits != 8)
819                 return AE_BAD_PARAMETER;
820
821         if (function == ACPI_READ) {
822                 result = ec_read(address, &temp);
823                 (*value) |= ((u64)temp) << i;
824         } else {
825                 temp = 0xff & ((*value) >> i);
826                 result = ec_write(address, temp);
827         }
828
829         switch (result) {
830         case -EINVAL:
831                 return AE_BAD_PARAMETER;
832                 break;
833         case -ENODEV:
834                 return AE_NOT_FOUND;
835                 break;
836         case -ETIME:
837                 return AE_TIME;
838                 break;
839         default:
840                 return AE_OK;
841         }
842 }
843
844 static void acpi_wmi_notify(struct acpi_device *device, u32 event)
845 {
846         struct guid_block *block;
847         struct wmi_block *wblock;
848         struct list_head *p;
849
850         list_for_each(p, &wmi_block_list) {
851                 wblock = list_entry(p, struct wmi_block, list);
852                 block = &wblock->gblock;
853
854                 if (wblock->acpi_device == device &&
855                     (block->flags & ACPI_WMI_EVENT) &&
856                     (block->notify_id == event)) {
857                         if (wblock->handler)
858                                 wblock->handler(event, wblock->handler_data);
859                         if (debug_event) {
860                                 pr_info("DEBUG Event GUID: %pUL\n",
861                                         wblock->gblock.guid);
862                         }
863
864                         acpi_bus_generate_netlink_event(
865                                 device->pnp.device_class, dev_name(&device->dev),
866                                 event, 0);
867                         break;
868                 }
869         }
870 }
871
872 static int acpi_wmi_remove(struct acpi_device *device)
873 {
874         acpi_remove_address_space_handler(device->handle,
875                                 ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
876         wmi_free_devices(device);
877         device_unregister((struct device *)acpi_driver_data(device));
878         device->driver_data = NULL;
879
880         return 0;
881 }
882
883 static int acpi_wmi_add(struct acpi_device *device)
884 {
885         struct device *wmi_bus_dev;
886         acpi_status status;
887         int error;
888
889         status = acpi_install_address_space_handler(device->handle,
890                                                     ACPI_ADR_SPACE_EC,
891                                                     &acpi_wmi_ec_space_handler,
892                                                     NULL, NULL);
893         if (ACPI_FAILURE(status)) {
894                 dev_err(&device->dev, "Error installing EC region handler\n");
895                 return -ENODEV;
896         }
897
898         wmi_bus_dev = device_create(&wmi_bus_class, &device->dev, MKDEV(0, 0),
899                                     NULL, "wmi_bus-%s", dev_name(&device->dev));
900         if (IS_ERR(wmi_bus_dev)) {
901                 error = PTR_ERR(wmi_bus_dev);
902                 goto err_remove_handler;
903         }
904         device->driver_data = wmi_bus_dev;
905
906         error = parse_wdg(wmi_bus_dev, device);
907         if (error) {
908                 pr_err("Failed to parse WDG method\n");
909                 goto err_remove_busdev;
910         }
911
912         return 0;
913
914 err_remove_busdev:
915         device_unregister(wmi_bus_dev);
916
917 err_remove_handler:
918         acpi_remove_address_space_handler(device->handle,
919                                           ACPI_ADR_SPACE_EC,
920                                           &acpi_wmi_ec_space_handler);
921
922         return error;
923 }
924
925 int __must_check __wmi_driver_register(struct wmi_driver *driver,
926                                        struct module *owner)
927 {
928         driver->driver.owner = owner;
929         driver->driver.bus = &wmi_bus_type;
930
931         return driver_register(&driver->driver);
932 }
933 EXPORT_SYMBOL(__wmi_driver_register);
934
935 void wmi_driver_unregister(struct wmi_driver *driver)
936 {
937         driver_unregister(&driver->driver);
938 }
939 EXPORT_SYMBOL(wmi_driver_unregister);
940
941 static int __init acpi_wmi_init(void)
942 {
943         int error;
944
945         if (acpi_disabled)
946                 return -ENODEV;
947
948         error = class_register(&wmi_bus_class);
949         if (error)
950                 return error;
951
952         error = bus_register(&wmi_bus_type);
953         if (error)
954                 goto err_unreg_class;
955
956         error = acpi_bus_register_driver(&acpi_wmi_driver);
957         if (error) {
958                 pr_err("Error loading mapper\n");
959                 goto err_unreg_bus;
960         }
961
962         return 0;
963
964 err_unreg_class:
965         class_unregister(&wmi_bus_class);
966
967 err_unreg_bus:
968         bus_unregister(&wmi_bus_type);
969
970         return error;
971 }
972
973 static void __exit acpi_wmi_exit(void)
974 {
975         acpi_bus_unregister_driver(&acpi_wmi_driver);
976         class_unregister(&wmi_bus_class);
977         bus_unregister(&wmi_bus_type);
978 }
979
980 subsys_initcall(acpi_wmi_init);
981 module_exit(acpi_wmi_exit);