From 08c9f4029007325e0bbd4fdda05650b03e43f071 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Sun, 16 Feb 2025 20:32:50 +0100 Subject: [PATCH] platform/x86: wmi: Call WCxx methods when setting data blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After performing some tests with a custom SSDT table available at https://github.com/Wer-Wolf/acpi-wmi-ssdt i found out that Windows also enables data block collection even when the data block is being set. Emulate this behaviour to avoid confusing the ACPI firmware. The bus-based API already implements this behaviour, so only the legacy GUID-based API needs to be changed. Signed-off-by: Armin Wolf Link: https://lore.kernel.org/r/20250216193251.866125-8-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- Documentation/wmi/acpi-interface.rst | 3 +++ drivers/platform/x86/wmi.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/Documentation/wmi/acpi-interface.rst b/Documentation/wmi/acpi-interface.rst index 06fb7fcf44134..f1b28835d23ce 100644 --- a/Documentation/wmi/acpi-interface.rst +++ b/Documentation/wmi/acpi-interface.rst @@ -89,6 +89,9 @@ Similar to the ``WExx`` ACPI methods, except that it controls data collection instead of events and thus the last two characters of the ACPI method name are the method ID of the data block to enable/disable. +Those ACPI methods are also called before setting data blocks to match the +behaviour of the Windows driver. + _WED ACPI method ---------------- diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 9377c5e6ba6fb..e46453750d5f1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -463,7 +463,14 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance, const struct acp if (IS_ERR(wdev)) return AE_ERROR; + if (wmi_device_enable(wdev, true) < 0) + dev_warn(&wdev->dev, "Failed to enable device\n"); + status = wmidev_block_set(wdev, instance, in); + + if (wmi_device_enable(wdev, false) < 0) + dev_warn(&wdev->dev, "Failed to disable device\n"); + wmi_device_put(wdev); return status;