From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/platform/x86/wmi.c | 167 +++++++++++++++++++++++++++++++------------------------ 1 files changed, 95 insertions(+), 72 deletions(-) diff --git a/kernel/drivers/platform/x86/wmi.c b/kernel/drivers/platform/x86/wmi.c index 387358a..567c287 100644 --- a/kernel/drivers/platform/x86/wmi.c +++ b/kernel/drivers/platform/x86/wmi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * ACPI-WMI mapping driver * @@ -11,24 +12,6 @@ * WMI bus infrastructure by Andrew Lutomirski and Darren Hart: * Copyright (C) 2015 Andrew Lutomirski * Copyright (C) 2017 VMware, Inc. All Rights Reserved. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -46,6 +29,7 @@ #include <linux/uaccess.h> #include <linux/uuid.h> #include <linux/wmi.h> +#include <linux/fs.h> #include <uapi/linux/wmi.h> ACPI_MODULE_NAME("wmi"); @@ -56,7 +40,7 @@ static LIST_HEAD(wmi_block_list); struct guid_block { - char guid[16]; + guid_t guid; union { char object_id[2]; struct { @@ -127,23 +111,52 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) { - uuid_le guid_input; + guid_t guid_input; struct wmi_block *wblock; struct guid_block *block; - if (uuid_le_to_bin(guid_string, &guid_input)) + if (guid_parse(guid_string, &guid_input)) return false; list_for_each_entry(wblock, &wmi_block_list, list) { block = &wblock->gblock; - if (memcmp(block->guid, &guid_input, 16) == 0) { + if (guid_equal(&block->guid, &guid_input)) { if (out) *out = wblock; return true; } } return false; +} + +static bool guid_parse_and_compare(const char *string, const guid_t *guid) +{ + guid_t guid_input; + + if (guid_parse(string, &guid_input)) + return false; + + return guid_equal(&guid_input, guid); +} + +static const void *find_guid_context(struct wmi_block *wblock, + struct wmi_driver *wdriver) +{ + const struct wmi_device_id *id; + + if (wblock == NULL || wdriver == NULL) + return NULL; + if (wdriver->id_table == NULL) + return NULL; + + id = wdriver->id_table; + while (*id->guid_string) { + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) + return id->context; + id++; + } + return NULL; } static int get_subobj_info(acpi_handle handle, const char *pathname, @@ -196,7 +209,7 @@ /** * set_required_buffer_size - Sets the buffer size needed for performing IOCTL * @wdev: A wmi bus device from a driver - * @instance: Instance index + * @length: Required buffer size * * Allocates memory needed for buffer, stores the buffer size in that memory */ @@ -216,8 +229,8 @@ * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba * @instance: Instance index * @method_id: Method ID to call - * &in: Buffer containing input for the method call - * &out: Empty buffer to return the method results + * @in: Buffer containing input for the method call + * @out: Empty buffer to return the method results * * Call an ACPI-WMI method */ @@ -238,8 +251,8 @@ * @wdev: A wmi bus device from a driver * @instance: Instance index * @method_id: Method ID to call - * &in: Buffer containing input for the method call - * &out: Empty buffer to return the method results + * @in: Buffer containing input for the method call + * @out: Empty buffer to return the method results * * Call an ACPI-WMI method */ @@ -335,9 +348,7 @@ * expensive, but have no corresponding WCxx method. So we * should not fail if this happens. */ - if (acpi_has_method(handle, wc_method)) - wc_status = acpi_execute_simple_method(handle, - wc_method, 1); + wc_status = acpi_execute_simple_method(handle, wc_method, 1); } strcpy(method, "WQ"); @@ -367,7 +378,7 @@ * wmi_query_block - Return contents of a WMI block (deprecated) * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba * @instance: Instance index - * &out: Empty buffer to return the contents of the data block to + * @out: Empty buffer to return the contents of the data block to * * Return the contents of an ACPI-WMI data block to a buffer */ @@ -402,7 +413,7 @@ * wmi_set_block - Write to a WMI block * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba * @instance: Instance index - * &in: Buffer containing new values for the data block + * @in: Buffer containing new values for the data block * * Write the contents of the input buffer to an ACPI-WMI data block */ @@ -453,7 +464,7 @@ static void wmi_dump_wdg(const struct guid_block *g) { - pr_info("%pUL:\n", g->guid); + pr_info("%pUL:\n", &g->guid); if (g->flags & ACPI_WMI_EVENT) pr_info("\tnotify_id: 0x%02X\n", g->notify_id); else @@ -513,6 +524,7 @@ /** * wmi_install_notify_handler - Register handler for WMI events + * @guid: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba * @handler: Function to handle notifications * @data: Data to be returned to handler when event is fired * @@ -523,18 +535,18 @@ { struct wmi_block *block; acpi_status status = AE_NOT_EXIST; - uuid_le guid_input; + guid_t guid_input; if (!guid || !handler) return AE_BAD_PARAMETER; - if (uuid_le_to_bin(guid, &guid_input)) + if (guid_parse(guid, &guid_input)) return AE_BAD_PARAMETER; list_for_each_entry(block, &wmi_block_list, list) { acpi_status wmi_status; - if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { + if (guid_equal(&block->gblock.guid, &guid_input)) { if (block->handler && block->handler != wmi_notify_debug) return AE_ALREADY_ACQUIRED; @@ -555,6 +567,7 @@ /** * wmi_uninstall_notify_handler - Unregister handler for WMI events + * @guid: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba * * Unregister handler for events sent to the ACPI-WMI mapper device. */ @@ -562,18 +575,18 @@ { struct wmi_block *block; acpi_status status = AE_NOT_EXIST; - uuid_le guid_input; + guid_t guid_input; if (!guid) return AE_BAD_PARAMETER; - if (uuid_le_to_bin(guid, &guid_input)) + if (guid_parse(guid, &guid_input)) return AE_BAD_PARAMETER; list_for_each_entry(block, &wmi_block_list, list) { acpi_status wmi_status; - if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { + if (guid_equal(&block->gblock.guid, &guid_input)) { if (!block->handler || block->handler == wmi_notify_debug) return AE_NULL_ENTRY; @@ -609,7 +622,6 @@ { struct acpi_object_list input; union acpi_object params[1]; - struct guid_block *gblock; struct wmi_block *wblock; input.count = 1; @@ -618,7 +630,7 @@ params[0].integer.value = event; list_for_each_entry(wblock, &wmi_block_list, list) { - gblock = &wblock->gblock; + struct guid_block *gblock = &wblock->gblock; if ((gblock->flags & ACPI_WMI_EVENT) && (gblock->notify_id == event)) @@ -642,6 +654,25 @@ } EXPORT_SYMBOL_GPL(wmi_has_guid); +/** + * wmi_get_acpi_device_uid() - Get _UID name of ACPI device that defines GUID + * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba + * + * Find the _UID of ACPI device associated with this WMI GUID. + * + * Return: The ACPI _UID field value or NULL if the WMI GUID was not found + */ +char *wmi_get_acpi_device_uid(const char *guid_string) +{ + struct wmi_block *wblock = NULL; + + if (!find_guid(guid_string, &wblock)) + return NULL; + + return acpi_device_uid(wblock->acpi_device); +} +EXPORT_SYMBOL_GPL(wmi_get_acpi_device_uid); + static struct wmi_block *dev_to_wblock(struct device *dev) { return container_of(dev, struct wmi_block, dev.dev); @@ -660,7 +691,7 @@ { struct wmi_block *wblock = dev_to_wblock(dev); - return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid); + return sprintf(buf, "wmi:%pUL\n", &wblock->gblock.guid); } static DEVICE_ATTR_RO(modalias); @@ -669,7 +700,7 @@ { struct wmi_block *wblock = dev_to_wblock(dev); - return sprintf(buf, "%pUL\n", wblock->gblock.guid); + return sprintf(buf, "%pUL\n", &wblock->gblock.guid); } static DEVICE_ATTR_RO(guid); @@ -752,10 +783,10 @@ { struct wmi_block *wblock = dev_to_wblock(dev); - if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid)) + if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid)) return -ENOMEM; - if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid)) + if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid)) return -ENOMEM; return 0; @@ -778,12 +809,8 @@ if (id == NULL) return 0; - while (id->guid_string) { - uuid_le driver_guid; - - if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid))) - continue; - if (!memcmp(&driver_guid, wblock->gblock.guid, 16)) + while (*id->guid_string) { + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return 1; id++; @@ -896,7 +923,7 @@ .read = wmi_char_read, .open = wmi_char_open, .unlocked_ioctl = wmi_ioctl, - .compat_ioctl = wmi_ioctl, + .compat_ioctl = compat_ptr_ioctl, }; static int wmi_dev_probe(struct device *dev) @@ -911,7 +938,8 @@ dev_warn(dev, "failed to enable device -- probing anyway\n"); if (wdriver->probe) { - ret = wdriver->probe(dev_to_wdev(dev)); + ret = wdriver->probe(dev_to_wdev(dev), + find_guid_context(wblock, wdriver)); if (ret != 0) goto probe_failure; } @@ -997,26 +1025,25 @@ .remove = wmi_dev_remove, }; -static struct device_type wmi_type_event = { +static const struct device_type wmi_type_event = { .name = "event", .groups = wmi_event_groups, .release = wmi_dev_release, }; -static struct device_type wmi_type_method = { +static const struct device_type wmi_type_method = { .name = "method", .groups = wmi_method_groups, .release = wmi_dev_release, }; -static struct device_type wmi_type_data = { +static const struct device_type wmi_type_data = { .name = "data", .groups = wmi_data_groups, .release = wmi_dev_release, }; static int wmi_create_device(struct device *wmi_bus_dev, - const struct guid_block *gblock, struct wmi_block *wblock, struct acpi_device *device) { @@ -1024,12 +1051,12 @@ char method[5]; int result; - if (gblock->flags & ACPI_WMI_EVENT) { + if (wblock->gblock.flags & ACPI_WMI_EVENT) { wblock->dev.dev.type = &wmi_type_event; goto out_init; } - if (gblock->flags & ACPI_WMI_METHOD) { + if (wblock->gblock.flags & ACPI_WMI_METHOD) { wblock->dev.dev.type = &wmi_type_method; mutex_init(&wblock->char_mutex); goto out_init; @@ -1079,7 +1106,7 @@ wblock->dev.dev.bus = &wmi_bus_type; wblock->dev.dev.parent = wmi_bus_dev; - dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid); + dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid); device_initialize(&wblock->dev.dev); @@ -1099,13 +1126,12 @@ } } -static bool guid_already_parsed(struct acpi_device *device, - const u8 *guid) +static bool guid_already_parsed(struct acpi_device *device, const guid_t *guid) { struct wmi_block *wblock; list_for_each_entry(wblock, &wmi_block_list, list) { - if (memcmp(wblock->gblock.guid, guid, 16) == 0) { + if (guid_equal(&wblock->gblock.guid, guid)) { /* * Because we historically didn't track the relationship * between GUIDs and ACPI nodes, we don't know whether @@ -1160,7 +1186,7 @@ * case yet, so for now, we'll just ignore the duplicate * for device creation. */ - if (guid_already_parsed(device, gblock[i].guid)) + if (guid_already_parsed(device, &gblock[i].guid)) continue; wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); @@ -1172,7 +1198,7 @@ wblock->acpi_device = device; wblock->gblock = gblock[i]; - retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device); + retval = wmi_create_device(wmi_bus_dev, wblock, device); if (retval) { kfree(wblock); continue; @@ -1197,7 +1223,7 @@ retval = device_add(&wblock->dev.dev); if (retval) { dev_err(wmi_bus_dev, "failed to register %pUL\n", - wblock->gblock.guid); + &wblock->gblock.guid); if (debug_event) wmi_method_enable(wblock, 0); list_del(&wblock->list); @@ -1257,12 +1283,11 @@ static void acpi_wmi_notify_handler(acpi_handle handle, u32 event, void *context) { - struct guid_block *block; struct wmi_block *wblock; bool found_it = false; list_for_each_entry(wblock, &wmi_block_list, list) { - block = &wblock->gblock; + struct guid_block *block = &wblock->gblock; if (wblock->acpi_device->handle == handle && (block->flags & ACPI_WMI_EVENT) && @@ -1310,10 +1335,8 @@ wblock->handler(event, wblock->handler_data); } - if (debug_event) { - pr_info("DEBUG Event GUID: %pUL\n", - wblock->gblock.guid); - } + if (debug_event) + pr_info("DEBUG Event GUID: %pUL\n", &wblock->gblock.guid); acpi_bus_generate_netlink_event( wblock->acpi_device->pnp.device_class, -- Gitblit v1.6.2