Skip to content

Commit a0a4df6

Browse files
committed
Merge tag 'platform-drivers-x86-v5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform drivers fixes from Hans de Goede: "A set of bug-fixes and some model specific quirks. Summary: - dell-wmi-sysman: A set of probe-error-exit-handling fixes to fix some systems which advertise the WMI GUIDs, but are not compatible, not booting - intel-vbtn/intel-hid: Misc. bugfixes - intel_pmc: Bug-fixes + a quirk to lower suspend power-consumption on Tiger Lake - thinkpad_acpi: misc bugfixes" * tag 'platform-drivers-x86-v5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: platform/x86: intel_pmc_core: Ignore GBE LTR on Tiger Lake platforms platform/x86: intel_pmc_core: Update Kconfig platform/x86: intel_pmt_crashlog: Fix incorrect macros platform/x86: intel_pmt_class: Initial resource to 0 platform/x86: intel-vbtn: Stop reporting SW_DOCK events platform/x86: dell-wmi-sysman: Cleanup create_attributes_level_sysfs_files() platform/x86: dell-wmi-sysman: Make sysman_init() return -ENODEV of the interfaces are not found platform/x86: dell-wmi-sysman: Cleanup sysman_init() error-exit handling platform/x86: dell-wmi-sysman: Fix release_attributes_data() getting called twice on init_bios_attributes() failure platform/x86: dell-wmi-sysman: Make it safe to call exit_foo_attributes() multiple times platform/x86: dell-wmi-sysman: Fix possible NULL pointer deref on exit platform/x86: dell-wmi-sysman: Fix crash caused by calling kset_unregister twice platform/x86: thinkpad_acpi: Disable DYTC CQL mode around switching to balanced mode platform/x86: thinkpad_acpi: Allow the FnLock LED to change state platform/x86: thinkpad_acpi: check dytc version for lapmode sysfs platform/x86: intel-hid: Support Lenovo ThinkPad X1 Tablet Gen 2
2 parents 8a9d2e1 + d163544 commit a0a4df6

12 files changed

Lines changed: 190 additions & 109 deletions

File tree

drivers/platform/x86/Kconfig

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,15 +1173,20 @@ config INTEL_PMC_CORE
11731173
depends on PCI
11741174
help
11751175
The Intel Platform Controller Hub for Intel Core SoCs provides access
1176-
to Power Management Controller registers via a PCI interface. This
1176+
to Power Management Controller registers via various interfaces. This
11771177
driver can utilize debugging capabilities and supported features as
1178-
exposed by the Power Management Controller.
1178+
exposed by the Power Management Controller. It also may perform some
1179+
tasks in the PMC in order to enable transition into the SLPS0 state.
1180+
It should be selected on all Intel platforms supported by the driver.
11791181

11801182
Supported features:
11811183
- SLP_S0_RESIDENCY counter
11821184
- PCH IP Power Gating status
1183-
- LTR Ignore
1185+
- LTR Ignore / LTR Show
11841186
- MPHY/PLL gating status (Sunrisepoint PCH only)
1187+
- SLPS0 Debug registers (Cannonlake/Icelake PCH)
1188+
- Low Power Mode registers (Tigerlake and beyond)
1189+
- PMC quirks as needed to enable SLPS0/S0ix
11851190

11861191
config INTEL_PMT_CLASS
11871192
tristate

drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,8 @@ void exit_enum_attributes(void)
185185
sysfs_remove_group(wmi_priv.enumeration_data[instance_id].attr_name_kobj,
186186
&enumeration_attr_group);
187187
}
188+
wmi_priv.enumeration_instances_count = 0;
189+
188190
kfree(wmi_priv.enumeration_data);
191+
wmi_priv.enumeration_data = NULL;
189192
}

drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,8 @@ void exit_int_attributes(void)
175175
sysfs_remove_group(wmi_priv.integer_data[instance_id].attr_name_kobj,
176176
&integer_attr_group);
177177
}
178+
wmi_priv.integer_instances_count = 0;
179+
178180
kfree(wmi_priv.integer_data);
181+
wmi_priv.integer_data = NULL;
179182
}

drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,8 @@ void exit_po_attributes(void)
183183
sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj,
184184
&po_attr_group);
185185
}
186+
wmi_priv.po_instances_count = 0;
187+
186188
kfree(wmi_priv.po_data);
189+
wmi_priv.po_data = NULL;
187190
}

drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,8 @@ void exit_str_attributes(void)
155155
sysfs_remove_group(wmi_priv.str_data[instance_id].attr_name_kobj,
156156
&str_attr_group);
157157
}
158+
wmi_priv.str_instances_count = 0;
159+
158160
kfree(wmi_priv.str_data);
161+
wmi_priv.str_data = NULL;
159162
}

drivers/platform/x86/dell/dell-wmi-sysman/sysman.c

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -210,25 +210,17 @@ static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
210210
*/
211211
static int create_attributes_level_sysfs_files(void)
212212
{
213-
int ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
213+
int ret;
214214

215-
if (ret) {
216-
pr_debug("could not create reset_bios file\n");
215+
ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
216+
if (ret)
217217
return ret;
218-
}
219218

220219
ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr);
221-
if (ret) {
222-
pr_debug("could not create changing_pending_reboot file\n");
223-
sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
224-
}
225-
return ret;
226-
}
220+
if (ret)
221+
return ret;
227222

