[PATCH 8/9] platform/x86: lenovo-wmi-helpers: Adopt new WMI API

From: Rong Zhang

Date: Sun Sep 13 2026 - 16:54:14 EST


The new WMI API supports multiple ACPI types by converting them into a
unified buffer that satisfies alignment and size requirements.

Adopt it to make our life easier.

Note that the Windows WMI-ACPI driver converts all ACPI objects into a
common buffer format, so adopting the new API intentionally accepts more
ACPI types as a followup of commit 465dc9da8ff6 ("platform/x86:
lenovo-wmi-helpers: Convert returned buffer into u32").

Suggested-by: Armin Wolf <W_Armin@xxxxxx>
Link: https://lore.kernel.org/r/f1787927-b655-4321-b9d9-bc12353c72db@xxxxxx/
Signed-off-by: Rong Zhang <i@xxxxxxxx>
---
drivers/platform/x86/lenovo/wmi-helpers.c | 61 ++++++++++++-------------------
1 file changed, 23 insertions(+), 38 deletions(-)

diff --git a/drivers/platform/x86/lenovo/wmi-helpers.c b/drivers/platform/x86/lenovo/wmi-helpers.c
index 8f5766c391eb..687caa226263 100644
--- a/drivers/platform/x86/lenovo/wmi-helpers.c
+++ b/drivers/platform/x86/lenovo/wmi-helpers.c
@@ -24,9 +24,10 @@
#include <linux/export.h>
#include <linux/module.h>
#include <linux/notifier.h>
-#include <linux/unaligned.h>
#include <linux/wmi.h>

+#include <asm/byteorder.h>
+
#include "wmi-helpers.h"

/* Thermal mode notifier chain. */
@@ -42,49 +43,33 @@ static BLOCKING_NOTIFIER_HEAD(tm_chain_head);
* @size: Length of the buffer.
* @retval: Pointer for the return value to be assigned.
*
- * Calls wmidev_evaluate_method for Lenovo WMI devices that return an ACPI
- * integer. Validates the return value type and assigns the value to the
- * retval pointer.
+ * Calls the specified WMI method for Lenovo WMI devices that return a WMI
+ * integer. Validates the return value and assigns it to @retval when it's not
+ * NULL, otherwise the return value is not validated.
*
* Return: 0 on success, or an error code.
*/
int lwmi_dev_evaluate_int(struct wmi_device *wdev, u8 instance, u32 method_id,
unsigned char *buf, size_t size, u32 *retval)
{
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_buffer input = { size, buf };
- acpi_status status;
-
- status = wmidev_evaluate_method(wdev, instance, method_id, &input,
- &output);
- if (ACPI_FAILURE(status))
- return -EIO;
-
- union acpi_object *ret_obj __free(kfree) = output.pointer;
-
- if (retval) {
- if (!ret_obj)
- return -ENODATA;
-
- switch (ret_obj->type) {
- /*
- * The ACPI method may simply return a buffer when a u32
- * is expected. This is valid on Windows as its WMI-ACPI
- * driver converts everything to a common buffer.
- */
- case ACPI_TYPE_BUFFER:
- if (ret_obj->buffer.length < sizeof(u32))
- return -ENXIO;
-
- *retval = get_unaligned_le32(ret_obj->buffer.pointer);
- return 0;
- case ACPI_TYPE_INTEGER:
- *retval = (u32)ret_obj->integer.value;
- return 0;
- default:
- return -ENXIO;
- }
- }
+ struct wmi_buffer input = {
+ .length = size,
+ .data = buf,
+ };
+ struct wmi_buffer output;
+ int ret;
+
+ if (!retval)
+ return wmidev_invoke_procedure(wdev, instance, method_id, &input);
+
+ ret = wmidev_invoke_method(wdev, instance, method_id, &input,
+ &output, sizeof(__le32));
+ if (ret)
+ return ret;
+
+ __le32 *valp __free(kfree) = output.data;
+
+ *retval = le32_to_cpu(*valp);

return 0;
};

--
2.55.0