Lines Matching +full:per +full:- +full:hart
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * ACPI-WMI mapping driver
5 * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
9 * Copyright (c) 2001-2007 Anton Altaparmakov
12 * WMI bus infrastructure by Andrew Lutomirski and Darren Hart:
39 MODULE_DESCRIPTION("ACPI-WMI Mapping Driver");
107 "05901221-D566-11D1-B2F0-00A0C9062910", /* wmi-bmof */
108 "8A42EA14-4F2A-FD45-6422-0087F7A7E608", /* dell-wmi-ddv */
128 if (guid_equal(&wblock->gblock.guid, &guid_input)) { in find_guid()
154 id = wdriver->id_table; in find_guid_context()
158 while (*id->guid_string) { in find_guid_context()
159 if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) in find_guid_context()
160 return id->context; in find_guid_context()
175 return -ENOENT; in get_subobj_info()
177 return -EIO; in get_subobj_info()
182 return -EIO; in get_subobj_info()
197 block = &wblock->gblock; in wmi_method_enable()
198 handle = wblock->acpi_device->handle; in wmi_method_enable()
200 snprintf(method, 5, "WE%02X", block->notify_id); in wmi_method_enable()
214 static_assert(ARRAY_SIZE(wblock->gblock.object_id) == 2); in get_acpi_method_name()
219 buffer[2] = wblock->gblock.object_id[0]; in get_acpi_method_name()
220 buffer[3] = wblock->gblock.object_id[1]; in get_acpi_method_name()
226 if (wblock->gblock.flags & ACPI_WMI_STRING) in get_param_acpi_type()
237 .value = wblock->gblock.notify_id, in get_event_data()
245 return acpi_evaluate_object(wblock->acpi_device->handle, "_WED", &input, out); in get_event_data()
253 * set_required_buffer_size - Sets the buffer size needed for performing IOCTL
266 wblock->req_buf_size = length; in set_required_buffer_size()
273 * wmi_instance_count - Get number of WMI object instances
274 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
288 return -EINVAL; in wmi_instance_count()
290 return -ENODEV; in wmi_instance_count()
293 return wmidev_instance_count(&wblock->dev); in wmi_instance_count()
298 * wmidev_instance_count - Get number of WMI object instances
309 return wblock->gblock.instance_count; in wmidev_instance_count()
314 * wmi_evaluate_method - Evaluate a WMI method (deprecated)
315 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
321 * Call an ACPI-WMI method, the caller must free @out.
335 return wmidev_evaluate_method(&wblock->dev, instance, method_id, in wmi_evaluate_method()
341 * wmidev_evaluate_method - Evaluate a WMI method
348 * Call an ACPI-WMI method, the caller must free @out.
363 block = &wblock->gblock; in wmidev_evaluate_method()
364 handle = wblock->acpi_device->handle; in wmidev_evaluate_method()
366 if (!(block->flags & ACPI_WMI_METHOD)) in wmidev_evaluate_method()
369 if (block->instance_count <= instance) in wmidev_evaluate_method()
383 params[2].buffer.length = in->length; in wmidev_evaluate_method()
384 params[2].buffer.pointer = in->pointer; in wmidev_evaluate_method()
407 block = &wblock->gblock; in __query_block()
408 handle = wblock->acpi_device->handle; in __query_block()
410 if (block->instance_count <= instance) in __query_block()
414 if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) in __query_block()
422 if (instance == 0 && test_bit(WMI_READ_TAKES_NO_ARGS, &wblock->flags)) in __query_block()
429 if (block->flags & ACPI_WMI_EXPENSIVE) { in __query_block()
445 * the WQxx method failed - we should disable collection anyway. in __query_block()
447 if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { in __query_block()
462 * wmi_query_block - Return contents of a WMI block (deprecated)
463 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
467 * Query a ACPI-WMI block, the caller must free @out.
486 * wmidev_block_query - Return contents of a WMI block
490 * Query an ACPI-WMI block, the caller must free the result.
507 * wmi_set_block - Write to a WMI block (deprecated)
508 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
512 * Write the contents of the input buffer to an ACPI-WMI data block.
534 block = &wblock->gblock; in wmi_set_block()
535 handle = wblock->acpi_device->handle; in wmi_set_block()
537 if (block->instance_count <= instance) in wmi_set_block()
541 if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) in wmi_set_block()
549 params[1].buffer.length = in->length; in wmi_set_block()
550 params[1].buffer.pointer = in->pointer; in wmi_set_block()
560 pr_info("%pUL:\n", &g->guid); in wmi_dump_wdg()
561 if (g->flags & ACPI_WMI_EVENT) in wmi_dump_wdg()
562 pr_info("\tnotify_id: 0x%02X\n", g->notify_id); in wmi_dump_wdg()
564 pr_info("\tobject_id: %2pE\n", g->object_id); in wmi_dump_wdg()
565 pr_info("\tinstance_count: %d\n", g->instance_count); in wmi_dump_wdg()
566 pr_info("\tflags: %#x", g->flags); in wmi_dump_wdg()
567 if (g->flags) { in wmi_dump_wdg()
568 if (g->flags & ACPI_WMI_EXPENSIVE) in wmi_dump_wdg()
570 if (g->flags & ACPI_WMI_METHOD) in wmi_dump_wdg()
572 if (g->flags & ACPI_WMI_STRING) in wmi_dump_wdg()
574 if (g->flags & ACPI_WMI_EVENT) in wmi_dump_wdg()
598 switch (obj->type) { in wmi_notify_debug()
600 pr_cont("BUFFER_TYPE - length %u\n", obj->buffer.length); in wmi_notify_debug()
603 pr_cont("STRING_TYPE - %s\n", obj->string.pointer); in wmi_notify_debug()
606 pr_cont("INTEGER_TYPE - %llu\n", obj->integer.value); in wmi_notify_debug()
609 pr_cont("PACKAGE_TYPE - %u elements\n", obj->package.count); in wmi_notify_debug()
612 pr_cont("object type 0x%X\n", obj->type); in wmi_notify_debug()
618 * wmi_install_notify_handler - Register handler for WMI events (deprecated)
619 * @guid: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
623 * Register a handler for events sent to the ACPI-WMI mapper device.
644 if (guid_equal(&block->gblock.guid, &guid_input)) { in wmi_install_notify_handler()
645 if (block->handler && in wmi_install_notify_handler()
646 block->handler != wmi_notify_debug) in wmi_install_notify_handler()
649 block->handler = handler; in wmi_install_notify_handler()
650 block->handler_data = data; in wmi_install_notify_handler()
664 * wmi_remove_notify_handler - Unregister handler for WMI events (deprecated)
665 * @guid: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
667 * Unregister handler for events sent to the ACPI-WMI mapper device.
686 if (guid_equal(&block->gblock.guid, &guid_input)) { in wmi_remove_notify_handler()
687 if (!block->handler || in wmi_remove_notify_handler()
688 block->handler == wmi_notify_debug) in wmi_remove_notify_handler()
692 block->handler = wmi_notify_debug; in wmi_remove_notify_handler()
696 block->handler = NULL; in wmi_remove_notify_handler()
697 block->handler_data = NULL; in wmi_remove_notify_handler()
711 * wmi_get_event_data - Get WMI data associated with an event (deprecated)
725 struct guid_block *gblock = &wblock->gblock; in wmi_get_event_data()
727 if ((gblock->flags & ACPI_WMI_EVENT) && gblock->notify_id == event) in wmi_get_event_data()
736 * wmi_has_guid - Check if a GUID is available
737 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
750 * wmi_get_acpi_device_uid() - Get _UID name of ACPI device that defines GUID (deprecated)
751 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
766 return acpi_device_uid(wblock->acpi_device); in wmi_get_acpi_device_uid()
786 return sysfs_emit(buf, "wmi:%pUL\n", &wblock->gblock.guid); in modalias_show()
795 return sysfs_emit(buf, "%pUL\n", &wblock->gblock.guid); in guid_show()
804 return sysfs_emit(buf, "%d\n", (int)wblock->gblock.instance_count); in instance_count_show()
814 (wblock->gblock.flags & ACPI_WMI_EXPENSIVE) != 0); in expensive_show()
832 return sysfs_emit(buf, "%02X\n", (unsigned int)wblock->gblock.notify_id); in notify_id_show()
847 return sysfs_emit(buf, "%c%c\n", wblock->gblock.object_id[0], in object_id_show()
848 wblock->gblock.object_id[1]); in object_id_show()
857 return sysfs_emit(buf, "%d\n", (int)wdev->setable); in setable_show()
878 if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid)) in wmi_dev_uevent()
879 return -ENOMEM; in wmi_dev_uevent()
881 if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid)) in wmi_dev_uevent()
882 return -ENOMEM; in wmi_dev_uevent()
898 const struct wmi_device_id *id = wmi_driver->id_table; in wmi_dev_match()
903 while (*id->guid_string) { in wmi_dev_match()
904 if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) in wmi_dev_match()
916 * inside filp->private_data in wmi_char_open()
918 struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev); in wmi_char_open()
920 filp->private_data = wblock; in wmi_char_open()
928 struct wmi_block *wblock = filp->private_data; in wmi_char_read()
931 &wblock->req_buf_size, in wmi_char_read()
932 sizeof(wblock->req_buf_size)); in wmi_char_read()
939 struct wmi_block *wblock = filp->private_data; in wmi_ioctl()
945 return -ENOTTY; in wmi_ioctl()
948 if (_IOC_NR(cmd) >= wblock->gblock.instance_count) in wmi_ioctl()
949 return -EINVAL; in wmi_ioctl()
951 mutex_lock(&wblock->char_mutex); in wmi_ioctl()
952 buf = wblock->handler_data; in wmi_ioctl()
953 if (get_user(buf->length, &input->length)) { in wmi_ioctl()
954 dev_dbg(&wblock->dev.dev, "Read length from user failed\n"); in wmi_ioctl()
955 ret = -EFAULT; in wmi_ioctl()
959 if (buf->length < wblock->req_buf_size) { in wmi_ioctl()
960 dev_err(&wblock->dev.dev, in wmi_ioctl()
962 buf->length, wblock->req_buf_size); in wmi_ioctl()
963 ret = -EINVAL; in wmi_ioctl()
967 if (buf->length > wblock->req_buf_size) in wmi_ioctl()
968 dev_warn(&wblock->dev.dev, in wmi_ioctl()
970 buf->length, wblock->req_buf_size); in wmi_ioctl()
973 if (copy_from_user(buf, input, wblock->req_buf_size)) { in wmi_ioctl()
974 dev_dbg(&wblock->dev.dev, "Copy %llu from user failed\n", in wmi_ioctl()
975 wblock->req_buf_size); in wmi_ioctl()
976 ret = -EFAULT; in wmi_ioctl()
981 wdriver = drv_to_wdrv(wblock->dev.dev.driver); in wmi_ioctl()
982 if (!try_module_get(wdriver->driver.owner)) { in wmi_ioctl()
983 ret = -EBUSY; in wmi_ioctl()
986 ret = wdriver->filter_callback(&wblock->dev, cmd, buf); in wmi_ioctl()
987 module_put(wdriver->driver.owner); in wmi_ioctl()
992 if (copy_to_user(input, buf, wblock->req_buf_size)) { in wmi_ioctl()
993 dev_dbg(&wblock->dev.dev, "Copy %llu to user failed\n", in wmi_ioctl()
994 wblock->req_buf_size); in wmi_ioctl()
995 ret = -EFAULT; in wmi_ioctl()
999 mutex_unlock(&wblock->char_mutex); in wmi_ioctl()
1014 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); in wmi_dev_probe()
1019 dev_warn(dev, "failed to enable device -- probing anyway\n"); in wmi_dev_probe()
1021 if (wdriver->probe) { in wmi_dev_probe()
1022 ret = wdriver->probe(dev_to_wdev(dev), in wmi_dev_probe()
1029 if (wdriver->filter_callback) { in wmi_dev_probe()
1031 if (!wblock->req_buf_size) { in wmi_dev_probe()
1032 dev_err(&wblock->dev.dev, in wmi_dev_probe()
1034 ret = -EINVAL; in wmi_dev_probe()
1038 wblock->handler_data = kmalloc(wblock->req_buf_size, in wmi_dev_probe()
1040 if (!wblock->handler_data) { in wmi_dev_probe()
1041 ret = -ENOMEM; in wmi_dev_probe()
1045 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); in wmi_dev_probe()
1047 ret = -ENOMEM; in wmi_dev_probe()
1050 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; in wmi_dev_probe()
1051 wblock->char_dev.name = buf; in wmi_dev_probe()
1052 wblock->char_dev.fops = &wmi_fops; in wmi_dev_probe()
1053 wblock->char_dev.mode = 0444; in wmi_dev_probe()
1054 ret = misc_register(&wblock->char_dev); in wmi_dev_probe()
1057 ret = -ENOMEM; in wmi_dev_probe()
1062 set_bit(WMI_PROBED, &wblock->flags); in wmi_dev_probe()
1068 kfree(wblock->handler_data); in wmi_dev_probe()
1078 struct wmi_driver *wdriver = drv_to_wdrv(dev->driver); in wmi_dev_remove()
1080 clear_bit(WMI_PROBED, &wblock->flags); in wmi_dev_remove()
1082 if (wdriver->filter_callback) { in wmi_dev_remove()
1083 misc_deregister(&wblock->char_dev); in wmi_dev_remove()
1084 kfree(wblock->char_dev.name); in wmi_dev_remove()
1085 kfree(wblock->handler_data); in wmi_dev_remove()
1088 if (wdriver->remove) in wmi_dev_remove()
1089 wdriver->remove(dev_to_wdev(dev)); in wmi_dev_remove()
1136 if (guid_equal(&wblock->gblock.guid, guid)) in guid_count()
1152 if (wblock->gblock.flags & ACPI_WMI_EVENT) { in wmi_create_device()
1153 wblock->dev.dev.type = &wmi_type_event; in wmi_create_device()
1157 if (wblock->gblock.flags & ACPI_WMI_METHOD) { in wmi_create_device()
1158 wblock->dev.dev.type = &wmi_type_method; in wmi_create_device()
1159 mutex_init(&wblock->char_mutex); in wmi_create_device()
1165 * required per the WMI documentation. If it is not present, in wmi_create_device()
1169 result = get_subobj_info(device->handle, method, &info); in wmi_create_device()
1178 wblock->dev.dev.type = &wmi_type_data; in wmi_create_device()
1190 if (info->type != ACPI_TYPE_METHOD || info->param_count == 0) in wmi_create_device()
1191 set_bit(WMI_READ_TAKES_NO_ARGS, &wblock->flags); in wmi_create_device()
1196 result = get_subobj_info(device->handle, method, NULL); in wmi_create_device()
1199 wblock->dev.setable = true; in wmi_create_device()
1202 wblock->dev.dev.bus = &wmi_bus_type; in wmi_create_device()
1203 wblock->dev.dev.parent = wmi_bus_dev; in wmi_create_device()
1205 count = guid_count(&wblock->gblock.guid); in wmi_create_device()
1207 dev_set_name(&wblock->dev.dev, "%pUL-%d", &wblock->gblock.guid, count); in wmi_create_device()
1209 dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid); in wmi_create_device()
1211 device_initialize(&wblock->dev.dev); in wmi_create_device()
1222 if (wblock->acpi_device == device) { in wmi_free_devices()
1223 list_del(&wblock->list); in wmi_free_devices()
1224 device_unregister(&wblock->dev.dev); in wmi_free_devices()
1239 if (guid_equal(&wblock->gblock.guid, guid)) { in guid_already_parsed_for_legacy()
1246 dev_warn(&device->dev, "duplicate WMI GUID %pUL (first instance was on %s)\n", in guid_already_parsed_for_legacy()
1247 guid, dev_name(&wblock->acpi_device->dev)); in guid_already_parsed_for_legacy()
1268 status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out); in parse_wdg()
1270 return -ENXIO; in parse_wdg()
1274 return -ENXIO; in parse_wdg()
1276 if (obj->type != ACPI_TYPE_BUFFER) { in parse_wdg()
1278 return -ENXIO; in parse_wdg()
1281 gblock = (const struct guid_block *)obj->buffer.pointer; in parse_wdg()
1282 total = obj->buffer.length / sizeof(struct guid_block); in parse_wdg()
1302 wblock->acpi_device = device; in parse_wdg()
1303 wblock->gblock = gblock[i]; in parse_wdg()
1311 list_add_tail(&wblock->list, &wmi_block_list); in parse_wdg()
1314 wblock->handler = wmi_notify_debug; in parse_wdg()
1324 if (wblock->acpi_device != device) in parse_wdg()
1327 retval = device_add(&wblock->dev.dev); in parse_wdg()
1330 &wblock->gblock.guid); in parse_wdg()
1333 list_del(&wblock->list); in parse_wdg()
1334 put_device(&wblock->dev.dev); in parse_wdg()
1373 case -EINVAL: in acpi_wmi_ec_space_handler()
1375 case -ENODEV: in acpi_wmi_ec_space_handler()
1377 case -ETIME: in acpi_wmi_ec_space_handler()
1390 struct guid_block *block = &iter->gblock; in acpi_wmi_notify_handler()
1392 if (iter->acpi_device->handle == handle && in acpi_wmi_notify_handler()
1393 (block->flags & ACPI_WMI_EVENT) && in acpi_wmi_notify_handler()
1394 (block->notify_id == event)) { in acpi_wmi_notify_handler()
1404 if (test_bit(WMI_PROBED, &wblock->flags) && wblock->dev.dev.driver) { in acpi_wmi_notify_handler()
1405 struct wmi_driver *driver = drv_to_wdrv(wblock->dev.dev.driver); in acpi_wmi_notify_handler()
1409 if (!driver->no_notify_data) { in acpi_wmi_notify_handler()
1412 dev_warn(&wblock->dev.dev, "failed to get event data\n"); in acpi_wmi_notify_handler()
1417 if (driver->notify) in acpi_wmi_notify_handler()
1418 driver->notify(&wblock->dev, evdata.pointer); in acpi_wmi_notify_handler()
1421 } else if (wblock->handler) { in acpi_wmi_notify_handler()
1423 wblock->handler(event, wblock->handler_data); in acpi_wmi_notify_handler()
1427 pr_info("DEBUG: GUID %pUL event 0x%02X\n", &wblock->gblock.guid, event); in acpi_wmi_notify_handler()
1430 wblock->acpi_device->pnp.device_class, in acpi_wmi_notify_handler()
1431 dev_name(&wblock->dev.dev), in acpi_wmi_notify_handler()
1437 struct acpi_device *acpi_device = ACPI_COMPANION(&device->dev); in acpi_wmi_remove()
1439 acpi_remove_notify_handler(acpi_device->handle, ACPI_ALL_NOTIFY, in acpi_wmi_remove()
1441 acpi_remove_address_space_handler(acpi_device->handle, in acpi_wmi_remove()
1444 device_unregister(dev_get_drvdata(&device->dev)); in acpi_wmi_remove()
1454 acpi_device = ACPI_COMPANION(&device->dev); in acpi_wmi_probe()
1456 dev_err(&device->dev, "ACPI companion is missing\n"); in acpi_wmi_probe()
1457 return -ENODEV; in acpi_wmi_probe()
1460 status = acpi_install_address_space_handler(acpi_device->handle, in acpi_wmi_probe()
1465 dev_err(&device->dev, "Error installing EC region handler\n"); in acpi_wmi_probe()
1466 return -ENODEV; in acpi_wmi_probe()
1469 status = acpi_install_notify_handler(acpi_device->handle, in acpi_wmi_probe()
1474 dev_err(&device->dev, "Error installing notify handler\n"); in acpi_wmi_probe()
1475 error = -ENODEV; in acpi_wmi_probe()
1479 wmi_bus_dev = device_create(&wmi_bus_class, &device->dev, MKDEV(0, 0), in acpi_wmi_probe()
1480 NULL, "wmi_bus-%s", dev_name(&device->dev)); in acpi_wmi_probe()
1485 dev_set_drvdata(&device->dev, wmi_bus_dev); in acpi_wmi_probe()
1499 acpi_remove_notify_handler(acpi_device->handle, ACPI_ALL_NOTIFY, in acpi_wmi_probe()
1503 acpi_remove_address_space_handler(acpi_device->handle, in acpi_wmi_probe()
1513 driver->driver.owner = owner; in __wmi_driver_register()
1514 driver->driver.bus = &wmi_bus_type; in __wmi_driver_register()
1516 return driver_register(&driver->driver); in __wmi_driver_register()
1521 * wmi_driver_unregister() - Unregister a WMI driver
1528 driver_unregister(&driver->driver); in wmi_driver_unregister()
1534 .name = "acpi-wmi",
1546 return -ENODEV; in acpi_wmi_init()