228-
static void release_reset_bios_data(void)
229-
{
230-
sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
231-
sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr);
223+
return 0;
232224
}
233225

234226
static ssize_t wmi_sysman_attr_show(struct kobject *kobj, struct attribute *attr,
@@ -373,8 +365,6 @@ static void destroy_attribute_objs(struct kset *kset)
373365
*/
374366
static void release_attributes_data(void)
375367
{
376-
release_reset_bios_data();
377-
378368
mutex_lock(&wmi_priv.mutex);
379369
exit_enum_attributes();
380370
exit_int_attributes();
@@ -386,11 +376,13 @@ static void release_attributes_data(void)
386376
wmi_priv.authentication_dir_kset = NULL;
387377
}
388378
if (wmi_priv.main_dir_kset) {
379+
sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
380+
sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr);
389381
destroy_attribute_objs(wmi_priv.main_dir_kset);
390382
kset_unregister(wmi_priv.main_dir_kset);
383+
wmi_priv.main_dir_kset = NULL;
391384
}
392385
mutex_unlock(&wmi_priv.mutex);
393-
394386
}
395387

396388
/**
@@ -497,7 +489,6 @@ static int init_bios_attributes(int attr_type, const char *guid)
497489

498490
err_attr_init:
499491
mutex_unlock(&wmi_priv.mutex);
500-
release_attributes_data();
501492
kfree(obj);
502493
return retval;
503494
}
@@ -513,102 +504,91 @@ static int __init sysman_init(void)
513504
}
514505

515506
ret = init_bios_attr_set_interface();
516-
if (ret || !wmi_priv.bios_attr_wdev) {
517-
pr_debug("failed to initialize set interface\n");
518-
goto fail_set_interface;
519-
}
507+
if (ret)
508+
return ret;
520509

521510
ret = init_bios_attr_pass_interface();
522-
if (ret || !wmi_priv.password_attr_wdev) {
523-
pr_debug("failed to initialize pass interface\n");
524-
goto fail_pass_interface;
511+
if (ret)
512+
goto err_exit_bios_attr_set_interface;
513+
514+
if (!wmi_priv.bios_attr_wdev || !wmi_priv.password_attr_wdev) {
515+
pr_debug("failed to find set or pass interface\n");
516+
ret = -ENODEV;
517+
goto err_exit_bios_attr_pass_interface;
525518
}
526519

527520
ret = class_register(&firmware_attributes_class);
528521
if (ret)
529-
goto fail_class;
522+
goto err_exit_bios_attr_pass_interface;
530523

531524
wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0),
532525
NULL, "%s", DRIVER_NAME);
533526
if (IS_ERR(wmi_priv.class_dev)) {
534527
ret = PTR_ERR(wmi_priv.class_dev);
535-
goto fail_classdev;
528+
goto err_unregister_class;
536529
}
537530

538531
wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL,
539532
&wmi_priv.class_dev->kobj);
540533
if (!wmi_priv.main_dir_kset) {
541534
ret = -ENOMEM;
542-
goto fail_main_kset;
535+
goto err_destroy_classdev;
543536
}
544537

545538
wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL,
546539
&wmi_priv.class_dev->kobj);
547540
if (!wmi_priv.authentication_dir_kset) {
548541
ret = -ENOMEM;
549-
goto fail_authentication_kset;
542+
goto err_release_attributes_data;
550543
}
551544

552545
ret = create_attributes_level_sysfs_files();
553546
if (ret) {
554547
pr_debug("could not create reset BIOS attribute\n");
555-
goto fail_reset_bios;
548+
goto err_release_attributes_data;
556549
}
557550

558551
ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID);
559552
if (ret) {
560553
pr_debug("failed to populate enumeration type attributes\n");
561-
goto fail_create_group;
554+
goto err_release_attributes_data;
562555
}
563556

564557
ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID);
565558
if (ret) {
566559
pr_debug("failed to populate integer type attributes\n");
567-
goto fail_create_group;
560+
goto err_release_attributes_data;
568561
}
569562

570563
ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID);
571564
if (ret) {
572565
pr_debug("failed to populate string type attributes\n");
573-
goto fail_create_group;
566+
goto err_release_attributes_data;
574567
}
575568

576569
ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID);
577570
if (ret) {
578571
pr_debug("failed to populate pass object type attributes\n");
579-
goto fail_create_group;
572+
goto err_release_attributes_data;
580573
}
581574

582575
return 0;
583576

584-
fail_create_group:
577+
err_release_attributes_data:
585578
release_attributes_data();
586579

587-
fail_reset_bios:
588-
if (wmi_priv.authentication_dir_kset) {
589-
kset_unregister(wmi_priv.authentication_dir_kset);
590-
wmi_priv.authentication_dir_kset = NULL;
591-
}
592-
593-
fail_authentication_kset:
594-
if (wmi_priv.main_dir_kset) {
595-
kset_unregister(wmi_priv.main_dir_kset);
596-
wmi_priv.main_dir_kset = NULL;
597-
}
598-
599-
fail_main_kset:
580+
err_destroy_classdev:
600581
device_destroy(&firmware_attributes_class, MKDEV(0, 0));
601582

602-
fail_classdev:
583+
err_unregister_class:
603584
class_unregister(&firmware_attributes_class);
604585

605-
fail_class:
586+
err_exit_bios_attr_pass_interface:
606587
exit_bios_attr_pass_interface();
607588

608-
fail_pass_interface:
589+
err_exit_bios_attr_set_interface:
609590
exit_bios_attr_set_interface();
610591

611-
fail_set_interface:
612592
return ret;
613593
}
614594

drivers/platform/x86/intel-hid.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ static const struct dmi_system_id button_array_table[] = {
9090
DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"),
9191
},
9292
},
93+
{
94+
.ident = "Lenovo ThinkPad X1 Tablet Gen 2",
95+
.matches = {
96+
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
97+
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"),
98+
},
99+
},
93100
{ }
94101
};
95102

drivers/platform/x86/intel-vbtn.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,16 @@ static const struct key_entry intel_vbtn_keymap[] = {
4848
};
4949

5050
static const struct key_entry intel_vbtn_switchmap[] = {
51-
{ KE_SW, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */
52-
{ KE_SW, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */
51+
/*
52+
* SW_DOCK should only be reported for docking stations, but DSDTs using the
53+
* intel-vbtn code, always seem to use this for 2-in-1s / convertibles and set
54+
* SW_DOCK=1 when in laptop-mode (in tandem with setting SW_TABLET_MODE=0).
55+
* This causes userspace to think the laptop is docked to a port-replicator
56+
* and to disable suspend-on-lid-close, which is undesirable.
57+
* Map the dock events to KEY_IGNORE to avoid this broken SW_DOCK reporting.
58+
*/
59+
{ KE_IGNORE, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */
60+
{ KE_IGNORE, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */
5361
{ KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */
5462
{ KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */
5563
{ KE_END }

drivers/platform/x86/intel_pmc_core.c

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -863,34 +863,45 @@ static int pmc_core_pll_show(struct seq_file *s, void *unused)
863863
}
864864
DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
865865

866-
static ssize_t pmc_core_ltr_ignore_write(struct file *file,
867-
const char __user *userbuf,
868-
size_t count, loff_t *ppos)
866+
static int pmc_core_send_ltr_ignore(u32 value)
869867
{
870868
struct pmc_dev *pmcdev = &pmc;
871869
const struct pmc_reg_map *map = pmcdev->map;
872-
u32 val, buf_size, fd;
873-
int err;
874-
875-
buf_size = count < 64 ? count : 64;
876-
877-
err = kstrtou32_from_user(userbuf, buf_size, 10, &val);
878-
if (err)
879-
return err;
870+
u32 reg;
871+
int err = 0;
880872

881873
mutex_lock(&pmcdev->lock);
882874

883-
if (val > map->ltr_ignore_max) {
875+
if (value > map->ltr_ignore_max) {
884876
err = -EINVAL;
885877
goto out_unlock;
886878
}
887879

888-
fd = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
889-
fd |= (1U << val);
890-
pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, fd);
880+
reg = pmc_core_reg_read(pmcdev, map->ltr_ignore_offset);
881+
reg |= BIT(value);
882+
pmc_core_reg_write(pmcdev, map->ltr_ignore_offset, reg);
891883

892884
out_unlock:
893885
mutex_unlock(&pmcdev->lock);
886+
887+
return err;
888+
}
889+
890+
static ssize_t pmc_core_ltr_ignore_write(struct file *file,
891+
const char __user *userbuf,
892+
size_t count, loff_t *ppos)
893+
{
894+
u32 buf_size, value;
895+
int err;
896+
897+
buf_size = min_t(u32, count, 64);
898+
899+
err = kstrtou32_from_user(userbuf, buf_size, 10, &value);
900+
if (err)
901+
return err;
902+
903+
err = pmc_core_send_ltr_ignore(value);
904+
894905
return err == 0 ? count : err;
895906
}
896907

@@ -1244,6 +1255,15 @@ static int pmc_core_probe(struct platform_device *pdev)
12441255
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
12451256
dmi_check_system(pmc_core_dmi_table);
12461257

1258+
/*
1259+
* On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when
1260+
* a cable is attached. Tell the PMC to ignore it.
1261+
*/
1262+
if (pmcdev->map == &tgl_reg_map) {
1263+
dev_dbg(&pdev->dev, "ignoring GBE LTR\n");
1264+
pmc_core_send_ltr_ignore(3);
1265+
}
1266+
12471267
pmc_core_dbgfs_register(pmcdev);
12481268

12491269
device_initialized = true;

drivers/platform/x86/intel_pmt_class.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
173173
struct intel_pmt_namespace *ns,
174174
struct device *parent)
175175
{
176-
struct resource res;
176+
struct resource res = {0};
177177
struct device *dev;
178178
int ret;
179179

0 commit comments

Comments
 (0)