Skip to content

Commit c7138f7

Browse files
committed
Merge tag 'platform-drivers-x86-v6.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform driver fixes from Hans de Goede: "Regression fixes: - Fix INT0002 vGPIO events no longer working after 6.8 ACPI SCI changes - AMD-PMF: Fix laptops (e.g. Framework 13 AMD) hanging on suspend - x86-android-tablets: Fix touchscreen no longer working on Lenovo Yogabook - x86-android-tablets: Fix serdev instantiation regression - intel-vbtn: Fix ThinkPad X1 Tablet Gen2 no longer suspending Bug fixes: - think-lmi: Fix changing BIOS settings on Lenovo workstations - touchscreen_dmi: Fix Hi8 Air touchscreen data sometimes missing - AMD-PMF: Fix Smart PC support not working after suspend/resume Other misc small fixes" * tag 'platform-drivers-x86-v6.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: platform/x86: thinkpad_acpi: Only update profile if successfully converted platform/x86: intel-vbtn: Stop calling "VBDL" from notify_handler platform/x86: x86-android-tablets: Fix acer_b1_750_goodix_gpios name platform/x86: x86-android-tablets: Fix serdev instantiation no longer working platform/x86: Add new get_serdev_controller() helper platform/x86: x86-android-tablets: Fix keyboard touchscreen on Lenovo Yogabook1 X90 platform/x86/amd/pmf: Fix a potential race with policy binary sideload platform/x86/amd/pmf: Fixup error handling for amd_pmf_init_smart_pc() platform/x86/amd/pmf: Add debugging message for missing policy data platform/x86/amd/pmf: Fix a suspend hang on Framework 13 platform/x86/amd/pmf: Fix TEE enact command failure after suspend and resume platform/x86/amd/pmf: Remove smart_pc_status enum platform/x86: touchscreen_dmi: Consolidate Goodix upside-down touchscreen data platform/x86: touchscreen_dmi: Allow partial (prefix) matches for ACPI names platform/x86: intel: int0002_vgpio: Pass IRQF_ONESHOT to request_irq() platform/x86: think-lmi: Fix password opcode ordering for workstations
2 parents 8895376 + 427c70d commit c7138f7

File tree

13 files changed

+182
-97
lines changed

13 files changed

+182
-97
lines changed

drivers/platform/x86/amd/pmf/core.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ static int amd_pmf_suspend_handler(struct device *dev)
296296
{
297297
struct amd_pmf_dev *pdev = dev_get_drvdata(dev);
298298

299-
kfree(pdev->buf);
299+
if (pdev->smart_pc_enabled)
300+
cancel_delayed_work_sync(&pdev->pb_work);
300301

301302
return 0;
302303
}
@@ -312,6 +313,9 @@ static int amd_pmf_resume_handler(struct device *dev)
312313
return ret;
313314
}
314315

316+
if (pdev->smart_pc_enabled)
317+
schedule_delayed_work(&pdev->pb_work, msecs_to_jiffies(2000));
318+
315319
return 0;
316320
}
317321

@@ -330,9 +334,14 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev)
330334
dev_dbg(dev->dev, "SPS enabled and Platform Profiles registered\n");
331335
}
332336

333-
if (!amd_pmf_init_smart_pc(dev)) {
337+
amd_pmf_init_smart_pc(dev);
338+
if (dev->smart_pc_enabled) {
334339
dev_dbg(dev->dev, "Smart PC Solution Enabled\n");
335-
} else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
340+
/* If Smart PC is enabled, no need to check for other features */
341+
return;
342+
}
343+
344+
if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
336345
amd_pmf_init_auto_mode(dev);
337346
dev_dbg(dev->dev, "Auto Mode Init done\n");
338347
} else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) ||
@@ -351,7 +360,7 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev)
351360
amd_pmf_deinit_sps(dev);
352361
}
353362

