Lines Matching +full:per +full:- +full:hart
2 * ACPI-WMI mapping driver
4 * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
8 * Copyright (c) 2001-2007 Anton Altaparmakov
11 * WMI bus infrastructure by Andrew Lutomirski and Darren Hart:
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
53 MODULE_DESCRIPTION("ACPI-WMI Mapping Driver");
117 .name = "acpi-wmi",
138 block = &wblock->gblock; in find_guid()
140 if (memcmp(block->guid, &guid_input, 16) == 0) { in find_guid()
158 return -ENOENT; in get_subobj_info()
160 return -EIO; in get_subobj_info()
165 return -EIO; in get_subobj_info()
180 block = &wblock->gblock; in wmi_method_enable()
181 handle = wblock->acpi_device->handle; in wmi_method_enable()
183 snprintf(method, 5, "WE%02X", block->notify_id); in wmi_method_enable()
197 * set_required_buffer_size - Sets the buffer size needed for performing IOCTL
208 wblock->req_buf_size = length; in set_required_buffer_size()
215 * wmi_evaluate_method - Evaluate a WMI method
216 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
222 * Call an ACPI-WMI method
231 return wmidev_evaluate_method(&wblock->dev, instance, method_id, in wmi_evaluate_method()
237 * wmidev_evaluate_method - Evaluate a WMI method
244 * Call an ACPI-WMI method
258 block = &wblock->gblock; in wmidev_evaluate_method()
259 handle = wblock->acpi_device->handle; in wmidev_evaluate_method()
261 if (!(block->flags & ACPI_WMI_METHOD)) in wmidev_evaluate_method()
264 if (block->instance_count <= instance) in wmidev_evaluate_method()
277 if (block->flags & ACPI_WMI_STRING) { in wmidev_evaluate_method()
282 params[2].buffer.length = in->length; in wmidev_evaluate_method()
283 params[2].buffer.pointer = in->pointer; in wmidev_evaluate_method()
286 strncat(method, block->object_id, 2); in wmidev_evaluate_method()
308 block = &wblock->gblock; in __query_block()
309 handle = wblock->acpi_device->handle; in __query_block()
311 if (block->instance_count <= instance) in __query_block()
315 if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) in __query_block()
323 if (instance == 0 && wblock->read_takes_no_args) in __query_block()
330 if (block->flags & ACPI_WMI_EXPENSIVE) { in __query_block()
331 strncat(wc_method, block->object_id, 2); in __query_block()
344 strncat(method, block->object_id, 2); in __query_block()
350 * the WQxx method failed - we should disable collection anyway. in __query_block()
352 if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { in __query_block()
360 * wmi_query_block - Return contents of a WMI block (deprecated)
361 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
365 * Return the contents of an ACPI-WMI data block to a buffer
395 * wmi_set_block - Write to a WMI block
396 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
400 * Write the contents of the input buffer to an ACPI-WMI data block
418 block = &wblock->gblock; in wmi_set_block()
419 handle = wblock->acpi_device->handle; in wmi_set_block()
421 if (block->instance_count <= instance) in wmi_set_block()
425 if (block->flags & (ACPI_WMI_EVENT | ACPI_WMI_METHOD)) in wmi_set_block()
433 if (block->flags & ACPI_WMI_STRING) { in wmi_set_block()
438 params[1].buffer.length = in->length; in wmi_set_block()
439 params[1].buffer.pointer = in->pointer; in wmi_set_block()
441 strncat(method, block->object_id, 2); in wmi_set_block()
449 pr_info("%pUL:\n", g->guid); in wmi_dump_wdg()
450 if (g->flags & ACPI_WMI_EVENT) in wmi_dump_wdg()
451 pr_info("\tnotify_id: 0x%02X\n", g->notify_id); in wmi_dump_wdg()
453 pr_info("\tobject_id: %2pE\n", g->object_id); in wmi_dump_wdg()
454 pr_info("\tinstance_count: %d\n", g->instance_count); in wmi_dump_wdg()
455 pr_info("\tflags: %#x", g->flags); in wmi_dump_wdg()
456 if (g->flags) { in wmi_dump_wdg()
457 if (g->flags & ACPI_WMI_EXPENSIVE) in wmi_dump_wdg()
459 if (g->flags & ACPI_WMI_METHOD) in wmi_dump_wdg()
461 if (g->flags & ACPI_WMI_STRING) in wmi_dump_wdg()
463 if (g->flags & ACPI_WMI_EVENT) in wmi_dump_wdg()
488 switch(obj->type) { in wmi_notify_debug()
490 pr_cont("BUFFER_TYPE - length %d\n", obj->buffer.length); in wmi_notify_debug()
493 pr_cont("STRING_TYPE - %s\n", obj->string.pointer); in wmi_notify_debug()
496 pr_cont("INTEGER_TYPE - %llu\n", obj->integer.value); in wmi_notify_debug()
499 pr_cont("PACKAGE_TYPE - %d elements\n", obj->package.count); in wmi_notify_debug()
502 pr_cont("object type 0x%X\n", obj->type); in wmi_notify_debug()
508 * wmi_install_notify_handler - Register handler for WMI events
512 * Register a handler for events sent to the ACPI-WMI mapper device.
530 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { in wmi_install_notify_handler()
531 if (block->handler && in wmi_install_notify_handler()
532 block->handler != wmi_notify_debug) in wmi_install_notify_handler()
535 block->handler = handler; in wmi_install_notify_handler()
536 block->handler_data = data; in wmi_install_notify_handler()
550 * wmi_uninstall_notify_handler - Unregister handler for WMI events
552 * Unregister handler for events sent to the ACPI-WMI mapper device.
569 if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { in wmi_remove_notify_handler()
570 if (!block->handler || in wmi_remove_notify_handler()
571 block->handler == wmi_notify_debug) in wmi_remove_notify_handler()
575 block->handler = wmi_notify_debug; in wmi_remove_notify_handler()
579 block->handler = NULL; in wmi_remove_notify_handler()
580 block->handler_data = NULL; in wmi_remove_notify_handler()
594 * wmi_get_event_data - Get WMI data associated with an event
597 * @out: Buffer to hold event data. out->pointer should be freed with kfree()
614 gblock = &wblock->gblock; in wmi_get_event_data()
616 if ((gblock->flags & ACPI_WMI_EVENT) && in wmi_get_event_data()
617 (gblock->notify_id == event)) in wmi_get_event_data()
618 return acpi_evaluate_object(wblock->acpi_device->handle, in wmi_get_event_data()
627 * wmi_has_guid - Check if a GUID is available
628 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
656 return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid); in modalias_show()
665 return sprintf(buf, "%pUL\n", wblock->gblock.guid); in guid_show()
674 return sprintf(buf, "%d\n", (int)wblock->gblock.instance_count); in instance_count_show()
684 (wblock->gblock.flags & ACPI_WMI_EXPENSIVE) != 0); in expensive_show()
702 return sprintf(buf, "%02X\n", (unsigned int)wblock->gblock.notify_id); in notify_id_show()
717 return sprintf(buf, "%c%c\n", wblock->gblock.object_id[0], in object_id_show()
718 wblock->gblock.object_id[1]); in object_id_show()
727 return sprintf(buf, "%d\n", (int)wdev->setable); in setable_show()
748 if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid)) in wmi_dev_uevent()
749 return -ENOMEM; in wmi_dev_uevent()
751 if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid)) in wmi_dev_uevent()
752 return -ENOMEM; in wmi_dev_uevent()
769 const struct wmi_device_id *id = wmi_driver->id_table; in wmi_dev_match()
774 while (id->guid_string) { in wmi_dev_match()
777 if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid))) in wmi_dev_match()
779 if (!memcmp(&driver_guid, wblock->gblock.guid, 16)) in wmi_dev_match()
789 const char *driver_name = filp->f_path.dentry->d_iname; in wmi_char_open()
794 if (!wblock->dev.dev.driver) in wmi_char_open()
796 if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) { in wmi_char_open()
797 filp->private_data = wblock; in wmi_char_open()
802 if (!filp->private_data) in wmi_char_open()
803 return -ENODEV; in wmi_char_open()
811 struct wmi_block *wblock = filp->private_data; in wmi_char_read()
814 &wblock->req_buf_size, in wmi_char_read()
815 sizeof(wblock->req_buf_size)); in wmi_char_read()
822 struct wmi_block *wblock = filp->private_data; in wmi_ioctl()
828 return -ENOTTY; in wmi_ioctl()
831 if (_IOC_NR(cmd) >= wblock->gblock.instance_count) in wmi_ioctl()
832 return -EINVAL; in wmi_ioctl()
834 mutex_lock(&wblock->char_mutex); in wmi_ioctl()
835 buf = wblock->handler_data; in wmi_ioctl()
836 if (get_user(buf->length, &input->length)) { in wmi_ioctl()
837 dev_dbg(&wblock->dev.dev, "Read length from user failed\n"); in wmi_ioctl()
838 ret = -EFAULT; in wmi_ioctl()
842 if (buf->length < wblock->req_buf_size) { in wmi_ioctl()
843 dev_err(&wblock->dev.dev, in wmi_ioctl()
845 buf->length, wblock->req_buf_size); in wmi_ioctl()
846 ret = -EINVAL; in wmi_ioctl()
850 if (buf->length > wblock->req_buf_size) in wmi_ioctl()
851 dev_warn(&wblock->dev.dev, in wmi_ioctl()
853 buf->length, wblock->req_buf_size); in wmi_ioctl()
856 if (copy_from_user(buf, input, wblock->req_buf_size)) { in wmi_ioctl()
857 dev_dbg(&wblock->dev.dev, "Copy %llu from user failed\n", in wmi_ioctl()
858 wblock->req_buf_size); in wmi_ioctl()
859 ret = -EFAULT; in wmi_ioctl()
864 wdriver = container_of(wblock->dev.dev.driver, in wmi_ioctl()
866 if (!try_module_get(wdriver->driver.owner)) { in wmi_ioctl()
867 ret = -EBUSY; in wmi_ioctl()
870 ret = wdriver->filter_callback(&wblock->dev, cmd, buf); in wmi_ioctl()
871 module_put(wdriver->driver.owner); in wmi_ioctl()
876 if (copy_to_user(input, buf, wblock->req_buf_size)) { in wmi_ioctl()
877 dev_dbg(&wblock->dev.dev, "Copy %llu to user failed\n", in wmi_ioctl()
878 wblock->req_buf_size); in wmi_ioctl()
879 ret = -EFAULT; in wmi_ioctl()
883 mutex_unlock(&wblock->char_mutex); in wmi_ioctl()
899 container_of(dev->driver, struct wmi_driver, driver); in wmi_dev_probe()
904 dev_warn(dev, "failed to enable device -- probing anyway\n"); in wmi_dev_probe()
906 if (wdriver->probe) { in wmi_dev_probe()
907 ret = wdriver->probe(dev_to_wdev(dev)); in wmi_dev_probe()
913 if (wdriver->filter_callback) { in wmi_dev_probe()
915 if (!wblock->req_buf_size) { in wmi_dev_probe()
916 dev_err(&wblock->dev.dev, in wmi_dev_probe()
918 ret = -EINVAL; in wmi_dev_probe()
922 wblock->handler_data = kmalloc(wblock->req_buf_size, in wmi_dev_probe()
924 if (!wblock->handler_data) { in wmi_dev_probe()
925 ret = -ENOMEM; in wmi_dev_probe()
929 buf = kasprintf(GFP_KERNEL, "wmi/%s", wdriver->driver.name); in wmi_dev_probe()
931 ret = -ENOMEM; in wmi_dev_probe()
934 wblock->char_dev.minor = MISC_DYNAMIC_MINOR; in wmi_dev_probe()
935 wblock->char_dev.name = buf; in wmi_dev_probe()
936 wblock->char_dev.fops = &wmi_fops; in wmi_dev_probe()
937 wblock->char_dev.mode = 0444; in wmi_dev_probe()
938 ret = misc_register(&wblock->char_dev); in wmi_dev_probe()
941 ret = -ENOMEM; in wmi_dev_probe()
951 kfree(wblock->handler_data); in wmi_dev_probe()
962 container_of(dev->driver, struct wmi_driver, driver); in wmi_dev_remove()
965 if (wdriver->filter_callback) { in wmi_dev_remove()
966 misc_deregister(&wblock->char_dev); in wmi_dev_remove()
967 kfree(wblock->char_dev.name); in wmi_dev_remove()
968 kfree(wblock->handler_data); in wmi_dev_remove()
971 if (wdriver->remove) in wmi_dev_remove()
972 ret = wdriver->remove(dev_to_wdev(dev)); in wmi_dev_remove()
1020 if (gblock->flags & ACPI_WMI_EVENT) { in wmi_create_device()
1021 wblock->dev.dev.type = &wmi_type_event; in wmi_create_device()
1025 if (gblock->flags & ACPI_WMI_METHOD) { in wmi_create_device()
1026 wblock->dev.dev.type = &wmi_type_method; in wmi_create_device()
1027 mutex_init(&wblock->char_mutex); in wmi_create_device()
1033 * required per the WMI documentation. If it is not present, in wmi_create_device()
1037 strncat(method, wblock->gblock.object_id, 2); in wmi_create_device()
1038 result = get_subobj_info(device->handle, method, &info); in wmi_create_device()
1047 wblock->dev.dev.type = &wmi_type_data; in wmi_create_device()
1059 if (info->type != ACPI_TYPE_METHOD || info->param_count == 0) in wmi_create_device()
1060 wblock->read_takes_no_args = true; in wmi_create_device()
1065 strncat(method, wblock->gblock.object_id, 2); in wmi_create_device()
1066 result = get_subobj_info(device->handle, method, NULL); in wmi_create_device()
1069 wblock->dev.setable = true; in wmi_create_device()
1072 wblock->dev.dev.bus = &wmi_bus_type; in wmi_create_device()
1073 wblock->dev.dev.parent = wmi_bus_dev; in wmi_create_device()
1075 dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid); in wmi_create_device()
1077 device_initialize(&wblock->dev.dev); in wmi_create_device()
1088 if (wblock->acpi_device == device) { in wmi_free_devices()
1089 list_del(&wblock->list); in wmi_free_devices()
1090 device_unregister(&wblock->dev.dev); in wmi_free_devices()
1101 if (memcmp(wblock->gblock.guid, guid, 16) == 0) { in guid_already_parsed()
1108 dev_warn(&device->dev, "duplicate WMI GUID %pUL (first instance was on %s)\n", in guid_already_parsed()
1109 guid, dev_name(&wblock->acpi_device->dev)); in guid_already_parsed()
1130 status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out); in parse_wdg()
1132 return -ENXIO; in parse_wdg()
1136 return -ENXIO; in parse_wdg()
1138 if (obj->type != ACPI_TYPE_BUFFER) { in parse_wdg()
1139 retval = -ENXIO; in parse_wdg()
1143 gblock = (const struct guid_block *)obj->buffer.pointer; in parse_wdg()
1144 total = obj->buffer.length / sizeof(struct guid_block); in parse_wdg()
1161 retval = -ENOMEM; in parse_wdg()
1165 wblock->acpi_device = device; in parse_wdg()
1166 wblock->gblock = gblock[i]; in parse_wdg()
1174 list_add_tail(&wblock->list, &wmi_block_list); in parse_wdg()
1177 wblock->handler = wmi_notify_debug; in parse_wdg()
1187 if (wblock->acpi_device != device) in parse_wdg()
1190 retval = device_add(&wblock->dev.dev); in parse_wdg()
1193 wblock->gblock.guid); in parse_wdg()
1196 list_del(&wblock->list); in parse_wdg()
1197 put_device(&wblock->dev.dev); in parse_wdg()
1236 case -EINVAL: in acpi_wmi_ec_space_handler()
1239 case -ENODEV: in acpi_wmi_ec_space_handler()
1242 case -ETIME: in acpi_wmi_ec_space_handler()
1258 block = &wblock->gblock; in acpi_wmi_notify_handler()
1260 if (wblock->acpi_device->handle == handle && in acpi_wmi_notify_handler()
1261 (block->flags & ACPI_WMI_EVENT) && in acpi_wmi_notify_handler()
1262 (block->notify_id == event)) in acpi_wmi_notify_handler()
1273 if (wblock->dev.dev.driver) { in acpi_wmi_notify_handler()
1280 driver = container_of(wblock->dev.dev.driver, in acpi_wmi_notify_handler()
1288 status = acpi_evaluate_object(wblock->acpi_device->handle, in acpi_wmi_notify_handler()
1291 dev_warn(&wblock->dev.dev, in acpi_wmi_notify_handler()
1296 if (driver->notify) in acpi_wmi_notify_handler()
1297 driver->notify(&wblock->dev, in acpi_wmi_notify_handler()
1301 } else if (wblock->handler) { in acpi_wmi_notify_handler()
1303 wblock->handler(event, wblock->handler_data); in acpi_wmi_notify_handler()
1308 wblock->gblock.guid); in acpi_wmi_notify_handler()
1312 wblock->acpi_device->pnp.device_class, in acpi_wmi_notify_handler()
1313 dev_name(&wblock->dev.dev), in acpi_wmi_notify_handler()
1320 struct acpi_device *acpi_device = ACPI_COMPANION(&device->dev); in acpi_wmi_remove()
1322 acpi_remove_notify_handler(acpi_device->handle, ACPI_DEVICE_NOTIFY, in acpi_wmi_remove()
1324 acpi_remove_address_space_handler(acpi_device->handle, in acpi_wmi_remove()
1339 acpi_device = ACPI_COMPANION(&device->dev); in acpi_wmi_probe()
1341 dev_err(&device->dev, "ACPI companion is missing\n"); in acpi_wmi_probe()
1342 return -ENODEV; in acpi_wmi_probe()
1345 status = acpi_install_address_space_handler(acpi_device->handle, in acpi_wmi_probe()
1350 dev_err(&device->dev, "Error installing EC region handler\n"); in acpi_wmi_probe()
1351 return -ENODEV; in acpi_wmi_probe()
1354 status = acpi_install_notify_handler(acpi_device->handle, in acpi_wmi_probe()
1359 dev_err(&device->dev, "Error installing notify handler\n"); in acpi_wmi_probe()
1360 error = -ENODEV; in acpi_wmi_probe()
1364 wmi_bus_dev = device_create(&wmi_bus_class, &device->dev, MKDEV(0, 0), in acpi_wmi_probe()
1365 NULL, "wmi_bus-%s", dev_name(&device->dev)); in acpi_wmi_probe()
1370 dev_set_drvdata(&device->dev, wmi_bus_dev); in acpi_wmi_probe()
1384 acpi_remove_notify_handler(acpi_device->handle, ACPI_DEVICE_NOTIFY, in acpi_wmi_probe()
1388 acpi_remove_address_space_handler(acpi_device->handle, in acpi_wmi_probe()
1398 driver->driver.owner = owner; in __wmi_driver_register()
1399 driver->driver.bus = &wmi_bus_type; in __wmi_driver_register()
1401 return driver_register(&driver->driver); in __wmi_driver_register()
1407 driver_unregister(&driver->driver); in wmi_driver_unregister()
1416 return -ENODEV; in acpi_wmi_init()