Commit b27ea279 authored by Armin Wolf's avatar Armin Wolf Committed by Hans de Goede

platform/x86: lg-laptop: Use ACPI device handle when evaluating WMAB/WMBB

On the LG Gram 16Z90S, the WMAB and WMBB ACPI methods are not mapped
under \XINI, but instead are mapped under \_SB.XINI.

The reason for this is that the LGEX0820 ACPI device used by this
driver is mapped at \_SB.XINI, so the ACPI methods where moved as well
to appear below the LGEX0820 ACPI device.

Fix this by using the ACPI handle from the ACPI device when evaluating
both methods.

Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218901Tested-by: default avatarAgathe Boutmy <agathe@boutmy.com>
Signed-off-by: default avatarArmin Wolf <W_Armin@gmx.de>
Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20240606233540.9774-5-W_Armin@gmx.deReviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent 58a54f27
...@@ -39,8 +39,6 @@ MODULE_LICENSE("GPL"); ...@@ -39,8 +39,6 @@ MODULE_LICENSE("GPL");
#define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210" #define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210"
#define WMI_EVENT_GUID WMI_EVENT_GUID0 #define WMI_EVENT_GUID WMI_EVENT_GUID0
#define WMAB_METHOD "\\XINI.WMAB"
#define WMBB_METHOD "\\XINI.WMBB"
#define SB_GGOV_METHOD "\\_SB.GGOV" #define SB_GGOV_METHOD "\\_SB.GGOV"
#define GOV_TLED 0x2020008 #define GOV_TLED 0x2020008
#define WM_GET 1 #define WM_GET 1
...@@ -74,7 +72,7 @@ static u32 inited; ...@@ -74,7 +72,7 @@ static u32 inited;
static int battery_limit_use_wmbb; static int battery_limit_use_wmbb;
static struct led_classdev kbd_backlight; static struct led_classdev kbd_backlight;
static enum led_brightness get_kbd_backlight_level(void); static enum led_brightness get_kbd_backlight_level(struct device *dev);
static const struct key_entry wmi_keymap[] = { static const struct key_entry wmi_keymap[] = {
{KE_KEY, 0x70, {KEY_F15} }, /* LG control panel (F1) */ {KE_KEY, 0x70, {KEY_F15} }, /* LG control panel (F1) */
...@@ -127,11 +125,10 @@ static int ggov(u32 arg0) ...@@ -127,11 +125,10 @@ static int ggov(u32 arg0)
return res; return res;
} }
static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2) static union acpi_object *lg_wmab(struct device *dev, u32 method, u32 arg1, u32 arg2)
{ {
union acpi_object args[3]; union acpi_object args[3];
acpi_status status; acpi_status status;
acpi_handle handle;
struct acpi_object_list arg; struct acpi_object_list arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
...@@ -142,29 +139,22 @@ static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2) ...@@ -142,29 +139,22 @@ static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2)
args[2].type = ACPI_TYPE_INTEGER; args[2].type = ACPI_TYPE_INTEGER;
args[2].integer.value = arg2; args[2].integer.value = arg2;
status = acpi_get_handle(NULL, (acpi_string) WMAB_METHOD, &handle);
if (ACPI_FAILURE(status)) {
pr_err("Cannot get handle");
return NULL;
}
arg.count = 3; arg.count = 3;
arg.pointer = args; arg.pointer = args;
status = acpi_evaluate_object(handle, NULL, &arg, &buffer); status = acpi_evaluate_object(ACPI_HANDLE(dev), "WMAB", &arg, &buffer);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_handle_err(handle, "WMAB: call failed.\n"); dev_err(dev, "WMAB: call failed.\n");
return NULL; return NULL;
} }
return buffer.pointer; return buffer.pointer;
} }
static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2) static union acpi_object *lg_wmbb(struct device *dev, u32 method_id, u32 arg1, u32 arg2)
{ {
union acpi_object args[3]; union acpi_object args[3];
acpi_status status; acpi_status status;
acpi_handle handle;
struct acpi_object_list arg; struct acpi_object_list arg;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
u8 buf[32]; u8 buf[32];
...@@ -180,18 +170,12 @@ static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2) ...@@ -180,18 +170,12 @@ static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2)
args[2].buffer.length = 32; args[2].buffer.length = 32;
args[2].buffer.pointer = buf; args[2].buffer.pointer = buf;
status = acpi_get_handle(NULL, (acpi_string)WMBB_METHOD, &handle);
if (ACPI_FAILURE(status)) {
pr_err("Cannot get handle");
return NULL;
}
arg.count = 3; arg.count = 3;
arg.pointer = args; arg.pointer = args;
status = acpi_evaluate_object(handle, NULL, &arg, &buffer); status = acpi_evaluate_object(ACPI_HANDLE(dev), "WMBB", &arg, &buffer);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_handle_err(handle, "WMAB: call failed.\n"); dev_err(dev, "WMBB: call failed.\n");
return NULL; return NULL;
} }
...@@ -222,7 +206,7 @@ static void wmi_notify(u32 value, void *context) ...@@ -222,7 +206,7 @@ static void wmi_notify(u32 value, void *context)
if (eventcode == 0x10000000) { if (eventcode == 0x10000000) {
led_classdev_notify_brightness_hw_changed( led_classdev_notify_brightness_hw_changed(
&kbd_backlight, get_kbd_backlight_level()); &kbd_backlight, get_kbd_backlight_level(kbd_backlight.dev->parent));
} else { } else {
key = sparse_keymap_entry_from_scancode( key = sparse_keymap_entry_from_scancode(
wmi_input_dev, eventcode); wmi_input_dev, eventcode);
...@@ -287,7 +271,7 @@ static ssize_t fan_mode_store(struct device *dev, ...@@ -287,7 +271,7 @@ static ssize_t fan_mode_store(struct device *dev,
if (ret) if (ret)
return ret; return ret;
r = lg_wmab(WM_FAN_MODE, WM_GET, 0); r = lg_wmab(dev, WM_FAN_MODE, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -298,9 +282,9 @@ static ssize_t fan_mode_store(struct device *dev, ...@@ -298,9 +282,9 @@ static ssize_t fan_mode_store(struct device *dev,
m = r->integer.value; m = r->integer.value;
kfree(r); kfree(r);
r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4)); r = lg_wmab(dev, WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4));
kfree(r); kfree(r);
r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value); r = lg_wmab(dev, WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value);
kfree(r); kfree(r);
return count; return count;
...@@ -312,7 +296,7 @@ static ssize_t fan_mode_show(struct device *dev, ...@@ -312,7 +296,7 @@ static ssize_t fan_mode_show(struct device *dev,
unsigned int status; unsigned int status;
union acpi_object *r; union acpi_object *r;
r = lg_wmab(WM_FAN_MODE, WM_GET, 0); r = lg_wmab(dev, WM_FAN_MODE, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -339,7 +323,7 @@ static ssize_t usb_charge_store(struct device *dev, ...@@ -339,7 +323,7 @@ static ssize_t usb_charge_store(struct device *dev,
if (ret) if (ret)
return ret; return ret;
r = lg_wmbb(WMBB_USB_CHARGE, WM_SET, value); r = lg_wmbb(dev, WMBB_USB_CHARGE, WM_SET, value);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -353,7 +337,7 @@ static ssize_t usb_charge_show(struct device *dev, ...@@ -353,7 +337,7 @@ static ssize_t usb_charge_show(struct device *dev,
unsigned int status; unsigned int status;
union acpi_object *r; union acpi_object *r;
r = lg_wmbb(WMBB_USB_CHARGE, WM_GET, 0); r = lg_wmbb(dev, WMBB_USB_CHARGE, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -381,7 +365,7 @@ static ssize_t reader_mode_store(struct device *dev, ...@@ -381,7 +365,7 @@ static ssize_t reader_mode_store(struct device *dev,
if (ret) if (ret)
return ret; return ret;
r = lg_wmab(WM_READER_MODE, WM_SET, value); r = lg_wmab(dev, WM_READER_MODE, WM_SET, value);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -395,7 +379,7 @@ static ssize_t reader_mode_show(struct device *dev, ...@@ -395,7 +379,7 @@ static ssize_t reader_mode_show(struct device *dev,
unsigned int status; unsigned int status;
union acpi_object *r; union acpi_object *r;
r = lg_wmab(WM_READER_MODE, WM_GET, 0); r = lg_wmab(dev, WM_READER_MODE, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -423,7 +407,7 @@ static ssize_t fn_lock_store(struct device *dev, ...@@ -423,7 +407,7 @@ static ssize_t fn_lock_store(struct device *dev,
if (ret) if (ret)
return ret; return ret;
r = lg_wmab(WM_FN_LOCK, WM_SET, value); r = lg_wmab(dev, WM_FN_LOCK, WM_SET, value);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -437,7 +421,7 @@ static ssize_t fn_lock_show(struct device *dev, ...@@ -437,7 +421,7 @@ static ssize_t fn_lock_show(struct device *dev,
unsigned int status; unsigned int status;
union acpi_object *r; union acpi_object *r;
r = lg_wmab(WM_FN_LOCK, WM_GET, 0); r = lg_wmab(dev, WM_FN_LOCK, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -467,9 +451,9 @@ static ssize_t charge_control_end_threshold_store(struct device *dev, ...@@ -467,9 +451,9 @@ static ssize_t charge_control_end_threshold_store(struct device *dev,
union acpi_object *r; union acpi_object *r;
if (battery_limit_use_wmbb) if (battery_limit_use_wmbb)
r = lg_wmbb(WMBB_BATT_LIMIT, WM_SET, value); r = lg_wmbb(&pf_device->dev, WMBB_BATT_LIMIT, WM_SET, value);
else else
r = lg_wmab(WM_BATT_LIMIT, WM_SET, value); r = lg_wmab(&pf_device->dev, WM_BATT_LIMIT, WM_SET, value);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -488,7 +472,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device, ...@@ -488,7 +472,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device,
union acpi_object *r; union acpi_object *r;
if (battery_limit_use_wmbb) { if (battery_limit_use_wmbb) {
r = lg_wmbb(WMBB_BATT_LIMIT, WM_GET, 0); r = lg_wmbb(&pf_device->dev, WMBB_BATT_LIMIT, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -499,7 +483,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device, ...@@ -499,7 +483,7 @@ static ssize_t charge_control_end_threshold_show(struct device *device,
status = r->buffer.pointer[0x10]; status = r->buffer.pointer[0x10];
} else { } else {
r = lg_wmab(WM_BATT_LIMIT, WM_GET, 0); r = lg_wmab(&pf_device->dev, WM_BATT_LIMIT, WM_GET, 0);
if (!r) if (!r)
return -EIO; return -EIO;
...@@ -578,7 +562,7 @@ static void tpad_led_set(struct led_classdev *cdev, ...@@ -578,7 +562,7 @@ static void tpad_led_set(struct led_classdev *cdev,
{ {
union acpi_object *r; union acpi_object *r;
r = lg_wmab(WM_TLED, WM_SET, brightness > LED_OFF); r = lg_wmab(cdev->dev->parent, WM_TLED, WM_SET, brightness > LED_OFF);
kfree(r); kfree(r);
} }
...@@ -600,16 +584,16 @@ static void kbd_backlight_set(struct led_classdev *cdev, ...@@ -600,16 +584,16 @@ static void kbd_backlight_set(struct led_classdev *cdev,
val = 0; val = 0;
if (brightness >= LED_FULL) if (brightness >= LED_FULL)
val = 0x24; val = 0x24;
r = lg_wmab(WM_KEY_LIGHT, WM_SET, val); r = lg_wmab(cdev->dev->parent, WM_KEY_LIGHT, WM_SET, val);
kfree(r); kfree(r);
} }
static enum led_brightness get_kbd_backlight_level(void) static enum led_brightness get_kbd_backlight_level(struct device *dev)
{ {
union acpi_object *r; union acpi_object *r;
int val; int val;
r = lg_wmab(WM_KEY_LIGHT, WM_GET, 0); r = lg_wmab(dev, WM_KEY_LIGHT, WM_GET, 0);
if (!r) if (!r)
return LED_OFF; return LED_OFF;
...@@ -637,7 +621,7 @@ static enum led_brightness get_kbd_backlight_level(void) ...@@ -637,7 +621,7 @@ static enum led_brightness get_kbd_backlight_level(void)
static enum led_brightness kbd_backlight_get(struct led_classdev *cdev) static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
{ {
return get_kbd_backlight_level(); return get_kbd_backlight_level(cdev->dev->parent);
} }
static LED_DEVICE(kbd_backlight, 255, LED_BRIGHT_HW_CHANGED); static LED_DEVICE(kbd_backlight, 255, LED_BRIGHT_HW_CHANGED);
...@@ -664,6 +648,11 @@ static struct platform_driver pf_driver = { ...@@ -664,6 +648,11 @@ static struct platform_driver pf_driver = {
static int acpi_add(struct acpi_device *device) static int acpi_add(struct acpi_device *device)
{ {
struct platform_device_info pdev_info = {
.fwnode = acpi_fwnode_handle(device),
.name = PLATFORM_NAME,
.id = PLATFORM_DEVID_NONE,
};
int ret; int ret;
const char *product; const char *product;
int year = 2017; int year = 2017;
...@@ -675,9 +664,7 @@ static int acpi_add(struct acpi_device *device) ...@@ -675,9 +664,7 @@ static int acpi_add(struct acpi_device *device)
if (ret) if (ret)
return ret; return ret;
pf_device = platform_device_register_simple(PLATFORM_NAME, pf_device = platform_device_register_full(&pdev_info);
PLATFORM_DEVID_NONE,
NULL, 0);
if (IS_ERR(pf_device)) { if (IS_ERR(pf_device)) {
ret = PTR_ERR(pf_device); ret = PTR_ERR(pf_device);
pf_device = NULL; pf_device = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment