Message ID | 35811fe2-7aac-aa3c-46dc-2bef515b0f47@gmail.com (mailing list archive) |
---|---|
State | Accepted, archived |
Delegated to: | Andy Shevchenko |
Headers | show |
Series | Support of ASUS TUF Gaming series laptops | expand |
On Tue, May 14, 2019 at 12:59 PM Yurii Pavlovskyi <yurii.pavlovskyi@gmail.com> wrote: > > Add a new function to acpi.h / wmi.c that returns _UID of the ACPI WMI > device. For example, it returns "ATK" for the following declaration in > DSDT: > Device (ATKD) > { > Name (_HID, "PNP0C14" /* Windows Management Instrumentation Device */) > // _HID: Hardware ID > Name (_UID, "ATK") // _UID: Unique ID > .. > > Generally, it is possible that multiple PNP0C14 ACPI devices are present in > the system as mentioned in the commit message of commit bff431e49ff5 > ("ACPI: WMI: Add ACPI-WMI mapping driver"). > > Therefore the _UID is returned for a specific ACPI device that declares the > given GUID, to which it is also mapped by other methods of wmi module. > > Signed-off-by: Yurii Pavlovskyi <yurii.pavlovskyi@gmail.com> Some extra background may be useful when reviewing this. As researched in https://marc.info/?l=linux-kernel&m=155498017207933&w=2, we are dealing with a tricky situation. asus-wmi currently serves two different classes of device: eeepci-wmi and asus-nb-wmi. The eeepci devices have: _WDG : includes a METHOD block with GUID ASUS_WMI_MGMT_GUID, and an EVENT block with GUID EEEPC_WMI_EVENT_GUID _UID : ASUSWMI The asus-nb-wmi devices have: _ WDG : includes a METHOD block with GUID ASUS_WMI_MGMT_GUID (same as eeepc), and an EVENT block with GUID ASUS_NB_WMI_EVENT_GUID _UID : ATK To support new devices we now need to start concretely identifying which of these we are working with. But complications include: - The main MGMT_GUID used for matching at the moment is shared over both device types - Some Asus products have both of these (via two separate two separate PNP0C14 WMI devices). Currently eeepci-wmi and asus-nb-wmi register themselves with asus-wmi, which registers a platform device for each one. The platform dev probe then succeeds the platform device probe when it finds any _WDG entry for the main MGMT_GUID and the _WDG entry for the corresponding event GUID (not necessarily as part of the same underlying ACPI Device). In the case of both devices being present with duplicate MGMT, the first one that is parsed wins, and the other is ignored (see guid_already_parsed()). Sticking with the current approach, which is imperfect for devices that have both devices, adding a method to detect the _UID seems reasonable. Although actually I just realised you could probably also detect the difference by using wmi_has_guid() on the EVENT UUID without having to add a new function. I'll keep thinking about how to improve the situation around two devices present (but don't want to needlessly conflate this patch series with that). Daniel
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 7b26b6ccf1a0..b08ffb769cbe 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -635,6 +635,25 @@ bool wmi_has_guid(const char *guid_string) } 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); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d5dcebd7aad3..d31c7fd66f97 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -376,6 +376,7 @@ extern acpi_status wmi_install_notify_handler(const char *guid, extern acpi_status wmi_remove_notify_handler(const char *guid); extern acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out); extern bool wmi_has_guid(const char *guid); +extern char *wmi_get_acpi_device_uid(const char *guid); #endif /* CONFIG_ACPI_WMI */
Add a new function to acpi.h / wmi.c that returns _UID of the ACPI WMI device. For example, it returns "ATK" for the following declaration in DSDT: Device (ATKD) { Name (_HID, "PNP0C14" /* Windows Management Instrumentation Device */) // _HID: Hardware ID Name (_UID, "ATK") // _UID: Unique ID .. Generally, it is possible that multiple PNP0C14 ACPI devices are present in the system as mentioned in the commit message of commit bff431e49ff5 ("ACPI: WMI: Add ACPI-WMI mapping driver"). Therefore the _UID is returned for a specific ACPI device that declares the given GUID, to which it is also mapped by other methods of wmi module. Signed-off-by: Yurii Pavlovskyi <yurii.pavlovskyi@gmail.com> --- drivers/platform/x86/wmi.c | 19 +++++++++++++++++++ include/linux/acpi.h | 1 + 2 files changed, 20 insertions(+)