1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * ACPI-WMI mapping driver 4 * 5 * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk> 6 * 7 * GUID parsing code from ldm.c is: 8 * Copyright (C) 2001,2002 Richard Russon <ldm@flatcap.org> 9 * Copyright (c) 2001-2007 Anton Altaparmakov 10 * Copyright (C) 2001,2002 Jakob Kemi <jakob.kemi@telia.com> 11 * 12 * WMI bus infrastructure by Andrew Lutomirski and Darren Hart: 13 * Copyright (C) 2015 Andrew Lutomirski 14 * Copyright (C) 2017 VMware, Inc. All Rights Reserved. 15 */ 16 17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 19 #include <linux/acpi.h> 20 #include <linux/device.h> 21 #include <linux/init.h> 22 #include <linux/kernel.h> 23 #include <linux/list.h> 24 #include <linux/miscdevice.h> 25 #include <linux/module.h> 26 #include <linux/platform_device.h> 27 #include <linux/slab.h> 28 #include <linux/types.h> 29 #include <linux/uaccess.h> 30 #include <linux/uuid.h> 31 #include <linux/wmi.h> 32 #include <linux/fs.h> 33 #include <uapi/linux/wmi.h> 34 35 ACPI_MODULE_NAME("wmi"); 36 MODULE_AUTHOR("Carlos Corbacho"); 37 MODULE_DESCRIPTION("ACPI-WMI Mapping Driver"); 38 MODULE_LICENSE("GPL"); 39 40 static LIST_HEAD(wmi_block_list); 41 42 struct guid_block { 43 char guid[16]; 44 union { 45 char object_id[2]; 46 struct { 47 unsigned char notify_id; 48 unsigned char reserved; 49 }; 50 }; 51 u8 instance_count; 52 u8 flags; 53 }; 54 55 struct wmi_block { 56 struct wmi_device dev; 57 struct list_head list; 58 struct guid_block gblock; 59 struct miscdevice char_dev; 60 struct mutex char_mutex; 61 struct acpi_device *acpi_device; 62 wmi_notify_handler handler; 63 void *handler_data; 64 u64 req_buf_size; 65 66 bool read_takes_no_args; 67 }; 68 69 70 /* 71 * If the GUID data block is marked as expensive, we must enable and 72 * explicitily disable data collection. 73 */ 74 #define ACPI_WMI_EXPENSIVE 0x1 75 #define ACPI_WMI_METHOD 0x2 /* GUID is a method */ 76 #define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */ 77 #define ACPI_WMI_EVENT 0x8 /* GUID is an event */ 78 79 static bool debug_event; 80 module_param(debug_event, bool, 0444); 81 MODULE_PARM_DESC(debug_event, 82 "Log WMI Events [0/1]"); 83 84 static bool debug_dump_wdg; 85 module_param(debug_dump_wdg, bool, 0444); 86 MODULE_PARM_DESC(debug_dump_wdg, 87 "Dump available WMI interfaces [0/1]"); 88 89 static int acpi_wmi_remove(struct platform_device *device); 90 static int acpi_wmi_probe(struct platform_device *device); 91 92 static const struct acpi_device_id wmi_device_ids[] = { 93 {"PNP0C14", 0}, 94 {"pnp0c14", 0}, 95 {"", 0}, 96 }; 97 MODULE_DEVICE_TABLE(acpi, wmi_device_ids); 98 99 static struct platform_driver acpi_wmi_driver = { 100 .driver = { 101 .name = "acpi-wmi", 102 .acpi_match_table = wmi_device_ids, 103 }, 104 .probe = acpi_wmi_probe, 105 .remove = acpi_wmi_remove, 106 }; 107 108 /* 109 * GUID parsing functions 110 */ 111 112 static bool find_guid(const char *guid_string, struct wmi_block **out) 113 { 114 uuid_le guid_input; 115 struct wmi_block *wblock; 116 struct guid_block *block; 117 118 if (uuid_le_to_bin(guid_string, &guid_input)) 119 return false; 120 121 list_for_each_entry(wblock, &wmi_block_list, list) { 122 block = &wblock->gblock; 123 124 if (memcmp(block->guid, &guid_input, 16) == 0) { 125 if (out) 126 *out = wblock; 127 return true; 128 } 129 } 130 return false; 131 } 132 133 static const void *find_guid_context(struct wmi_block *wblock, 134 struct wmi_driver *wdriver) 135 { 136 const struct wmi_device_id *id; 137 uuid_le guid_input; 138 139 if (wblock == NULL || wdriver == NULL) 140 return NULL; 141 if (wdriver->id_table == NULL) 142 return NULL; 143 144 id = wdriver->id_table; 145 while (*id->guid_string) { 146 if (uuid_le_to_bin(id->guid_string, &guid_input)) 147 continue; 148 if (!memcmp(wblock->gblock.guid, &guid_input, 16)) 149 return id->context; 150 id++; 151 } 152 return NULL; 153 } 154 155 static int get_subobj_info(acpi_handle handle, const char *pathname, 156 struct acpi_device_info **info) 157 { 158 struct acpi_device_info *dummy_info, **info_ptr; 159 acpi_handle subobj_handle; 160 acpi_status status; 161 162 status = acpi_get_handle(handle, (char *)pathname, &subobj_handle); 163 if (status == AE_NOT_FOUND) 164 return -ENOENT; 165 else if (ACPI_FAILURE(status)) 166 return -EIO; 167 168 info_ptr = info ? info : &dummy_info; 169 status = acpi_get_object_info(subobj_handle, info_ptr); 170 if (ACPI_FAILURE(status)) 171 return -EIO; 172 173 if (!info) 174 kfree(dummy_info); 175 176 return 0; 177 } 178 179 static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) 180 { 181 struct guid_block *block = NULL; 182 char method[5]; 183 acpi_status status; 184 acpi_handle handle; 185 186 block = &wblock->gblock; 187 handle = wblock->acpi_device->handle; 188 189 snprintf(method, 5, "WE%02X", block->notify_id); 190 status = acpi_execute_simple_method(handle, method, enable); 191 192 if (status != AE_OK && status != AE_NOT_FOUND) 193 return status; 194 else 195 return AE_OK; 196 } 197 198 /* 199 * Exported WMI functions 200 */ 201 202 /** 203 * set_required_buffer_size - Sets the buffer size needed for performing IOCTL 204 * @wdev: A wmi bus device from a driver 205 * @instance: Instance index 206 * 207 * Allocates memory needed for buffer, stores the buffer size in that memory 208 */ 209 int set_required_buffer_size(struct wmi_device *wdev, u64 length) 210 { 211 struct wmi_block *wblock; 212 213 wblock = container_of(wdev, struct wmi_block, dev); 214 wblock->req_buf_size = length; 215 216 return 0; 217 } 218 EXPORT_SYMBOL_GPL(set_required_buffer_size); 219 220 /** 221 * wmi_evaluate_method - Evaluate a WMI method 222 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba 223 * @instance: Instance index 224 * @method_id: Method ID to call 225 * &in: Buffer containing input for the method call 226 * &out: Empty buffer to return the method results 227 * 228 * Call an ACPI-WMI method 229 */ 230 acpi_status wmi_evaluate_method(const char *guid_string, u8 instance, 231 u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) 232 { 233 struct wmi_block *wblock = NULL; 234 235 if (!find_guid(guid_string, &wblock)) 236 return AE_ERROR; 237 return wmidev_evaluate_method(&wblock->dev, instance, method_id, 238 in, out); 239 } 240 EXPORT_SYMBOL_GPL(wmi_evaluate_method); 241 242 /** 243 * wmidev_evaluate_method - Evaluate a WMI method 244 * @wdev: A wmi bus device from a driver 245 * @instance: Instance index 246 * @method_id: Method ID to call 247 * &in: Buffer containing input for the method call 248 * &out: Empty buffer to return the method results 249 * 250 * Call an ACPI-WMI method 251 */ 252 acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, 253 u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) 254 { 255 struct guid_block *block = NULL; 256 struct wmi_block *wblock = NULL; 257 acpi_handle handle; 258 acpi_status status; 259 struct acpi_object_list input; 260 union acpi_object params[3]; 261 char method[5] = "WM"; 262 263 wblock = container_of(wdev, struct wmi_block, dev); 264 block = &wblock->gblock; 265 handle = wblock->acpi_device->handle; 266 267 if (!(block->flags & ACPI_WMI_METHOD)) 268 return AE_BAD_DATA; 269 270 if (block->instance_count <= instance) 271 return AE_BAD_PARAMETER; 272 273 input.count = 2; 274 input.pointer = params; 275 params[0].type = ACPI_TYPE_INTEGER; 276 params[0].integer.value = instance; 277 params[1].type = ACPI_TYPE_INTEGER; 278 params[1].integer.value = method_id; 279 280 if (in) { 281 input.count = 3; 282 283 if (block->flags & ACPI_WMI_STRING) { 284 params[2].type = ACPI_TYPE_STRING; 285 } else { 286 params[2].type = ACPI_TYPE_BUFFER; 287 } 288 params[2].buffer.length = in->length; 289 params[2].buffer.pointer = in->pointer; 290 } 291 292 strncat(method, block->object_id, 2); 293 294 status = acpi_evaluate_object(handle, method, &input, out); 295 296 return status; 297 } 298 EXPORT_SYMBOL_GPL(wmidev_evaluate_method); 299 300 static acpi_status __query_block(struct wmi_block *wblock, u8 instance, 301 struct acpi_buffer *out) 302 { 303 struct guid_block *block = NULL; 304 acpi_handle handle; 305 acpi_status status, wc_status = AE_ERROR; 306 struct acpi_object_list input; 307 union acpi_object wq_params[1]; 308 char method[5]; 309 char wc_method[5] = "WC"; 310 311 if (!out) 312 return AE_BAD_PARAMETER; 313 314 block = &wblock->gblock; 315 handle = wblock->acpi_device->handle; 316 317 if (block->instance_count <= instance) 318 return AE_BAD_PARAMETER; 319 320 /* Check GUID is a data block */ 321 if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) 322 return AE_ERROR; 323 324 input.count = 1; 325 input.pointer = wq_params; 326 wq_params[0].type = ACPI_TYPE_INTEGER; 327 wq_params[0].integer.value = instance; 328 329 if (instance == 0 && wblock->read_takes_no_args) 330 input.count = 0; 331 332 /* 333 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to 334 * enable collection. 335 */ 336 if (block->flags & ACPI_WMI_EXPENSIVE) { 337 strncat(wc_method, block->object_id, 2); 338 339 /* 340 * Some GUIDs break the specification by declaring themselves 341 * expensive, but have no corresponding WCxx method. So we 342 * should not fail if this happens. 343 */ 344 wc_status = acpi_execute_simple_method(handle, wc_method, 1); 345 } 346 347 strcpy(method, "WQ"); 348 strncat(method, block->object_id, 2); 349 350 status = acpi_evaluate_object(handle, method, &input, out); 351 352 /* 353 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if 354 * the WQxx method failed - we should disable collection anyway. 355 */ 356 if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { 357 status = acpi_execute_simple_method(handle, wc_method, 0); 358 } 359 360 return status; 361 } 362 363 /** 364 * wmi_query_block - Return contents of a WMI block (deprecated) 365 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba 366 * @instance: Instance index 367 * &out: Empty buffer to return the contents of the data block to 368 * 369 * Return the contents of an ACPI-WMI data block to a buffer 370 */ 371 acpi_status wmi_query_block(const char *guid_string, u8 instance, 372 struct acpi_buffer *out) 373 { 374 struct wmi_block *wblock; 375 376 if (!guid_string) 377 return AE_BAD_PARAMETER; 378 379 if (!find_guid(guid_string, &wblock)) 380 return AE_ERROR; 381 382 return __query_block(wblock, instance, out); 383 } 384 EXPORT_SYMBOL_GPL(wmi_query_block); 385 386 union acpi_object *wmidev_block_query(struct wmi_device *wdev, u8 instance) 387 { 388 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 389 struct wmi_block *wblock = container_of(wdev, struct wmi_block, dev); 390 391 if (ACPI_FAILURE(__query_block(wblock, instance, &out))) 392 return NULL; 393 394 return (union acpi_object *)out.pointer; 395 } 396 EXPORT_SYMBOL_GPL(wmidev_block_query); 397 398 /** 399 * wmi_set_block - Write to a WMI block 400 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba 401 * @instance: Instance index 402 * &in: Buffer containing new values for the data block 403 * 404 * Write the contents of the input buffer to an ACPI-WMI data block 405 */ 406 acpi_status wmi_set_block(const char *guid_string, u8 instance, 407 const struct acpi_buffer *in) 408 { 409 struct guid_block *block = NULL; 410 struct wmi_block *wblock = NULL; 411 acpi_handle handle; 412 struct acpi_object_list input; 413 union acpi_object params[2]; 414 char method[5] = "WS"; 415 416 if (!guid_string || !in) 417 return AE_BAD_DATA; 418 419 if (!find_guid(guid_string, &wblock)) 420 return AE_ERROR; 421 422 block = &wblock->gblock; 423 handle = wblock->acpi_device->handle; 424 425 if (block->instance_count <= instance) 426 return AE_BAD_PARAMETER; 427 428 /* Check GUID is a data block */ 429 if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) 430 return AE_ERROR; 431 432 input.count = 2; 433 input.pointer = params; 434 params[0].type = ACPI_TYPE_INTEGER; 435 params[0].integer.value = instance; 436 437 if (block->flags & ACPI_WMI_STRING) { 438 params[1].type = ACPI_TYPE_STRING; 439 } else { 440 params[1].type = ACPI_TYPE_BUFFER; 441 } 442 params[1].buffer.length = in->length; 443 params[1].buffer.pointer = in->pointer; 444 445 strncat(method, block->object_id, 2); 446 447 return acpi_evaluate_object(handle, method, &input, NULL); 448 } 449 EXPORT_SYMBOL_GPL(wmi_set_block); 450 451 static void wmi_dump_wdg(const struct guid_block *g) 452 { 453 pr_info("%pUL:\n", g->guid); 454 if (g->flags & ACPI_WMI_EVENT) 455 pr_info("\tnotify_id: 0x%02X\n", g->notify_id); 456 else 457 pr_info("\tobject_id: %2pE\n", g->object_id); 458 pr_info("\tinstance_count: %d\n", g->instance_count); 459 pr_info("\tflags: %#x", g->flags); 460 if (g->flags) { 461 if (g->flags & ACPI_WMI_EXPENSIVE) 462 pr_cont(" ACPI_WMI_EXPENSIVE"); 463 if (g->flags & ACPI_WMI_METHOD) 464 pr_cont(" ACPI_WMI_METHOD"); 465 if (g->flags & ACPI_WMI_STRING) 466 pr_cont(" ACPI_WMI_STRING"); 467 if (g->flags & ACPI_WMI_EVENT) 468 pr_cont(" ACPI_WMI_EVENT"); 469 } 470 pr_cont("\n"); 471 472 } 473 474 static void wmi_notify_debug(u32 value, void *context) 475 { 476 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 477 union acpi_object *obj; 478 acpi_status status; 479 480 status = wmi_get_event_data(value, &response); 481 if (status != AE_OK) { 482 pr_info("bad event status 0x%x\n", status); 483 return; 484 } 485 486 obj = (union acpi_object *)response.pointer; 487 488 if (!obj) 489 return; 490 491 pr_info("DEBUG Event "); 492 switch(obj->type) { 493 case ACPI_TYPE_BUFFER: 494 pr_cont("BUFFER_TYPE - length %d\n", obj->buffer.length); 495 break; 496 case ACPI_TYPE_STRING: 497 pr_cont("STRING_TYPE - %s\n", obj->string.pointer); 498 break; 499 case ACPI_TYPE_INTEGER: 500 pr_cont("INTEGER_TYPE - %llu\n", obj->integer.value); 501 break; 502 case ACPI_TYPE_PACKAGE: 503 pr_cont("PACKAGE_TYPE - %d elements\n", obj->package.count); 504 break; 505 default: 506 pr_cont("object type 0x%X\n", obj->type); 507 } 508 kfree(obj); 509 } 510 511 /** 512 * wmi_install_notify_handler - Register handler for WMI events 513 * @handler: Function to handle notifications 514 * @data: Data to be returned to handler when event is fired 515 * 516 * Register a handler for events sent to the ACPI-WMI mapper device. 517 */ 518 acpi_status wmi_install_notify_handler(const char *guid, 519 wmi_notify_handler handler, void *data) 520 { 521 struct wmi_block *block; 522 acpi_status status = AE_NOT_EXIST; 523 uuid_le guid_input; 524 525 if (!guid || !handler) 526 return AE_BAD_PARAMETER; 527 528 if (uuid_le_to_bin(guid, &guid_input)) 529 return AE_BAD_PARAMETER; 530 531 list_for_each_entry(block, &wmi_block_list, list) { 532 acpi_status wmi_status; 533 534 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { 535 if (block->handler && 536 block->handler != wmi_notify_debug) 537 return AE_ALREADY_ACQUIRED; 538 539 block->handler = handler; 540 block->handler_data = data; 541 542 wmi_status = wmi_method_enable(block, 1); 543 if ((wmi_status != AE_OK) || 544 ((wmi_status == AE_OK) && (status == AE_NOT_EXIST))) 545 status = wmi_status; 546 } 547 } 548 549 return status; 550 } 551 EXPORT_SYMBOL_GPL(wmi_install_notify_handler); 552 553 /** 554 * wmi_uninstall_notify_handler - Unregister handler for WMI events 555 * 556 * Unregister handler for events sent to the ACPI-WMI mapper device. 557 */ 558 acpi_status wmi_remove_notify_handler(const char *guid) 559 { 560 struct wmi_block *block; 561 acpi_status status = AE_NOT_EXIST; 562 uuid_le guid_input; 563 564 if (!guid) 565 return AE_BAD_PARAMETER; 566 567 if (uuid_le_to_bin(guid, &guid_input)) 568 return AE_BAD_PARAMETER; 569 570 list_for_each_entry(block, &wmi_block_list, list) { 571 acpi_status wmi_status; 572 573 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { 574 if (!block->handler || 575 block->handler == wmi_notify_debug) 576 return AE_NULL_ENTRY; 577 578 if (debug_event) { 579 block->handler = wmi_notify_debug; 580 status = AE_OK; 581 } else { 582 wmi_status = wmi_method_enable(block, 0); 583 block->handler = NULL; 584 block->handler_data = NULL; 585 if ((wmi_status != AE_OK) || 586 ((wmi_status == AE_OK) && 587 (status == AE_NOT_EXIST))) 588 status = wmi_status; 589 } 590 } 591 } 592 593 return status; 594 } 595 EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); 596 597 /** 598 * wmi_get_event_data - Get WMI data associated with an event 599 * 600 * @event: Event to find 601 * @out: Buffer to hold event data. out->pointer should be freed with kfree() 602 * 603 * Returns extra data associated with an event in WMI. 604 */ 605 acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out) 606 { 607 struct acpi_object_list input; 608 union acpi_object params[1]; 609 struct guid_block *gblock; 610 struct wmi_block *wblock; 611 612 input.count = 1; 613 input.pointer = params; 614 params[0].type = ACPI_TYPE_INTEGER; 615 params[0].integer.value = event; 616 617 list_for_each_entry(wblock, &wmi_block_list, list) { 618 gblock = &wblock->gblock; 619 620 if ((gblock->flags & ACPI_WMI_EVENT) && 621 (gblock->notify_id == event)) 622 return acpi_evaluate_object(wblock->acpi_device->handle, 623 "_WED", &input, out); 624 } 625 626 return AE_NOT_FOUND; 627 } 628 EXPORT_SYMBOL_GPL(wmi_get_event_data); 629 630 /** 631 * wmi_has_guid - Check if a GUID is available 632 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba 633 * 634 * Check if a given GUID is defined by _WDG 635 */ 636 bool wmi_has_guid(const char *guid_string) 637 { 638 return find_guid(guid_string, NULL); 639 } 640 EXPORT_SYMBOL_GPL(wmi_has_guid); 641 642 /** 643 * wmi_get_acpi_device_uid() - Get _UID name of ACPI device that defines GUID 644 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba 645 * 646 * Find the _UID of ACPI device associated with this WMI GUID. 647 * 648 * Return: The ACPI _UID field value or NULL if the WMI GUID was not found 649 */ 650 char *wmi_get_acpi_device_uid(const char *guid_string) 651 { 652 struct wmi_block *wblock = NULL; 653 654 if (!find_guid(guid_string, &wblock)) 655 return NULL; 656 657 return acpi_device_uid(wblock->acpi_device); 658 } 659 EXPORT_SYMBOL_GPL(wmi_get_acpi_device_uid); 660 661 static struct wmi_block *dev_to_wblock(struct device *dev) 662 { 663 return container_of(dev, struct wmi_block, dev.dev); 664 } 665 666 static struct wmi_device *dev_to_wdev(struct device *dev) 667 { 668 return container_of(dev, struct wmi_device, dev); 669 } 670 671 /* 672 * sysfs interface 673 */ 674 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, 675 char *buf) 676 { 677 struct wmi_block *wblock = dev_to_wblock(dev); 678 679 return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid); 680 } 681 static DEVICE_ATTR_RO(modalias); 682 683 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, 684 char *buf) 685 { 686 struct wmi_block *wblock = dev_to_wblock(dev); 687 688 return sprintf(buf, "%pUL\n", wblock->gblock.guid); 689 } 690 static DEVICE_ATTR_RO(guid); 691 692 static ssize_t instance_count_show(struct device *dev, 693 struct device_attribute *attr, char *buf) 694 { 695 struct wmi_block *wblock = dev_to_wblock(dev); 696 697 return sprintf(buf, "%d\n", (int)wblock->gblock.instance_count); 698 } 699 static DEVICE_ATTR_RO(instance_count); 700 701 static ssize_t expensive_show(struct device *dev, 702 struct device_attribute *attr, char *buf) 703 { 704 struct wmi_block *wblock = dev_to_wblock(dev); 705 706 return sprintf(buf, "%d\n", 707 (wblock->gblock.flags & ACPI_WMI_EXPENSIVE) != 0); 708 } 709 static DEVICE_ATTR_RO(expensive); 710 711 static struct attribute *wmi_attrs[] = { 712 &dev_attr_modalias.attr, 713 &dev_attr_guid.attr, 714 &dev_attr_instance_count.attr, 715 &dev_attr_expensive.attr, 716 NULL, 717 }; 718 ATTRIBUTE_GROUPS(wmi); 719 720 static ssize_t notify_id_show(struct device *dev, struct device_attribute *attr, 721 char *buf) 722 { 723 struct wmi_block *wblock = dev_to_wblock(dev); 724 725 return sprintf(buf, "%02X\n", (unsigned int)wblock->gblock.notify_id); 726 } 727 static DEVICE_ATTR_RO(notify_id); 728 729 static struct attribute *wmi_event_attrs[] = { 730 &dev_attr_notify_id.attr, 731 NULL, 732 }; 733 ATTRIBUTE_GROUPS(wmi_event); 734 735 static ssize_t object_id_show(struct device *dev, struct device_attribute *attr, 736 char *buf) 737 { 738 struct wmi_block *wblock = dev_to_wblock(dev); 739 740 return sprintf(buf, "%c%c\n", wblock->gblock.object_id[0], 741 wblock->gblock.object_id[1]); 742 } 743 static DEVICE_ATTR_RO(object_id); 744 745 static ssize_t setable_show(struct device *dev, struct device_attribute *attr, 746 char *buf) 747 { 748 struct wmi_device *wdev = dev_to_wdev(dev); 749 750 return sprintf(buf, "%d\n", (int)wdev->setable); 751 } 752 static DEVICE_ATTR_RO(setable); 753 754 static struct attribute *wmi_data_attrs[] = { 755 &dev_attr_object_id.attr, 756 &dev_attr_setable.attr, 757 NULL, 758 }; 759 ATTRIBUTE_GROUPS(wmi_data); 760 761 static struct attribute *wmi_method_attrs[] = { 762 &dev_attr_object_id.attr, 763 NULL, 764 }; 765 ATTRIBUTE_GROUPS(wmi_method); 766 767 static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) 768 { 769 struct wmi_block *wblock = dev_to_wblock(dev); 770 771 if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid)) 772 return -ENOMEM; 773 774 if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid)) 775 return -ENOMEM; 776 777 return 0; 778 } 779 780 static void wmi_dev_release(struct device *dev) 781 { 782 struct wmi_block *wblock = dev_to_wblock(dev); 783 784 kfree(wblock); 785 } 786 787 static int wmi_dev_match(struct device *dev, struct device_driver *driver) 788 { 789 struct wmi_driver *wmi_driver = 790 container_of(driver, struct wmi_driver, driver); 791 struct wmi_block *wblock = dev_to_wblock(dev); 792 const struct wmi_device_id *id = wmi_driver->id_table; 793 794 if (id == NULL) 795 return 0; 796 797 while (*id->guid_string) { 798 uuid_le driver_guid; 799 800 if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid))) 801 continue; 802 if (!memcmp(&driver_guid, wblock->gblock.guid, 16)) 803 return 1; 804 805 id++; 806 } 807 808 return 0; 809 } 810 static int wmi_char_open(struct inode *inode, struct file *filp) 811 { 812 const char *driver_name = filp->f_path.dentry->d_iname; 813 struct wmi_block *wblock = NULL; 814 struct wmi_block *next = NULL; 815 816 list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { 817 if (!wblock->dev.dev.driver) 818 continue; 819 if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) { 820 filp->private_data = wblock; 821 break; 822 } 823 } 824 825 if (!filp->private_data) 826 return -ENODEV; 827 828 return nonseekable_open(inode, filp); 829 } 830 831 static ssize_t wmi_char_read(struct file *filp, char __user *buffer, 832 size_t length, loff_t *offset) 833 { 834 struct wmi_block *wblock = filp->private_data; 835 836 return simple_read_from_buffer(buffer, length, offset, 837 &wblock->req_buf_size, 838 sizeof(wblock->req_buf_size)); 839 } 840 841 static long wmi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 842 { 843 struct wmi_ioctl_buffer __user *input = 844 (struct wmi_ioctl_buffer __user *) arg; 845 struct wmi_block *wblock = filp->private_data; 846 struct wmi_ioctl_buffer *buf = NULL; 847 struct wmi_driver *wdriver = NULL; 848 int ret; 849 850 if (_IOC_TYPE(cmd) != WMI_IOC) 851 return -ENOTTY; 852 853 /* make sure we're not calling a higher instance than exists*/ 854 if (_IOC_NR(cmd) >= wblock->gblock.instance_count) 855 return -EINVAL; 856 857 mutex_lock(&wblock->char_mutex); 858 buf = wblock->handler_data; 859 if (get_user(buf->length, &input->length)) { 860 dev_dbg(&wblock->dev.dev, "Read length from user failed\n"); 861 ret = -EFAULT; 862 goto out_ioctl; 863 } 864 /* if it's too small, abort */ 865 if (buf->length < wblock->req_buf_size) { 866 dev_err(&wblock->dev.dev, 867 "Buffer %lld too small, need at least %lld\n", 868 buf->length, wblock->req_buf_size); 869 ret = -EINVAL; 870 goto out_ioctl; 871 } 872 /* if it's too big, warn, driver will only use what is needed */ 873 if (buf->length > wblock->req_buf_size) 874 dev_warn(&wblock->dev.dev, 875 "Buffer %lld is bigger than required %lld\n", 876 buf->length, wblock->req_buf_size); 877 878 /* copy the structure from userspace */ 879 if (copy_from_user(buf, input, wblock->req_buf_size)) { 880 dev_dbg(&wblock->dev.dev, "Copy %llu from user failed\n", 881 wblock->req_buf_size); 882 ret = -EFAULT; 883 goto out_ioctl; 884 } 885 886 /* let the driver do any filtering and do the call */ 887 wdriver = container_of(wblock->dev.dev.driver, 888 struct wmi_driver, driver); 889 if (!try_module_get(wdriver->driver.owner)) { 890 ret = -EBUSY; 891 goto out_ioctl; 892 } 893 ret = wdriver->filter_callback(&wblock->dev, cmd, buf); 894 module_put(wdriver->driver.owner); 895 if (ret) 896 goto out_ioctl; 897 898 /* return the result (only up to our internal buffer size) */ 899 if (copy_to_user(input, buf, wblock->req_buf_size)) { 900 dev_dbg(&wblock->dev.dev, "Copy %llu to user failed\n", 901 wblock->req_buf_size); 902 ret = -EFAULT; 903 } 904 905 out_ioctl: 906 mutex_unlock(&wblock->char_mutex); 907 return ret; 908 } 909 910 static const struct file_operations wmi_fops = { 911 .owner = THIS_MODULE, 912 .read = wmi_char_read, 913 .open = wmi_char_open, 914 .unlocked_ioctl = wmi_ioctl, 915 .compat_ioctl = compat_ptr_ioctl, 916 }; 917 918 static int wmi_dev_probe(struct device *dev) 919 { 920 struct wmi_block *wblock = dev_to_wblock(dev); 921 struct wmi_driver *wdriver = 922 container_of(dev->driver, struct wmi_driver, driver); 923 int ret = 0; 924 char *buf; 925 926 if (ACPI_FAILURE(wmi_method_enable(wblock, 1))) 927 dev_warn(dev, "failed to enable device -- probing anyway\n"); 928 929 if (wdriver->probe) { 930 ret = wdriver->probe(dev_to_wdev(dev), 931 find_guid_context(wblock, wdriver)); 932 if (ret != 0) 933 goto probe_failure; 934 } 935 936 /* driver wants a character device made */ 937 if (wdriver->filter_callback) { 938 /* check that required buffer size declared by driver or MOF */ 939 if (!wblock->req_buf_size) { 940 dev_err(&wblock->dev.dev, 941 "Required buffer size not set\n"); 942 ret = -EINVAL; 943 goto probe_failure; 944 } 945 946 wblock->handler_data = kmalloc(wblock->req_buf_size, 947 GFP_KERNEL); 948 if (!wblock->handler_data) { 949 ret = -ENOMEM; 950 goto probe_failure; 951 } 952 953 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); 954 if (!buf) { 955 ret = -ENOMEM; 956 goto probe_string_failure; 957 } 958 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; 959 wblock->char_dev.name = buf; 960 wblock->char_dev.fops = &wmi_fops; 961 wblock->char_dev.mode = 0444; 962 ret = misc_register(&wblock->char_dev); 963 if (ret) { 964 dev_warn(dev, "failed to register char dev: %d\n", ret); 965 ret = -ENOMEM; 966 goto probe_misc_failure; 967 } 968 } 969 970 return 0; 971 972 probe_misc_failure: 973 kfree(buf); 974 probe_string_failure: 975 kfree(wblock->handler_data); 976 probe_failure: 977 if (ACPI_FAILURE(wmi_method_enable(wblock, 0))) 978 dev_warn(dev, "failed to disable device\n"); 979 return ret; 980 } 981 982 static int wmi_dev_remove(struct device *dev) 983 { 984 struct wmi_block *wblock = dev_to_wblock(dev); 985 struct wmi_driver *wdriver = 986 container_of(dev->driver, struct wmi_driver, driver); 987 int ret = 0; 988 989 if (wdriver->filter_callback) { 990 misc_deregister(&wblock->char_dev); 991 kfree(wblock->char_dev.name); 992 kfree(wblock->handler_data); 993 } 994 995 if (wdriver->remove) 996 ret = wdriver->remove(dev_to_wdev(dev)); 997 998 if (ACPI_FAILURE(wmi_method_enable(wblock, 0))) 999 dev_warn(dev, "failed to disable device\n"); 1000 1001 return ret; 1002 } 1003 1004 static struct class wmi_bus_class = { 1005 .name = "wmi_bus", 1006 }; 1007 1008 static struct bus_type wmi_bus_type = { 1009 .name = "wmi", 1010 .dev_groups = wmi_groups, 1011 .match = wmi_dev_match, 1012 .uevent = wmi_dev_uevent, 1013 .probe = wmi_dev_probe, 1014 .remove = wmi_dev_remove, 1015 }; 1016 1017 static const struct device_type wmi_type_event = { 1018 .name = "event", 1019 .groups = wmi_event_groups, 1020 .release = wmi_dev_release, 1021 }; 1022 1023 static const struct device_type wmi_type_method = { 1024 .name = "method", 1025 .groups = wmi_method_groups, 1026 .release = wmi_dev_release, 1027 }; 1028 1029 static const struct device_type wmi_type_data = { 1030 .name = "data", 1031 .groups = wmi_data_groups, 1032 .release = wmi_dev_release, 1033 }; 1034 1035 static int wmi_create_device(struct device *wmi_bus_dev, 1036 const struct guid_block *gblock, 1037 struct wmi_block *wblock, 1038 struct acpi_device *device) 1039 { 1040 struct acpi_device_info *info; 1041 char method[5]; 1042 int result; 1043 1044 if (gblock->flags & ACPI_WMI_EVENT) { 1045 wblock->dev.dev.type = &wmi_type_event; 1046 goto out_init; 1047 } 1048 1049 if (gblock->flags & ACPI_WMI_METHOD) { 1050 wblock->dev.dev.type = &wmi_type_method; 1051 mutex_init(&wblock->char_mutex); 1052 goto out_init; 1053 } 1054 1055 /* 1056 * Data Block Query Control Method (WQxx by convention) is 1057 * required per the WMI documentation. If it is not present, 1058 * we ignore this data block. 1059 */ 1060 strcpy(method, "WQ"); 1061 strncat(method, wblock->gblock.object_id, 2); 1062 result = get_subobj_info(device->handle, method, &info); 1063 1064 if (result) { 1065 dev_warn(wmi_bus_dev, 1066 "%s data block query control method not found\n", 1067 method); 1068 return result; 1069 } 1070 1071 wblock->dev.dev.type = &wmi_type_data; 1072 1073 /* 1074 * The Microsoft documentation specifically states: 1075 * 1076 * Data blocks registered with only a single instance 1077 * can ignore the parameter. 1078 * 1079 * ACPICA will get mad at us if we call the method with the wrong number 1080 * of arguments, so check what our method expects. (On some Dell 1081 * laptops, WQxx may not be a method at all.) 1082 */ 1083 if (info->type != ACPI_TYPE_METHOD || info->param_count == 0) 1084 wblock->read_takes_no_args = true; 1085 1086 kfree(info); 1087 1088 strcpy(method, "WS"); 1089 strncat(method, wblock->gblock.object_id, 2); 1090 result = get_subobj_info(device->handle, method, NULL); 1091 1092 if (result == 0) 1093 wblock->dev.setable = true; 1094 1095 out_init: 1096 wblock->dev.dev.bus = &wmi_bus_type; 1097 wblock->dev.dev.parent = wmi_bus_dev; 1098 1099 dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid); 1100 1101 device_initialize(&wblock->dev.dev); 1102 1103 return 0; 1104 } 1105 1106 static void wmi_free_devices(struct acpi_device *device) 1107 { 1108 struct wmi_block *wblock, *next; 1109 1110 /* Delete devices for all the GUIDs */ 1111 list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { 1112 if (wblock->acpi_device == device) { 1113 list_del(&wblock->list); 1114 device_unregister(&wblock->dev.dev); 1115 } 1116 } 1117 } 1118 1119 static bool guid_already_parsed(struct acpi_device *device, 1120 const u8 *guid) 1121 { 1122 struct wmi_block *wblock; 1123 1124 list_for_each_entry(wblock, &wmi_block_list, list) { 1125 if (memcmp(wblock->gblock.guid, guid, 16) == 0) { 1126 /* 1127 * Because we historically didn't track the relationship 1128 * between GUIDs and ACPI nodes, we don't know whether 1129 * we need to suppress GUIDs that are unique on a 1130 * given node but duplicated across nodes. 1131 */ 1132 dev_warn(&device->dev, "duplicate WMI GUID %pUL (first instance was on %s)\n", 1133 guid, dev_name(&wblock->acpi_device->dev)); 1134 return true; 1135 } 1136 } 1137 1138 return false; 1139 } 1140 1141 /* 1142 * Parse the _WDG method for the GUID data blocks 1143 */ 1144 static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) 1145 { 1146 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1147 const struct guid_block *gblock; 1148 struct wmi_block *wblock, *next; 1149 union acpi_object *obj; 1150 acpi_status status; 1151 int retval = 0; 1152 u32 i, total; 1153 1154 status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out); 1155 if (ACPI_FAILURE(status)) 1156 return -ENXIO; 1157 1158 obj = (union acpi_object *) out.pointer; 1159 if (!obj) 1160 return -ENXIO; 1161 1162 if (obj->type != ACPI_TYPE_BUFFER) { 1163 retval = -ENXIO; 1164 goto out_free_pointer; 1165 } 1166 1167 gblock = (const struct guid_block *)obj->buffer.pointer; 1168 total = obj->buffer.length / sizeof(struct guid_block); 1169 1170 for (i = 0; i < total; i++) { 1171 if (debug_dump_wdg) 1172 wmi_dump_wdg(&gblock[i]); 1173 1174 /* 1175 * Some WMI devices, like those for nVidia hooks, have a 1176 * duplicate GUID. It's not clear what we should do in this 1177 * case yet, so for now, we'll just ignore the duplicate 1178 * for device creation. 1179 */ 1180 if (guid_already_parsed(device, gblock[i].guid)) 1181 continue; 1182 1183 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); 1184 if (!wblock) { 1185 retval = -ENOMEM; 1186 break; 1187 } 1188 1189 wblock->acpi_device = device; 1190 wblock->gblock = gblock[i]; 1191 1192 retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device); 1193 if (retval) { 1194 kfree(wblock); 1195 continue; 1196 } 1197 1198 list_add_tail(&wblock->list, &wmi_block_list); 1199 1200 if (debug_event) { 1201 wblock->handler = wmi_notify_debug; 1202 wmi_method_enable(wblock, 1); 1203 } 1204 } 1205 1206 /* 1207 * Now that all of the devices are created, add them to the 1208 * device tree and probe subdrivers. 1209 */ 1210 list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { 1211 if (wblock->acpi_device != device) 1212 continue; 1213 1214 retval = device_add(&wblock->dev.dev); 1215 if (retval) { 1216 dev_err(wmi_bus_dev, "failed to register %pUL\n", 1217 wblock->gblock.guid); 1218 if (debug_event) 1219 wmi_method_enable(wblock, 0); 1220 list_del(&wblock->list); 1221 put_device(&wblock->dev.dev); 1222 } 1223 } 1224 1225 out_free_pointer: 1226 kfree(out.pointer); 1227 return retval; 1228 } 1229 1230 /* 1231 * WMI can have EmbeddedControl access regions. In which case, we just want to 1232 * hand these off to the EC driver. 1233 */ 1234 static acpi_status 1235 acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, 1236 u32 bits, u64 *value, 1237 void *handler_context, void *region_context) 1238 { 1239 int result = 0, i = 0; 1240 u8 temp = 0; 1241 1242 if ((address > 0xFF) || !value) 1243 return AE_BAD_PARAMETER; 1244 1245 if (function != ACPI_READ && function != ACPI_WRITE) 1246 return AE_BAD_PARAMETER; 1247 1248 if (bits != 8) 1249 return AE_BAD_PARAMETER; 1250 1251 if (function == ACPI_READ) { 1252 result = ec_read(address, &temp); 1253 (*value) |= ((u64)temp) << i; 1254 } else { 1255 temp = 0xff & ((*value) >> i); 1256 result = ec_write(address, temp); 1257 } 1258 1259 switch (result) { 1260 case -EINVAL: 1261 return AE_BAD_PARAMETER; 1262 break; 1263 case -ENODEV: 1264 return AE_NOT_FOUND; 1265 break; 1266 case -ETIME: 1267 return AE_TIME; 1268 break; 1269 default: 1270 return AE_OK; 1271 } 1272 } 1273 1274 static void acpi_wmi_notify_handler(acpi_handle handle, u32 event, 1275 void *context) 1276 { 1277 struct guid_block *block; 1278 struct wmi_block *wblock; 1279 bool found_it = false; 1280 1281 list_for_each_entry(wblock, &wmi_block_list, list) { 1282 block = &wblock->gblock; 1283 1284 if (wblock->acpi_device->handle == handle && 1285 (block->flags & ACPI_WMI_EVENT) && 1286 (block->notify_id == event)) 1287 { 1288 found_it = true; 1289 break; 1290 } 1291 } 1292 1293 if (!found_it) 1294 return; 1295 1296 /* If a driver is bound, then notify the driver. */ 1297 if (wblock->dev.dev.driver) { 1298 struct wmi_driver *driver; 1299 struct acpi_object_list input; 1300 union acpi_object params[1]; 1301 struct acpi_buffer evdata = { ACPI_ALLOCATE_BUFFER, NULL }; 1302 acpi_status status; 1303 1304 driver = container_of(wblock->dev.dev.driver, 1305 struct wmi_driver, driver); 1306 1307 input.count = 1; 1308 input.pointer = params; 1309 params[0].type = ACPI_TYPE_INTEGER; 1310 params[0].integer.value = event; 1311 1312 status = acpi_evaluate_object(wblock->acpi_device->handle, 1313 "_WED", &input, &evdata); 1314 if (ACPI_FAILURE(status)) { 1315 dev_warn(&wblock->dev.dev, 1316 "failed to get event data\n"); 1317 return; 1318 } 1319 1320 if (driver->notify) 1321 driver->notify(&wblock->dev, 1322 (union acpi_object *)evdata.pointer); 1323 1324 kfree(evdata.pointer); 1325 } else if (wblock->handler) { 1326 /* Legacy handler */ 1327 wblock->handler(event, wblock->handler_data); 1328 } 1329 1330 if (debug_event) { 1331 pr_info("DEBUG Event GUID: %pUL\n", 1332 wblock->gblock.guid); 1333 } 1334 1335 acpi_bus_generate_netlink_event( 1336 wblock->acpi_device->pnp.device_class, 1337 dev_name(&wblock->dev.dev), 1338 event, 0); 1339 1340 } 1341 1342 static int acpi_wmi_remove(struct platform_device *device) 1343 { 1344 struct acpi_device *acpi_device = ACPI_COMPANION(&device->dev); 1345 1346 acpi_remove_notify_handler(acpi_device->handle, ACPI_DEVICE_NOTIFY, 1347 acpi_wmi_notify_handler); 1348 acpi_remove_address_space_handler(acpi_device->handle, 1349 ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); 1350 wmi_free_devices(acpi_device); 1351 device_destroy(&wmi_bus_class, MKDEV(0, 0)); 1352 1353 return 0; 1354 } 1355 1356 static int acpi_wmi_probe(struct platform_device *device) 1357 { 1358 struct acpi_device *acpi_device; 1359 struct device *wmi_bus_dev; 1360 acpi_status status; 1361 int error; 1362 1363 acpi_device = ACPI_COMPANION(&device->dev); 1364 if (!acpi_device) { 1365 dev_err(&device->dev, "ACPI companion is missing\n"); 1366 return -ENODEV; 1367 } 1368 1369 status = acpi_install_address_space_handler(acpi_device->handle, 1370 ACPI_ADR_SPACE_EC, 1371 &acpi_wmi_ec_space_handler, 1372 NULL, NULL); 1373 if (ACPI_FAILURE(status)) { 1374 dev_err(&device->dev, "Error installing EC region handler\n"); 1375 return -ENODEV; 1376 } 1377 1378 status = acpi_install_notify_handler(acpi_device->handle, 1379 ACPI_DEVICE_NOTIFY, 1380 acpi_wmi_notify_handler, 1381 NULL); 1382 if (ACPI_FAILURE(status)) { 1383 dev_err(&device->dev, "Error installing notify handler\n"); 1384 error = -ENODEV; 1385 goto err_remove_ec_handler; 1386 } 1387 1388 wmi_bus_dev = device_create(&wmi_bus_class, &device->dev, MKDEV(0, 0), 1389 NULL, "wmi_bus-%s", dev_name(&device->dev)); 1390 if (IS_ERR(wmi_bus_dev)) { 1391 error = PTR_ERR(wmi_bus_dev); 1392 goto err_remove_notify_handler; 1393 } 1394 dev_set_drvdata(&device->dev, wmi_bus_dev); 1395 1396 error = parse_wdg(wmi_bus_dev, acpi_device); 1397 if (error) { 1398 pr_err("Failed to parse WDG method\n"); 1399 goto err_remove_busdev; 1400 } 1401 1402 return 0; 1403 1404 err_remove_busdev: 1405 device_destroy(&wmi_bus_class, MKDEV(0, 0)); 1406 1407 err_remove_notify_handler: 1408 acpi_remove_notify_handler(acpi_device->handle, ACPI_DEVICE_NOTIFY, 1409 acpi_wmi_notify_handler); 1410 1411 err_remove_ec_handler: 1412 acpi_remove_address_space_handler(acpi_device->handle, 1413 ACPI_ADR_SPACE_EC, 1414 &acpi_wmi_ec_space_handler); 1415 1416 return error; 1417 } 1418 1419 int __must_check __wmi_driver_register(struct wmi_driver *driver, 1420 struct module *owner) 1421 { 1422 driver->driver.owner = owner; 1423 driver->driver.bus = &wmi_bus_type; 1424 1425 return driver_register(&driver->driver); 1426 } 1427 EXPORT_SYMBOL(__wmi_driver_register); 1428 1429 void wmi_driver_unregister(struct wmi_driver *driver) 1430 { 1431 driver_unregister(&driver->driver); 1432 } 1433 EXPORT_SYMBOL(wmi_driver_unregister); 1434 1435 static int __init acpi_wmi_init(void) 1436 { 1437 int error; 1438 1439 if (acpi_disabled) 1440 return -ENODEV; 1441 1442 error = class_register(&wmi_bus_class); 1443 if (error) 1444 return error; 1445 1446 error = bus_register(&wmi_bus_type); 1447 if (error) 1448 goto err_unreg_class; 1449 1450 error = platform_driver_register(&acpi_wmi_driver); 1451 if (error) { 1452 pr_err("Error loading mapper\n"); 1453 goto err_unreg_bus; 1454 } 1455 1456 return 0; 1457 1458 err_unreg_bus: 1459 bus_unregister(&wmi_bus_type); 1460 1461 err_unreg_class: 1462 class_unregister(&wmi_bus_class); 1463 1464 return error; 1465 } 1466 1467 static void __exit acpi_wmi_exit(void) 1468 { 1469 platform_driver_unregister(&acpi_wmi_driver); 1470 bus_unregister(&wmi_bus_type); 1471 class_unregister(&wmi_bus_class); 1472 } 1473 1474 subsys_initcall_sync(acpi_wmi_init); 1475 module_exit(acpi_wmi_exit); 1476