354-
if (!dev->smart_pc_enabled) {
363+
if (dev->smart_pc_enabled) {
355364
amd_pmf_deinit_smart_pc(dev);
356365
} else if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) {
357366
amd_pmf_deinit_auto_mode(dev);

drivers/platform/x86/amd/pmf/pmf.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,6 @@ struct apmf_dyn_slider_output {
441441
struct apmf_cnqf_power_set ps[APMF_CNQF_MAX];
442442
} __packed;
443443

444-
enum smart_pc_status {
445-
PMF_SMART_PC_ENABLED,
446-
PMF_SMART_PC_DISABLED,
447-
};
448-
449444
/* Smart PC - TA internals */
450445
enum system_state {
451446
SYSTEM_STATE_S0i3,

drivers/platform/x86/amd/pmf/tee-if.c

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -252,23 +252,25 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev *dev)
252252
cookie = readl(dev->policy_buf + POLICY_COOKIE_OFFSET);
253253
length = readl(dev->policy_buf + POLICY_COOKIE_LEN);
254254

255-
if (cookie != POLICY_SIGN_COOKIE || !length)
255+
if (cookie != POLICY_SIGN_COOKIE || !length) {
256+
dev_dbg(dev->dev, "cookie doesn't match\n");
256257
return -EINVAL;
258+
}
257259

258260
/* Update the actual length */
259261
dev->policy_sz = length + 512;
260262
res = amd_pmf_invoke_cmd_init(dev);
261263
if (res == TA_PMF_TYPE_SUCCESS) {
262264
/* Now its safe to announce that smart pc is enabled */
263-
dev->smart_pc_enabled = PMF_SMART_PC_ENABLED;
265+
dev->smart_pc_enabled = true;
264266
/*
265267
* Start collecting the data from TA FW after a small delay
266268
* or else, we might end up getting stale values.
267269
*/
268270
schedule_delayed_work(&dev->pb_work, msecs_to_jiffies(pb_actions_ms * 3));
269271
} else {
270272
dev_err(dev->dev, "ta invoke cmd init failed err: %x\n", res);
271-
dev->smart_pc_enabled = PMF_SMART_PC_DISABLED;
273+
dev->smart_pc_enabled = false;
272274
return res;
273275
}
274276

@@ -336,25 +338,6 @@ static void amd_pmf_remove_pb(struct amd_pmf_dev *dev) {}
336338
static void amd_pmf_hex_dump_pb(struct amd_pmf_dev *dev) {}
337339
#endif
338340

339-
static int amd_pmf_get_bios_buffer(struct amd_pmf_dev *dev)
340-
{
341-
dev->policy_buf = kzalloc(dev->policy_sz, GFP_KERNEL);
342-
if (!dev->policy_buf)
343-
return -ENOMEM;
344-
345-
dev->policy_base = devm_ioremap(dev->dev, dev->policy_addr, dev->policy_sz);
346-
if (!dev->policy_base)
347-
return -ENOMEM;
348-
349-
memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
350-
351-
amd_pmf_hex_dump_pb(dev);
352-
if (pb_side_load)
353-
amd_pmf_open_pb(dev, dev->dbgfs_dir);
354-
355-
return amd_pmf_start_policy_engine(dev);
356-
}
357-
358341
static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const void *data)
359342
{
360343
return ver->impl_id == TEE_IMPL_ID_AMDTEE;
@@ -453,22 +436,57 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
453436
return ret;
454437

455438
INIT_DELAYED_WORK(&dev->pb_work, amd_pmf_invoke_cmd);
456-
amd_pmf_set_dram_addr(dev, true);
457-
amd_pmf_get_bios_buffer(dev);
439+
440+
ret = amd_pmf_set_dram_addr(dev, true);
441+
if (ret)
442+
goto error;
443+
444+
dev->policy_base = devm_ioremap(dev->dev, dev->policy_addr, dev->policy_sz);
445+
if (!dev->policy_base) {
446+
ret = -ENOMEM;
447+
goto error;
448+
}
449+
450+
dev->policy_buf = kzalloc(dev->policy_sz, GFP_KERNEL);
451+
if (!dev->policy_buf) {
452+
ret = -ENOMEM;
453+
goto error;
454+
}
455+
456+
memcpy(dev->policy_buf, dev->policy_base, dev->policy_sz);
457+
458+
amd_pmf_hex_dump_pb(dev);
459+
458460
dev->prev_data = kzalloc(sizeof(*dev->prev_data), GFP_KERNEL);
459461
if (!dev->prev_data)
460-
return -ENOMEM;
462+
goto error;
463+
464+
ret = amd_pmf_start_policy_engine(dev);
465+
if (ret)
466+
goto error;
461467

462-
return dev->smart_pc_enabled;
468+
if (pb_side_load)
469+
amd_pmf_open_pb(dev, dev->dbgfs_dir);
470+
471+
return 0;
472+
473+
error:
474+
amd_pmf_deinit_smart_pc(dev);
475+
476+
return ret;
463477
}
464478

