mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
platform/x86: lenovo-wmi-helpers: Adopt new WMI API
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 465dc9da8f ("platform/x86:
lenovo-wmi-helpers: Convert returned buffer into u32").
Suggested-by: Armin Wolf <W_Armin@gmx.de>
Link: https://lore.kernel.org/r/f1787927-b655-4321-b9d9-bc12353c72db@gmx.de/
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Tested-by: Navon John Lukose <navonjohnlukose@gmail.com>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20261019-lwmi-wmi-new-api-v5-11-71557d28d058@rong.moe
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
This commit is contained in:
parent
1e99760fb0
commit
87a7c09a9d
|
|
@ -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;
|
||||
struct wmi_buffer input = {
|
||||
.length = size,
|
||||
.data = buf,
|
||||
};
|
||||
struct wmi_buffer output;
|
||||
int ret;
|
||||
|
||||
status = wmidev_evaluate_method(wdev, instance, method_id, &input,
|
||||
&output);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EIO;
|
||||
if (!retval)
|
||||
return wmidev_invoke_procedure(wdev, instance, method_id, &input);
|
||||
|
||||
union acpi_object *ret_obj __free(kfree) = output.pointer;
|
||||
ret = wmidev_invoke_method(wdev, instance, method_id, &input,
|
||||
&output, sizeof(__le32));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (retval) {
|
||||
if (!ret_obj)
|
||||
return -ENODATA;
|
||||
__le32 *valp __free(kfree) = output.data;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
*retval = le32_to_cpu(*valp);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user