2 * ACPI-WMI mapping driver
4 * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
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>
11 * WMI bus infrastructure by Andrew Lutomirski and Darren Hart:
12 * Copyright (C) 2015 Andrew Lutomirski
13 * Copyright (C) 2017 VMware, Inc. All Rights Reserved.
15 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or (at
20 * your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
31 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
34 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
36 #include <linux/kernel.h>
37 #include <linux/init.h>
38 #include <linux/types.h>
39 #include <linux/device.h>
40 #include <linux/list.h>
41 #include <linux/acpi.h>
42 #include <linux/slab.h>
43 #include <linux/module.h>
44 #include <linux/platform_device.h>
45 #include <linux/wmi.h>
46 #include <linux/uuid.h>
48 ACPI_MODULE_NAME("wmi");
49 MODULE_AUTHOR("Carlos Corbacho");
50 MODULE_DESCRIPTION("ACPI-WMI Mapping Driver");
51 MODULE_LICENSE("GPL");
53 static LIST_HEAD(wmi_block_list
);
60 unsigned char notify_id
;
61 unsigned char reserved
;
69 struct wmi_device dev
;
70 struct list_head list
;
71 struct guid_block gblock
;
72 struct acpi_device
*acpi_device
;
73 wmi_notify_handler handler
;
76 bool read_takes_no_args
;
81 * If the GUID data block is marked as expensive, we must enable and
82 * explicitily disable data collection.
84 #define ACPI_WMI_EXPENSIVE 0x1
85 #define ACPI_WMI_METHOD 0x2 /* GUID is a method */
86 #define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */
87 #define ACPI_WMI_EVENT 0x8 /* GUID is an event */
89 static bool debug_event
;
90 module_param(debug_event
, bool, 0444);
91 MODULE_PARM_DESC(debug_event
,
92 "Log WMI Events [0/1]");
94 static bool debug_dump_wdg
;
95 module_param(debug_dump_wdg
, bool, 0444);
96 MODULE_PARM_DESC(debug_dump_wdg
,
97 "Dump available WMI interfaces [0/1]");
99 static int acpi_wmi_remove(struct platform_device
*device
);
100 static int acpi_wmi_probe(struct platform_device
*device
);
102 static const struct acpi_device_id wmi_device_ids
[] = {
107 MODULE_DEVICE_TABLE(acpi
, wmi_device_ids
);
109 static struct platform_driver acpi_wmi_driver
= {
112 .acpi_match_table
= wmi_device_ids
,
114 .probe
= acpi_wmi_probe
,
115 .remove
= acpi_wmi_remove
,
119 * GUID parsing functions
122 static bool find_guid(const char *guid_string
, struct wmi_block
**out
)
125 struct wmi_block
*wblock
;
126 struct guid_block
*block
;
129 if (uuid_le_to_bin(guid_string
, &guid_input
))
132 list_for_each(p
, &wmi_block_list
) {
133 wblock
= list_entry(p
, struct wmi_block
, list
);
134 block
= &wblock
->gblock
;
136 if (memcmp(block
->guid
, &guid_input
, 16) == 0) {
145 static int get_subobj_info(acpi_handle handle
, const char *pathname
,
146 struct acpi_device_info
**info
)
148 struct acpi_device_info
*dummy_info
, **info_ptr
;
149 acpi_handle subobj_handle
;
152 status
= acpi_get_handle(handle
, (char *)pathname
, &subobj_handle
);
153 if (status
== AE_NOT_FOUND
)
155 else if (ACPI_FAILURE(status
))
158 info_ptr
= info
? info
: &dummy_info
;
159 status
= acpi_get_object_info(subobj_handle
, info_ptr
);
160 if (ACPI_FAILURE(status
))
169 static acpi_status
wmi_method_enable(struct wmi_block
*wblock
, int enable
)
171 struct guid_block
*block
= NULL
;
176 block
= &wblock
->gblock
;
177 handle
= wblock
->acpi_device
->handle
;
179 snprintf(method
, 5, "WE%02X", block
->notify_id
);
180 status
= acpi_execute_simple_method(handle
, method
, enable
);
182 if (status
!= AE_OK
&& status
!= AE_NOT_FOUND
)
189 * Exported WMI functions
192 * wmi_evaluate_method - Evaluate a WMI method
193 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
194 * @instance: Instance index
195 * @method_id: Method ID to call
196 * &in: Buffer containing input for the method call
197 * &out: Empty buffer to return the method results
199 * Call an ACPI-WMI method
201 acpi_status
wmi_evaluate_method(const char *guid_string
, u8 instance
,
202 u32 method_id
, const struct acpi_buffer
*in
, struct acpi_buffer
*out
)
204 struct guid_block
*block
= NULL
;
205 struct wmi_block
*wblock
= NULL
;
208 struct acpi_object_list input
;
209 union acpi_object params
[3];
210 char method
[5] = "WM";
212 if (!find_guid(guid_string
, &wblock
))
215 block
= &wblock
->gblock
;
216 handle
= wblock
->acpi_device
->handle
;
218 if (!(block
->flags
& ACPI_WMI_METHOD
))
221 if (block
->instance_count
<= instance
)
222 return AE_BAD_PARAMETER
;
225 input
.pointer
= params
;
226 params
[0].type
= ACPI_TYPE_INTEGER
;
227 params
[0].integer
.value
= instance
;
228 params
[1].type
= ACPI_TYPE_INTEGER
;
229 params
[1].integer
.value
= method_id
;
234 if (block
->flags
& ACPI_WMI_STRING
) {
235 params
[2].type
= ACPI_TYPE_STRING
;
237 params
[2].type
= ACPI_TYPE_BUFFER
;
239 params
[2].buffer
.length
= in
->length
;
240 params
[2].buffer
.pointer
= in
->pointer
;
243 strncat(method
, block
->object_id
, 2);
245 status
= acpi_evaluate_object(handle
, method
, &input
, out
);
249 EXPORT_SYMBOL_GPL(wmi_evaluate_method
);
251 static acpi_status
__query_block(struct wmi_block
*wblock
, u8 instance
,
252 struct acpi_buffer
*out
)
254 struct guid_block
*block
= NULL
;
256 acpi_status status
, wc_status
= AE_ERROR
;
257 struct acpi_object_list input
;
258 union acpi_object wq_params
[1];
260 char wc_method
[5] = "WC";
263 return AE_BAD_PARAMETER
;
265 block
= &wblock
->gblock
;
266 handle
= wblock
->acpi_device
->handle
;
268 if (block
->instance_count
<= instance
)
269 return AE_BAD_PARAMETER
;
271 /* Check GUID is a data block */
272 if (block
->flags
& (ACPI_WMI_EVENT
| ACPI_WMI_METHOD
))
276 input
.pointer
= wq_params
;
277 wq_params
[0].type
= ACPI_TYPE_INTEGER
;
278 wq_params
[0].integer
.value
= instance
;
280 if (instance
== 0 && wblock
->read_takes_no_args
)
284 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to
287 if (block
->flags
& ACPI_WMI_EXPENSIVE
) {
288 strncat(wc_method
, block
->object_id
, 2);
291 * Some GUIDs break the specification by declaring themselves
292 * expensive, but have no corresponding WCxx method. So we
293 * should not fail if this happens.
295 if (acpi_has_method(handle
, wc_method
))
296 wc_status
= acpi_execute_simple_method(handle
,
300 strcpy(method
, "WQ");
301 strncat(method
, block
->object_id
, 2);
303 status
= acpi_evaluate_object(handle
, method
, &input
, out
);
306 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
307 * the WQxx method failed - we should disable collection anyway.
309 if ((block
->flags
& ACPI_WMI_EXPENSIVE
) && ACPI_SUCCESS(wc_status
)) {
310 status
= acpi_execute_simple_method(handle
, wc_method
, 0);
317 * wmi_query_block - Return contents of a WMI block (deprecated)
318 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
319 * @instance: Instance index
320 * &out: Empty buffer to return the contents of the data block to
322 * Return the contents of an ACPI-WMI data block to a buffer
324 acpi_status
wmi_query_block(const char *guid_string
, u8 instance
,
325 struct acpi_buffer
*out
)
327 struct wmi_block
*wblock
;
330 return AE_BAD_PARAMETER
;
332 if (!find_guid(guid_string
, &wblock
))
335 return __query_block(wblock
, instance
, out
);
337 EXPORT_SYMBOL_GPL(wmi_query_block
);
339 union acpi_object
*wmidev_block_query(struct wmi_device
*wdev
, u8 instance
)
341 struct acpi_buffer out
= { ACPI_ALLOCATE_BUFFER
, NULL
};
342 struct wmi_block
*wblock
= container_of(wdev
, struct wmi_block
, dev
);
344 if (ACPI_FAILURE(__query_block(wblock
, instance
, &out
)))
347 return (union acpi_object
*)out
.pointer
;
349 EXPORT_SYMBOL_GPL(wmidev_block_query
);
351 struct wmi_device
*wmidev_get_other_guid(struct wmi_device
*wdev
,
352 const char *guid_string
)
354 struct wmi_block
*this_wb
= container_of(wdev
, struct wmi_block
, dev
);
355 struct wmi_block
*other_wb
;
357 if (!find_guid(guid_string
, &other_wb
))
360 if (other_wb
->acpi_device
!= this_wb
->acpi_device
)
363 get_device(&other_wb
->dev
.dev
);
364 return &other_wb
->dev
;
366 EXPORT_SYMBOL_GPL(wmidev_get_other_guid
);
369 * wmi_set_block - Write to a WMI block
370 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
371 * @instance: Instance index
372 * &in: Buffer containing new values for the data block
374 * Write the contents of the input buffer to an ACPI-WMI data block
376 acpi_status
wmi_set_block(const char *guid_string
, u8 instance
,
377 const struct acpi_buffer
*in
)
379 struct guid_block
*block
= NULL
;
380 struct wmi_block
*wblock
= NULL
;
382 struct acpi_object_list input
;
383 union acpi_object params
[2];
384 char method
[5] = "WS";
386 if (!guid_string
|| !in
)
389 if (!find_guid(guid_string
, &wblock
))
392 block
= &wblock
->gblock
;
393 handle
= wblock
->acpi_device
->handle
;
395 if (block
->instance_count
<= instance
)
396 return AE_BAD_PARAMETER
;
398 /* Check GUID is a data block */
399 if (block
->flags
& (ACPI_WMI_EVENT
| ACPI_WMI_METHOD
))
403 input
.pointer
= params
;
404 params
[0].type
= ACPI_TYPE_INTEGER
;
405 params
[0].integer
.value
= instance
;
407 if (block
->flags
& ACPI_WMI_STRING
) {
408 params
[1].type
= ACPI_TYPE_STRING
;
410 params
[1].type
= ACPI_TYPE_BUFFER
;
412 params
[1].buffer
.length
= in
->length
;
413 params
[1].buffer
.pointer
= in
->pointer
;
415 strncat(method
, block
->object_id
, 2);
417 return acpi_evaluate_object(handle
, method
, &input
, NULL
);
419 EXPORT_SYMBOL_GPL(wmi_set_block
);
421 static void wmi_dump_wdg(const struct guid_block
*g
)
423 pr_info("%pUL:\n", g
->guid
);
424 if (g
->flags
& ACPI_WMI_EVENT
)
425 pr_info("\tnotify_id: 0x%02X\n", g
->notify_id
);
427 pr_info("\tobject_id: %2pE\n", g
->object_id
);
428 pr_info("\tinstance_count: %d\n", g
->instance_count
);
429 pr_info("\tflags: %#x", g
->flags
);
431 if (g
->flags
& ACPI_WMI_EXPENSIVE
)
432 pr_cont(" ACPI_WMI_EXPENSIVE");
433 if (g
->flags
& ACPI_WMI_METHOD
)
434 pr_cont(" ACPI_WMI_METHOD");
435 if (g
->flags
& ACPI_WMI_STRING
)
436 pr_cont(" ACPI_WMI_STRING");
437 if (g
->flags
& ACPI_WMI_EVENT
)
438 pr_cont(" ACPI_WMI_EVENT");
444 static void wmi_notify_debug(u32 value
, void *context
)
446 struct acpi_buffer response
= { ACPI_ALLOCATE_BUFFER
, NULL
};
447 union acpi_object
*obj
;
450 status
= wmi_get_event_data(value
, &response
);
451 if (status
!= AE_OK
) {
452 pr_info("bad event status 0x%x\n", status
);
456 obj
= (union acpi_object
*)response
.pointer
;
461 pr_info("DEBUG Event ");
463 case ACPI_TYPE_BUFFER
:
464 pr_cont("BUFFER_TYPE - length %d\n", obj
->buffer
.length
);
466 case ACPI_TYPE_STRING
:
467 pr_cont("STRING_TYPE - %s\n", obj
->string
.pointer
);
469 case ACPI_TYPE_INTEGER
:
470 pr_cont("INTEGER_TYPE - %llu\n", obj
->integer
.value
);
472 case ACPI_TYPE_PACKAGE
:
473 pr_cont("PACKAGE_TYPE - %d elements\n", obj
->package
.count
);
476 pr_cont("object type 0x%X\n", obj
->type
);
482 * wmi_install_notify_handler - Register handler for WMI events
483 * @handler: Function to handle notifications
484 * @data: Data to be returned to handler when event is fired
486 * Register a handler for events sent to the ACPI-WMI mapper device.
488 acpi_status
wmi_install_notify_handler(const char *guid
,
489 wmi_notify_handler handler
, void *data
)
491 struct wmi_block
*block
;
492 acpi_status status
= AE_NOT_EXIST
;
496 if (!guid
|| !handler
)
497 return AE_BAD_PARAMETER
;
499 if (uuid_le_to_bin(guid
, &guid_input
))
500 return AE_BAD_PARAMETER
;
502 list_for_each(p
, &wmi_block_list
) {
503 acpi_status wmi_status
;
504 block
= list_entry(p
, struct wmi_block
, list
);
506 if (memcmp(block
->gblock
.guid
, &guid_input
, 16) == 0) {
507 if (block
->handler
&&
508 block
->handler
!= wmi_notify_debug
)
509 return AE_ALREADY_ACQUIRED
;
511 block
->handler
= handler
;
512 block
->handler_data
= data
;
514 wmi_status
= wmi_method_enable(block
, 1);
515 if ((wmi_status
!= AE_OK
) ||
516 ((wmi_status
== AE_OK
) && (status
== AE_NOT_EXIST
)))
523 EXPORT_SYMBOL_GPL(wmi_install_notify_handler
);
526 * wmi_uninstall_notify_handler - Unregister handler for WMI events
528 * Unregister handler for events sent to the ACPI-WMI mapper device.
530 acpi_status
wmi_remove_notify_handler(const char *guid
)
532 struct wmi_block
*block
;
533 acpi_status status
= AE_NOT_EXIST
;
538 return AE_BAD_PARAMETER
;
540 if (uuid_le_to_bin(guid
, &guid_input
))
541 return AE_BAD_PARAMETER
;
543 list_for_each(p
, &wmi_block_list
) {
544 acpi_status wmi_status
;
545 block
= list_entry(p
, struct wmi_block
, list
);
547 if (memcmp(block
->gblock
.guid
, &guid_input
, 16) == 0) {
548 if (!block
->handler
||
549 block
->handler
== wmi_notify_debug
)
550 return AE_NULL_ENTRY
;
553 block
->handler
= wmi_notify_debug
;
556 wmi_status
= wmi_method_enable(block
, 0);
557 block
->handler
= NULL
;
558 block
->handler_data
= NULL
;
559 if ((wmi_status
!= AE_OK
) ||
560 ((wmi_status
== AE_OK
) &&
561 (status
== AE_NOT_EXIST
)))
569 EXPORT_SYMBOL_GPL(wmi_remove_notify_handler
);
572 * wmi_get_event_data - Get WMI data associated with an event
574 * @event: Event to find
575 * @out: Buffer to hold event data. out->pointer should be freed with kfree()
577 * Returns extra data associated with an event in WMI.
579 acpi_status
wmi_get_event_data(u32 event
, struct acpi_buffer
*out
)
581 struct acpi_object_list input
;
582 union acpi_object params
[1];
583 struct guid_block
*gblock
;
584 struct wmi_block
*wblock
;
588 input
.pointer
= params
;
589 params
[0].type
= ACPI_TYPE_INTEGER
;
590 params
[0].integer
.value
= event
;
592 list_for_each(p
, &wmi_block_list
) {
593 wblock
= list_entry(p
, struct wmi_block
, list
);
594 gblock
= &wblock
->gblock
;
596 if ((gblock
->flags
& ACPI_WMI_EVENT
) &&
597 (gblock
->notify_id
== event
))
598 return acpi_evaluate_object(wblock
->acpi_device
->handle
,
599 "_WED", &input
, out
);
604 EXPORT_SYMBOL_GPL(wmi_get_event_data
);
607 * wmi_has_guid - Check if a GUID is available
608 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
610 * Check if a given GUID is defined by _WDG
612 bool wmi_has_guid(const char *guid_string
)
614 return find_guid(guid_string
, NULL
);
616 EXPORT_SYMBOL_GPL(wmi_has_guid
);
618 static struct wmi_block
*dev_to_wblock(struct device
*dev
)
620 return container_of(dev
, struct wmi_block
, dev
.dev
);
623 static struct wmi_device
*dev_to_wdev(struct device
*dev
)
625 return container_of(dev
, struct wmi_device
, dev
);
631 static ssize_t
modalias_show(struct device
*dev
, struct device_attribute
*attr
,
634 struct wmi_block
*wblock
= dev_to_wblock(dev
);
636 return sprintf(buf
, "wmi:%pUL\n", wblock
->gblock
.guid
);
638 static DEVICE_ATTR_RO(modalias
);
640 static ssize_t
guid_show(struct device
*dev
, struct device_attribute
*attr
,
643 struct wmi_block
*wblock
= dev_to_wblock(dev
);
645 return sprintf(buf
, "%pUL\n", wblock
->gblock
.guid
);
647 static DEVICE_ATTR_RO(guid
);
649 static ssize_t
instance_count_show(struct device
*dev
,
650 struct device_attribute
*attr
, char *buf
)
652 struct wmi_block
*wblock
= dev_to_wblock(dev
);
654 return sprintf(buf
, "%d\n", (int)wblock
->gblock
.instance_count
);
656 static DEVICE_ATTR_RO(instance_count
);
658 static ssize_t
expensive_show(struct device
*dev
,
659 struct device_attribute
*attr
, char *buf
)
661 struct wmi_block
*wblock
= dev_to_wblock(dev
);
663 return sprintf(buf
, "%d\n",
664 (wblock
->gblock
.flags
& ACPI_WMI_EXPENSIVE
) != 0);
666 static DEVICE_ATTR_RO(expensive
);
668 static struct attribute
*wmi_attrs
[] = {
669 &dev_attr_modalias
.attr
,
671 &dev_attr_instance_count
.attr
,
672 &dev_attr_expensive
.attr
,
675 ATTRIBUTE_GROUPS(wmi
);
677 static ssize_t
notify_id_show(struct device
*dev
, struct device_attribute
*attr
,
680 struct wmi_block
*wblock
= dev_to_wblock(dev
);
682 return sprintf(buf
, "%02X\n", (unsigned int)wblock
->gblock
.notify_id
);
684 static DEVICE_ATTR_RO(notify_id
);
686 static struct attribute
*wmi_event_attrs
[] = {
687 &dev_attr_notify_id
.attr
,
690 ATTRIBUTE_GROUPS(wmi_event
);
692 static ssize_t
object_id_show(struct device
*dev
, struct device_attribute
*attr
,
695 struct wmi_block
*wblock
= dev_to_wblock(dev
);
697 return sprintf(buf
, "%c%c\n", wblock
->gblock
.object_id
[0],
698 wblock
->gblock
.object_id
[1]);
700 static DEVICE_ATTR_RO(object_id
);
702 static ssize_t
setable_show(struct device
*dev
, struct device_attribute
*attr
,
705 struct wmi_device
*wdev
= dev_to_wdev(dev
);
707 return sprintf(buf
, "%d\n", (int)wdev
->setable
);
709 static DEVICE_ATTR_RO(setable
);
711 static struct attribute
*wmi_data_attrs
[] = {
712 &dev_attr_object_id
.attr
,
713 &dev_attr_setable
.attr
,
716 ATTRIBUTE_GROUPS(wmi_data
);
718 static struct attribute
*wmi_method_attrs
[] = {
719 &dev_attr_object_id
.attr
,
722 ATTRIBUTE_GROUPS(wmi_method
);
724 static int wmi_dev_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
726 struct wmi_block
*wblock
= dev_to_wblock(dev
);
728 if (add_uevent_var(env
, "MODALIAS=wmi:%pUL", wblock
->gblock
.guid
))
731 if (add_uevent_var(env
, "WMI_GUID=%pUL", wblock
->gblock
.guid
))
737 static void wmi_dev_release(struct device
*dev
)
739 struct wmi_block
*wblock
= dev_to_wblock(dev
);
744 static int wmi_dev_match(struct device
*dev
, struct device_driver
*driver
)
746 struct wmi_driver
*wmi_driver
=
747 container_of(driver
, struct wmi_driver
, driver
);
748 struct wmi_block
*wblock
= dev_to_wblock(dev
);
749 const struct wmi_device_id
*id
= wmi_driver
->id_table
;
751 while (id
->guid_string
) {
754 if (WARN_ON(uuid_le_to_bin(id
->guid_string
, &driver_guid
)))
756 if (!memcmp(&driver_guid
, wblock
->gblock
.guid
, 16))
765 static int wmi_dev_probe(struct device
*dev
)
767 struct wmi_block
*wblock
= dev_to_wblock(dev
);
768 struct wmi_driver
*wdriver
=
769 container_of(dev
->driver
, struct wmi_driver
, driver
);
772 if (ACPI_FAILURE(wmi_method_enable(wblock
, 1)))
773 dev_warn(dev
, "failed to enable device -- probing anyway\n");
775 if (wdriver
->probe
) {
776 ret
= wdriver
->probe(dev_to_wdev(dev
));
777 if (ret
!= 0 && ACPI_FAILURE(wmi_method_enable(wblock
, 0)))
778 dev_warn(dev
, "failed to disable device\n");
784 static int wmi_dev_remove(struct device
*dev
)
786 struct wmi_block
*wblock
= dev_to_wblock(dev
);
787 struct wmi_driver
*wdriver
=
788 container_of(dev
->driver
, struct wmi_driver
, driver
);
792 ret
= wdriver
->remove(dev_to_wdev(dev
));
794 if (ACPI_FAILURE(wmi_method_enable(wblock
, 0)))
795 dev_warn(dev
, "failed to disable device\n");
800 static struct class wmi_bus_class
= {
804 static struct bus_type wmi_bus_type
= {
806 .dev_groups
= wmi_groups
,
807 .match
= wmi_dev_match
,
808 .uevent
= wmi_dev_uevent
,
809 .probe
= wmi_dev_probe
,
810 .remove
= wmi_dev_remove
,
813 static struct device_type wmi_type_event
= {
815 .groups
= wmi_event_groups
,
816 .release
= wmi_dev_release
,
819 static struct device_type wmi_type_method
= {
821 .groups
= wmi_method_groups
,
822 .release
= wmi_dev_release
,
825 static struct device_type wmi_type_data
= {
827 .groups
= wmi_data_groups
,
828 .release
= wmi_dev_release
,
831 static int wmi_create_device(struct device
*wmi_bus_dev
,
832 const struct guid_block
*gblock
,
833 struct wmi_block
*wblock
,
834 struct acpi_device
*device
)
836 struct acpi_device_info
*info
;
840 if (gblock
->flags
& ACPI_WMI_EVENT
) {
841 wblock
->dev
.dev
.type
= &wmi_type_event
;
845 if (gblock
->flags
& ACPI_WMI_METHOD
) {
846 wblock
->dev
.dev
.type
= &wmi_type_method
;
851 * Data Block Query Control Method (WQxx by convention) is
852 * required per the WMI documentation. If it is not present,
853 * we ignore this data block.
855 strcpy(method
, "WQ");
856 strncat(method
, wblock
->gblock
.object_id
, 2);
857 result
= get_subobj_info(device
->handle
, method
, &info
);
860 dev_warn(wmi_bus_dev
,
861 "%s data block query control method not found",
866 wblock
->dev
.dev
.type
= &wmi_type_data
;
869 * The Microsoft documentation specifically states:
871 * Data blocks registered with only a single instance
872 * can ignore the parameter.
874 * ACPICA will get mad at us if we call the method with the wrong number
875 * of arguments, so check what our method expects. (On some Dell
876 * laptops, WQxx may not be a method at all.)
878 if (info
->type
!= ACPI_TYPE_METHOD
|| info
->param_count
== 0)
879 wblock
->read_takes_no_args
= true;
883 strcpy(method
, "WS");
884 strncat(method
, wblock
->gblock
.object_id
, 2);
885 result
= get_subobj_info(device
->handle
, method
, NULL
);
888 wblock
->dev
.setable
= true;
891 wblock
->dev
.dev
.bus
= &wmi_bus_type
;
892 wblock
->dev
.dev
.parent
= wmi_bus_dev
;
894 dev_set_name(&wblock
->dev
.dev
, "%pUL", gblock
->guid
);
896 device_initialize(&wblock
->dev
.dev
);
901 static void wmi_free_devices(struct acpi_device
*device
)
903 struct wmi_block
*wblock
, *next
;
905 /* Delete devices for all the GUIDs */
906 list_for_each_entry_safe(wblock
, next
, &wmi_block_list
, list
) {
907 if (wblock
->acpi_device
== device
) {
908 list_del(&wblock
->list
);
909 device_unregister(&wblock
->dev
.dev
);
914 static bool guid_already_parsed(struct acpi_device
*device
,
917 struct wmi_block
*wblock
;
919 list_for_each_entry(wblock
, &wmi_block_list
, list
) {
920 if (memcmp(wblock
->gblock
.guid
, guid
, 16) == 0) {
922 * Because we historically didn't track the relationship
923 * between GUIDs and ACPI nodes, we don't know whether
924 * we need to suppress GUIDs that are unique on a
925 * given node but duplicated across nodes.
927 dev_warn(&device
->dev
, "duplicate WMI GUID %pUL (first instance was on %s)\n",
928 guid
, dev_name(&wblock
->acpi_device
->dev
));
937 * Parse the _WDG method for the GUID data blocks
939 static int parse_wdg(struct device
*wmi_bus_dev
, struct acpi_device
*device
)
941 struct acpi_buffer out
= {ACPI_ALLOCATE_BUFFER
, NULL
};
942 const struct guid_block
*gblock
;
943 struct wmi_block
*wblock
, *next
;
944 union acpi_object
*obj
;
949 status
= acpi_evaluate_object(device
->handle
, "_WDG", NULL
, &out
);
950 if (ACPI_FAILURE(status
))
953 obj
= (union acpi_object
*) out
.pointer
;
957 if (obj
->type
!= ACPI_TYPE_BUFFER
) {
959 goto out_free_pointer
;
962 gblock
= (const struct guid_block
*)obj
->buffer
.pointer
;
963 total
= obj
->buffer
.length
/ sizeof(struct guid_block
);
965 for (i
= 0; i
< total
; i
++) {
967 wmi_dump_wdg(&gblock
[i
]);
970 * Some WMI devices, like those for nVidia hooks, have a
971 * duplicate GUID. It's not clear what we should do in this
972 * case yet, so for now, we'll just ignore the duplicate
973 * for device creation.
975 if (guid_already_parsed(device
, gblock
[i
].guid
))
978 wblock
= kzalloc(sizeof(struct wmi_block
), GFP_KERNEL
);
984 wblock
->acpi_device
= device
;
985 wblock
->gblock
= gblock
[i
];
987 retval
= wmi_create_device(wmi_bus_dev
, &gblock
[i
], wblock
, device
);
993 list_add_tail(&wblock
->list
, &wmi_block_list
);
996 wblock
->handler
= wmi_notify_debug
;
997 wmi_method_enable(wblock
, 1);
1002 * Now that all of the devices are created, add them to the
1003 * device tree and probe subdrivers.
1005 list_for_each_entry_safe(wblock
, next
, &wmi_block_list
, list
) {
1006 if (wblock
->acpi_device
!= device
)
1009 retval
= device_add(&wblock
->dev
.dev
);
1011 dev_err(wmi_bus_dev
, "failed to register %pULL\n",
1012 wblock
->gblock
.guid
);
1014 wmi_method_enable(wblock
, 0);
1015 list_del(&wblock
->list
);
1016 put_device(&wblock
->dev
.dev
);
1026 * WMI can have EmbeddedControl access regions. In which case, we just want to
1027 * hand these off to the EC driver.
1030 acpi_wmi_ec_space_handler(u32 function
, acpi_physical_address address
,
1031 u32 bits
, u64
*value
,
1032 void *handler_context
, void *region_context
)
1034 int result
= 0, i
= 0;
1037 if ((address
> 0xFF) || !value
)
1038 return AE_BAD_PARAMETER
;
1040 if (function
!= ACPI_READ
&& function
!= ACPI_WRITE
)
1041 return AE_BAD_PARAMETER
;
1044 return AE_BAD_PARAMETER
;
1046 if (function
== ACPI_READ
) {
1047 result
= ec_read(address
, &temp
);
1048 (*value
) |= ((u64
)temp
) << i
;
1050 temp
= 0xff & ((*value
) >> i
);
1051 result
= ec_write(address
, temp
);
1056 return AE_BAD_PARAMETER
;
1059 return AE_NOT_FOUND
;
1069 static void acpi_wmi_notify_handler(acpi_handle handle
, u32 event
,
1072 struct guid_block
*block
;
1073 struct wmi_block
*wblock
;
1074 struct list_head
*p
;
1075 bool found_it
= false;
1077 list_for_each(p
, &wmi_block_list
) {
1078 wblock
= list_entry(p
, struct wmi_block
, list
);
1079 block
= &wblock
->gblock
;
1081 if (wblock
->acpi_device
->handle
== handle
&&
1082 (block
->flags
& ACPI_WMI_EVENT
) &&
1083 (block
->notify_id
== event
))
1093 /* If a driver is bound, then notify the driver. */
1094 if (wblock
->dev
.dev
.driver
) {
1095 struct wmi_driver
*driver
;
1096 struct acpi_object_list input
;
1097 union acpi_object params
[1];
1098 struct acpi_buffer evdata
= { ACPI_ALLOCATE_BUFFER
, NULL
};
1101 driver
= container_of(wblock
->dev
.dev
.driver
,
1102 struct wmi_driver
, driver
);
1105 input
.pointer
= params
;
1106 params
[0].type
= ACPI_TYPE_INTEGER
;
1107 params
[0].integer
.value
= event
;
1109 status
= acpi_evaluate_object(wblock
->acpi_device
->handle
,
1110 "_WED", &input
, &evdata
);
1111 if (ACPI_FAILURE(status
)) {
1112 dev_warn(&wblock
->dev
.dev
,
1113 "failed to get event data\n");
1118 driver
->notify(&wblock
->dev
,
1119 (union acpi_object
*)evdata
.pointer
);
1121 kfree(evdata
.pointer
);
1122 } else if (wblock
->handler
) {
1123 /* Legacy handler */
1124 wblock
->handler(event
, wblock
->handler_data
);
1128 pr_info("DEBUG Event GUID: %pUL\n",
1129 wblock
->gblock
.guid
);
1132 acpi_bus_generate_netlink_event(
1133 wblock
->acpi_device
->pnp
.device_class
,
1134 dev_name(&wblock
->dev
.dev
),
1139 static int acpi_wmi_remove(struct platform_device
*device
)
1141 struct acpi_device
*acpi_device
= ACPI_COMPANION(&device
->dev
);
1143 acpi_remove_notify_handler(acpi_device
->handle
, ACPI_DEVICE_NOTIFY
,
1144 acpi_wmi_notify_handler
);
1145 acpi_remove_address_space_handler(acpi_device
->handle
,
1146 ACPI_ADR_SPACE_EC
, &acpi_wmi_ec_space_handler
);
1147 wmi_free_devices(acpi_device
);
1148 device_unregister((struct device
*)dev_get_drvdata(&device
->dev
));
1153 static int acpi_wmi_probe(struct platform_device
*device
)
1155 struct acpi_device
*acpi_device
;
1156 struct device
*wmi_bus_dev
;
1160 acpi_device
= ACPI_COMPANION(&device
->dev
);
1162 dev_err(&device
->dev
, "ACPI companion is missing\n");
1166 status
= acpi_install_address_space_handler(acpi_device
->handle
,
1168 &acpi_wmi_ec_space_handler
,
1170 if (ACPI_FAILURE(status
)) {
1171 dev_err(&device
->dev
, "Error installing EC region handler\n");
1175 status
= acpi_install_notify_handler(acpi_device
->handle
,
1177 acpi_wmi_notify_handler
,
1179 if (ACPI_FAILURE(status
)) {
1180 dev_err(&device
->dev
, "Error installing notify handler\n");
1182 goto err_remove_ec_handler
;
1185 wmi_bus_dev
= device_create(&wmi_bus_class
, &device
->dev
, MKDEV(0, 0),
1186 NULL
, "wmi_bus-%s", dev_name(&device
->dev
));
1187 if (IS_ERR(wmi_bus_dev
)) {
1188 error
= PTR_ERR(wmi_bus_dev
);
1189 goto err_remove_notify_handler
;
1191 dev_set_drvdata(&device
->dev
, wmi_bus_dev
);
1193 error
= parse_wdg(wmi_bus_dev
, acpi_device
);
1195 pr_err("Failed to parse WDG method\n");
1196 goto err_remove_busdev
;
1202 device_unregister(wmi_bus_dev
);
1204 err_remove_notify_handler
:
1205 acpi_remove_notify_handler(acpi_device
->handle
, ACPI_DEVICE_NOTIFY
,
1206 acpi_wmi_notify_handler
);
1208 err_remove_ec_handler
:
1209 acpi_remove_address_space_handler(acpi_device
->handle
,
1211 &acpi_wmi_ec_space_handler
);
1216 int __must_check
__wmi_driver_register(struct wmi_driver
*driver
,
1217 struct module
*owner
)
1219 driver
->driver
.owner
= owner
;
1220 driver
->driver
.bus
= &wmi_bus_type
;
1222 return driver_register(&driver
->driver
);
1224 EXPORT_SYMBOL(__wmi_driver_register
);
1226 void wmi_driver_unregister(struct wmi_driver
*driver
)
1228 driver_unregister(&driver
->driver
);
1230 EXPORT_SYMBOL(wmi_driver_unregister
);
1232 static int __init
acpi_wmi_init(void)
1239 error
= class_register(&wmi_bus_class
);
1243 error
= bus_register(&wmi_bus_type
);
1245 goto err_unreg_class
;
1247 error
= platform_driver_register(&acpi_wmi_driver
);
1249 pr_err("Error loading mapper\n");
1256 bus_unregister(&wmi_bus_type
);
1259 class_unregister(&wmi_bus_class
);
1264 static void __exit
acpi_wmi_exit(void)
1266 platform_driver_unregister(&acpi_wmi_driver
);
1267 class_unregister(&wmi_bus_class
);
1268 bus_unregister(&wmi_bus_type
);
1271 subsys_initcall(acpi_wmi_init
);
1272 module_exit(acpi_wmi_exit
);