465479
void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev)
466480
{
467-
if (pb_side_load)
481+
if (pb_side_load && dev->esbin)
468482
amd_pmf_remove_pb(dev);
469483

484+
cancel_delayed_work_sync(&dev->pb_work);
470485
kfree(dev->prev_data);
486+
dev->prev_data = NULL;
471487
kfree(dev->policy_buf);
472-
cancel_delayed_work_sync(&dev->pb_work);
488+
dev->policy_buf = NULL;
489+
kfree(dev->buf);
490+
dev->buf = NULL;
473491
amd_pmf_tee_deinit(dev);
474492
}

drivers/platform/x86/intel/int0002_vgpio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ static int int0002_probe(struct platform_device *pdev)
196196
* IRQs into gpiolib.
197197
*/
198198
ret = devm_request_irq(dev, irq, int0002_irq,
199-
IRQF_SHARED, "INT0002", chip);
199+
IRQF_ONESHOT | IRQF_SHARED, "INT0002", chip);
200200
if (ret) {
201201
dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret);
202202
return ret;

drivers/platform/x86/intel/vbtn.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,6 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
200200
autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE);
201201

202202
sparse_keymap_report_event(input_dev, event, val, autorelease);
203-
204-
/* Some devices need this to report further events */
205-
acpi_evaluate_object(handle, "VBDL", NULL, NULL);
206203
}
207204

208205
/*

drivers/platform/x86/serdev_helpers.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
/*
3+
* In some cases UART attached devices which require an in kernel driver,
4+
* e.g. UART attached Bluetooth HCIs are described in the ACPI tables
5+
* by an ACPI device with a broken or missing UartSerialBusV2() resource.
6+
*
7+
* This causes the kernel to create a /dev/ttyS# char-device for the UART
8+
* instead of creating an in kernel serdev-controller + serdev-device pair
9+
* for the in kernel driver.
10+
*
11+
* The quirk handling in acpi_quirk_skip_serdev_enumeration() makes the kernel
12+
* create a serdev-controller device for these UARTs instead of a /dev/ttyS#.
13+
*
14+
* Instantiating the actual serdev-device to bind to is up to pdx86 code,
15+
* this header provides a helper for getting the serdev-controller device.
16+
*/
17+
#include <linux/acpi.h>
18+
#include <linux/device.h>
19+
#include <linux/err.h>
20+
#include <linux/printk.h>
21+
#include <linux/sprintf.h>
22+
#include <linux/string.h>
23+
24+
static inline struct device *
25+
get_serdev_controller(const char *serial_ctrl_hid,
26+
const char *serial_ctrl_uid,
27+
int serial_ctrl_port,
28+
const char *serdev_ctrl_name)
29+
{
30+
struct device *ctrl_dev, *child;
31+
struct acpi_device *ctrl_adev;
32+
char name[32];
33+
int i;
34+
35+
ctrl_adev = acpi_dev_get_first_match_dev(serial_ctrl_hid, serial_ctrl_uid, -1);
36+
if (!ctrl_adev) {
37+
pr_err("error could not get %s/%s serial-ctrl adev\n",
38+
serial_ctrl_hid, serial_ctrl_uid);
39+
return ERR_PTR(-ENODEV);
40+
}
41+
42+
/* get_first_physical_node() returns a weak ref */
43+
ctrl_dev = get_device(acpi_get_first_physical_node(ctrl_adev));
44+
if (!ctrl_dev) {
45+
pr_err("error could not get %s/%s serial-ctrl physical node\n",
46+
serial_ctrl_hid, serial_ctrl_uid);
47+
ctrl_dev = ERR_PTR(-ENODEV);
48+
goto put_ctrl_adev;
49+
}
50+
51+
/* Walk host -> uart-ctrl -> port -> serdev-ctrl */
52+
for (i = 0; i < 3; i++) {
53+
switch (i) {
54+
case 0:
55+
snprintf(name, sizeof(name), "%s:0", dev_name(ctrl_dev));
56+
break;
57+
case 1:
58+
snprintf(name, sizeof(name), "%s.%d",
59+
dev_name(ctrl_dev), serial_ctrl_port);
60+
break;
61+
case 2:
62+
strscpy(name, serdev_ctrl_name, sizeof(name));
63+
break;
64+
}
65+
66+
child = device_find_child_by_name(ctrl_dev, name);
67+
put_device(ctrl_dev);
68+
if (!child) {
69+
pr_err("error could not find '%s' device\n", name);
70+
ctrl_dev = ERR_PTR(-ENODEV);
71+
goto put_ctrl_adev;
72+
}
73+
74+
ctrl_dev = child;
75+
}
76+
77+
put_ctrl_adev:
78+
acpi_dev_put(ctrl_adev);
79+
return ctrl_dev;
80+
}

drivers/platform/x86/think-lmi.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,16 @@ static ssize_t current_value_store(struct kobject *kobj,
10091009
* Note - this sets the variable and then the password as separate
10101010
* WMI calls. Function tlmi_save_bios_settings will error if the
10111011
* password is incorrect.
1012+
* Workstation's require the opcode to be set before changing the
1013+
* attribute.
10121014
*/
1015+
if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
1016+
ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
1017+
tlmi_priv.pwd_admin->password);
1018+
if (ret)
1019+
goto out;
1020+
}
1021+
10131022
set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
10141023
new_setting);
10151024
if (!set_str) {
@@ -1021,17 +1030,10 @@ static ssize_t current_value_store(struct kobject *kobj,
10211030
if (ret)
10221031
goto out;
10231032

1024-
if (tlmi_priv.save_mode == TLMI_SAVE_BULK) {
1033+
if (tlmi_priv.save_mode == TLMI_SAVE_BULK)
10251034
tlmi_priv.save_required = true;
1026-
} else {
1027-
if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
1028-
ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
1029-
tlmi_priv.pwd_admin->password);
1030-
if (ret)
1031-
goto out;
1032-
}
1035+
else
10331036
ret = tlmi_save_bios_settings("");
1034-
}
10351037
} else { /* old non-opcode based authentication method (deprecated) */
10361038
if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
10371039
auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",

drivers/platform/x86/thinkpad_acpi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10308,6 +10308,7 @@ static int convert_dytc_to_profile(int funcmode, int dytcmode,
1030810308
return 0;
1030910309
default:
1031010310
/* Unknown function */
10311+
pr_debug("unknown function 0x%x\n", funcmode);
1031110312
return -EOPNOTSUPP;
1031210313
}
1031310314
return 0;
@@ -10493,8 +10494,8 @@ static void dytc_profile_refresh(void)
1049310494
return;
1049410495

1049510496
perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF;
10496-
convert_dytc_to_profile(funcmode, perfmode, &profile);
10497-
if (profile != dytc_current_profile) {
10497+
err = convert_dytc_to_profile(funcmode, perfmode, &profile);
10498+
if (!err && profile != dytc_current_profile) {
1049810499
dytc_current_profile = profile;
1049910500
platform_profile_notify();
1050010501
}

0 commit comments

Comments
 (0)