Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+190 -109
+8 -3
drivers/platform/x86/Kconfig
··· 1173 1173 depends on PCI 1174 1174 help 1175 1175 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 1177 1177 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. 1179 1181 1180 1182 Supported features: 1181 1183 - SLP_S0_RESIDENCY counter 1182 1184 - PCH IP Power Gating status 1183 - - LTR Ignore 1185 + - LTR Ignore / LTR Show 1184 1186 - 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 1185 1190 1186 1191 config INTEL_PMT_CLASS 1187 1192 tristate
+3
drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c
··· 185 185 sysfs_remove_group(wmi_priv.enumeration_data[instance_id].attr_name_kobj, 186 186 &enumeration_attr_group); 187 187 } 188 + wmi_priv.enumeration_instances_count = 0; 189 + 188 190 kfree(wmi_priv.enumeration_data); 191 + wmi_priv.enumeration_data = NULL; 189 192 }
+3
drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c
··· 175 175 sysfs_remove_group(wmi_priv.integer_data[instance_id].attr_name_kobj, 176 176 &integer_attr_group); 177 177 } 178 + wmi_priv.integer_instances_count = 0; 179 + 178 180 kfree(wmi_priv.integer_data); 181 + wmi_priv.integer_data = NULL; 179 182 }
+3
drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c
··· 183 183 sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj, 184 184 &po_attr_group); 185 185 } 186 + wmi_priv.po_instances_count = 0; 187 + 186 188 kfree(wmi_priv.po_data); 189 + wmi_priv.po_data = NULL; 187 190 }
+3
drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c
··· 155 155 sysfs_remove_group(wmi_priv.str_data[instance_id].attr_name_kobj, 156 156 &str_attr_group); 157 157 } 158 + wmi_priv.str_instances_count = 0; 159 + 158 160 kfree(wmi_priv.str_data); 161 + wmi_priv.str_data = NULL; 159 162 }
+32 -52
drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
··· 210 210 */ 211 211 static int create_attributes_level_sysfs_files(void) 212 212 { 213 - int ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); 213 + int ret; 214 214 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) 217 217 return ret; 218 - } 219 218 220 219 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; 227 222 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; 232 224 } 233 225 234 226 static ssize_t wmi_sysman_attr_show(struct kobject *kobj, struct attribute *attr, ··· 365 373 */ 366 374 static void release_attributes_data(void) 367 375 { 368 - release_reset_bios_data(); 369 - 370 376 mutex_lock(&wmi_priv.mutex); 371 377 exit_enum_attributes(); 372 378 exit_int_attributes(); ··· 376 386 wmi_priv.authentication_dir_kset = NULL; 377 387 } 378 388 if (wmi_priv.main_dir_kset) { 389 + sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); 390 + sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); 379 391 destroy_attribute_objs(wmi_priv.main_dir_kset); 380 392 kset_unregister(wmi_priv.main_dir_kset); 393 + wmi_priv.main_dir_kset = NULL; 381 394 } 382 395 mutex_unlock(&wmi_priv.mutex); 383 - 384 396 } 385 397 386 398 /** ··· 489 497 490 498 err_attr_init: 491 499 mutex_unlock(&wmi_priv.mutex); 492 - release_attributes_data(); 493 500 kfree(obj); 494 501 return retval; 495 502 } ··· 504 513 } 505 514 506 515 ret = init_bios_attr_set_interface(); 507 - if (ret || !wmi_priv.bios_attr_wdev) { 508 - pr_debug("failed to initialize set interface\n"); 509 - goto fail_set_interface; 510 - } 516 + if (ret) 517 + return ret; 511 518 512 519 ret = init_bios_attr_pass_interface(); 513 - if (ret || !wmi_priv.password_attr_wdev) { 514 - pr_debug("failed to initialize pass interface\n"); 515 - goto fail_pass_interface; 520 + if (ret) 521 + goto err_exit_bios_attr_set_interface; 522 + 523 + if (!wmi_priv.bios_attr_wdev || !wmi_priv.password_attr_wdev) { 524 + pr_debug("failed to find set or pass interface\n"); 525 + ret = -ENODEV; 526 + goto err_exit_bios_attr_pass_interface; 516 527 } 517 528 518 529 ret = class_register(&firmware_attributes_class); 519 530 if (ret) 520 - goto fail_class; 531 + goto err_exit_bios_attr_pass_interface; 521 532 522 533 wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), 523 534 NULL, "%s", DRIVER_NAME); 524 535 if (IS_ERR(wmi_priv.class_dev)) { 525 536 ret = PTR_ERR(wmi_priv.class_dev); 526 - goto fail_classdev; 537 + goto err_unregister_class; 527 538 } 528 539 529 540 wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL, 530 541 &wmi_priv.class_dev->kobj); 531 542 if (!wmi_priv.main_dir_kset) { 532 543 ret = -ENOMEM; 533 - goto fail_main_kset; 544 + goto err_destroy_classdev; 534 545 } 535 546 536 547 wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL, 537 548 &wmi_priv.class_dev->kobj); 538 549 if (!wmi_priv.authentication_dir_kset) { 539 550 ret = -ENOMEM; 540 - goto fail_authentication_kset; 551 + goto err_release_attributes_data; 541 552 } 542 553 543 554 ret = create_attributes_level_sysfs_files(); 544 555 if (ret) { 545 556 pr_debug("could not create reset BIOS attribute\n"); 546 - goto fail_reset_bios; 557 + goto err_release_attributes_data; 547 558 } 548 559 549 560 ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); 550 561 if (ret) { 551 562 pr_debug("failed to populate enumeration type attributes\n"); 552 - goto fail_create_group; 563 + goto err_release_attributes_data; 553 564 } 554 565 555 566 ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); 556 567 if (ret) { 557 568 pr_debug("failed to populate integer type attributes\n"); 558 - goto fail_create_group; 569 + goto err_release_attributes_data; 559 570 } 560 571 561 572 ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); 562 573 if (ret) { 563 574 pr_debug("failed to populate string type attributes\n"); 564 - goto fail_create_group; 575 + goto err_release_attributes_data; 565 576 } 566 577 567 578 ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); 568 579 if (ret) { 569 580 pr_debug("failed to populate pass object type attributes\n"); 570 - goto fail_create_group; 581 + goto err_release_attributes_data; 571 582 } 572 583 573 584 return 0; 574 585 575 - fail_create_group: 586 + err_release_attributes_data: 576 587 release_attributes_data(); 577 588 578 - fail_reset_bios: 579 - if (wmi_priv.authentication_dir_kset) { 580 - kset_unregister(wmi_priv.authentication_dir_kset); 581 - wmi_priv.authentication_dir_kset = NULL; 582 - } 583 - 584 - fail_authentication_kset: 585 - if (wmi_priv.main_dir_kset) { 586 - kset_unregister(wmi_priv.main_dir_kset); 587 - wmi_priv.main_dir_kset = NULL; 588 - } 589 - 590 - fail_main_kset: 589 + err_destroy_classdev: 591 590 device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 592 591 593 - fail_classdev: 592 + err_unregister_class: 594 593 class_unregister(&firmware_attributes_class); 595 594 596 - fail_class: 595 + err_exit_bios_attr_pass_interface: 597 596 exit_bios_attr_pass_interface(); 598 597 599 - fail_pass_interface: 598 + err_exit_bios_attr_set_interface: 600 599 exit_bios_attr_set_interface(); 601 600 602 - fail_set_interface: 603 601 return ret; 604 602 } 605 603
+7
drivers/platform/x86/intel-hid.c
··· 90 90 DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"), 91 91 }, 92 92 }, 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 + }, 93 100 { } 94 101 }; 95 102
+10 -2
drivers/platform/x86/intel-vbtn.c
··· 48 48 }; 49 49 50 50 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 */ 53 61 { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ 54 62 { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ 55 63 { KE_END }
+35 -15
drivers/platform/x86/intel_pmc_core.c
··· 863 863 } 864 864 DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); 865 865 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) 869 867 { 870 868 struct pmc_dev *pmcdev = &pmc; 871 869 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; 880 872 881 873 mutex_lock(&pmcdev->lock); 882 874 883 - if (val > map->ltr_ignore_max) { 875 + if (value > map->ltr_ignore_max) { 884 876 err = -EINVAL; 885 877 goto out_unlock; 886 878 } 887 879 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); 891 883 892 884 out_unlock: 893 885 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 + 894 905 return err == 0 ? count : err; 895 906 } 896 907 ··· 1254 1243 platform_set_drvdata(pdev, pmcdev); 1255 1244 pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); 1256 1245 dmi_check_system(pmc_core_dmi_table); 1246 + 1247 + /* 1248 + * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when 1249 + * a cable is attached. Tell the PMC to ignore it. 1250 + */ 1251 + if (pmcdev->map == &tgl_reg_map) { 1252 + dev_dbg(&pdev->dev, "ignoring GBE LTR\n"); 1253 + pmc_core_send_ltr_ignore(3); 1254 + } 1257 1255 1258 1256 pmc_core_dbgfs_register(pmcdev); 1259 1257
+1 -1
drivers/platform/x86/intel_pmt_class.c
··· 173 173 struct intel_pmt_namespace *ns, 174 174 struct device *parent) 175 175 { 176 - struct resource res; 176 + struct resource res = {0}; 177 177 struct device *dev; 178 178 int ret; 179 179
+6 -7
drivers/platform/x86/intel_pmt_crashlog.c
··· 23 23 #define CRASH_TYPE_OOBMSM 1 24 24 25 25 /* Control Flags */ 26 - #define CRASHLOG_FLAG_DISABLE BIT(27) 26 + #define CRASHLOG_FLAG_DISABLE BIT(28) 27 27 28 28 /* 29 - * Bits 28 and 29 control the state of bit 31. 29 + * Bits 29 and 30 control the state of bit 31. 30 30 * 31 - * Bit 28 will clear bit 31, if set, allowing a new crashlog to be captured. 32 - * Bit 29 will immediately trigger a crashlog to be generated, setting bit 31. 33 - * Bit 30 is read-only and reserved as 0. 31 + * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured. 32 + * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31. 34 33 * Bit 31 is the read-only status with a 1 indicating log is complete. 35 34 */ 36 - #define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(28) 37 - #define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(29) 35 + #define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(29) 36 + #define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(30) 38 37 #define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31) 39 38 #define CRASHLOG_FLAG_TRIGGER_MASK GENMASK(31, 28) 40 39
+79 -29
drivers/platform/x86/thinkpad_acpi.c
··· 4081 4081 4082 4082 case TP_HKEY_EV_KEY_NUMLOCK: 4083 4083 case TP_HKEY_EV_KEY_FN: 4084 - case TP_HKEY_EV_KEY_FN_ESC: 4085 4084 /* key press events, we just ignore them as long as the EC 4086 4085 * is still reporting them in the normal keyboard stream */ 4086 + *send_acpi_ev = false; 4087 + *ignore_acpi_ev = true; 4088 + return true; 4089 + 4090 + case TP_HKEY_EV_KEY_FN_ESC: 4091 + /* Get the media key status to foce the status LED to update */ 4092 + acpi_evalf(hkey_handle, NULL, "GMKS", "v"); 4087 4093 *send_acpi_ev = false; 4088 4094 *ignore_acpi_ev = true; 4089 4095 return true; ··· 9851 9845 * Thinkpad sensor interfaces 9852 9846 */ 9853 9847 9848 + #define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ 9849 + #define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */ 9850 + #define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */ 9851 + #define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */ 9852 + 9854 9853 #define DYTC_CMD_GET 2 /* To get current IC function and mode */ 9855 9854 #define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */ 9856 9855 ··· 9866 9855 static bool has_lapsensor; 9867 9856 static bool palm_state; 9868 9857 static bool lap_state; 9858 + static int dytc_version; 9869 9859 9870 9860 static int dytc_command(int command, int *output) 9871 9861 { ··· 9878 9866 } 9879 9867 if (!acpi_evalf(dytc_handle, output, NULL, "dd", command)) 9880 9868 return -EIO; 9869 + return 0; 9870 + } 9871 + 9872 + static int dytc_get_version(void) 9873 + { 9874 + int err, output; 9875 + 9876 + /* Check if we've been called before - and just return cached value */ 9877 + if (dytc_version) 9878 + return dytc_version; 9879 + 9880 + /* Otherwise query DYTC and extract version information */ 9881 + err = dytc_command(DYTC_CMD_QUERY, &output); 9882 + /* 9883 + * If support isn't available (ENODEV) then don't return an error 9884 + * and don't create the sysfs group 9885 + */ 9886 + if (err == -ENODEV) 9887 + return 0; 9888 + /* For all other errors we can flag the failure */ 9889 + if (err) 9890 + return err; 9891 + 9892 + /* Check DYTC is enabled and supports mode setting */ 9893 + if (output & BIT(DYTC_QUERY_ENABLE_BIT)) 9894 + dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; 9895 + 9881 9896 return 0; 9882 9897 } 9883 9898 ··· 10013 9974 if (err) 10014 9975 return err; 10015 9976 } 10016 - if (has_lapsensor) { 9977 + 9978 + /* Check if we know the DYTC version, if we don't then get it */ 9979 + if (!dytc_version) { 9980 + err = dytc_get_version(); 9981 + if (err) 9982 + return err; 9983 + } 9984 + /* 9985 + * Platforms before DYTC version 5 claim to have a lap sensor, but it doesn't work, so we 9986 + * ignore them 9987 + */ 9988 + if (has_lapsensor && (dytc_version >= 5)) { 10017 9989 err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); 10018 9990 if (err) 10019 9991 return err; ··· 10049 9999 * DYTC Platform Profile interface 10050 10000 */ 10051 10001 10052 - #define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ 10053 10002 #define DYTC_CMD_SET 1 /* To enable/disable IC function mode */ 10054 10003 #define DYTC_CMD_RESET 0x1ff /* To reset back to default */ 10055 - 10056 - #define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */ 10057 - #define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */ 10058 - #define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */ 10059 10004 10060 10005 #define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */ 10061 10006 #define DYTC_GET_MODE_BIT 12 /* Bits 12-15 - mode setting */ ··· 10187 10142 return err; 10188 10143 10189 10144 if (profile == PLATFORM_PROFILE_BALANCED) { 10190 - /* To get back to balanced mode we just issue a reset command */ 10191 - err = dytc_command(DYTC_CMD_RESET, &output); 10145 + /* 10146 + * To get back to balanced mode we need to issue a reset command. 10147 + * Note we still need to disable CQL mode before hand and re-enable 10148 + * it afterwards, otherwise dytc_lapmode gets reset to 0 and stays 10149 + * stuck at 0 for aprox. 30 minutes. 10150 + */ 10151 + err = dytc_cql_command(DYTC_CMD_RESET, &output); 10192 10152 if (err) 10193 10153 goto unlock; 10194 10154 } else { ··· 10261 10211 if (err) 10262 10212 return err; 10263 10213 10214 + /* Check if we know the DYTC version, if we don't then get it */ 10215 + if (!dytc_version) { 10216 + err = dytc_get_version(); 10217 + if (err) 10218 + return err; 10219 + } 10264 10220 /* Check DYTC is enabled and supports mode setting */ 10265 - if (output & BIT(DYTC_QUERY_ENABLE_BIT)) { 10266 - /* Only DYTC v5.0 and later has this feature. */ 10267 - int dytc_version; 10221 + if (dytc_version >= 5) { 10222 + dbg_printk(TPACPI_DBG_INIT, 10223 + "DYTC version %d: thermal mode available\n", dytc_version); 10224 + /* Create platform_profile structure and register */ 10225 + err = platform_profile_register(&dytc_profile); 10226 + /* 10227 + * If for some reason platform_profiles aren't enabled 10228 + * don't quit terminally. 10229 + */ 10230 + if (err) 10231 + return 0; 10268 10232 10269 - dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; 10270 - if (dytc_version >= 5) { 10271 - dbg_printk(TPACPI_DBG_INIT, 10272 - "DYTC version %d: thermal mode available\n", dytc_version); 10273 - /* Create platform_profile structure and register */ 10274 - err = platform_profile_register(&dytc_profile); 10275 - /* 10276 - * If for some reason platform_profiles aren't enabled 10277 - * don't quit terminally. 10278 - */ 10279 - if (err) 10280 - return 0; 10281 - 10282 - dytc_profile_available = true; 10283 - /* Ensure initial values are correct */ 10284 - dytc_profile_refresh(); 10285 - } 10233 + dytc_profile_available = true; 10234 + /* Ensure initial values are correct */ 10235 + dytc_profile_refresh(); 10286 10236 } 10287 10237 return 0; 10288 10238 }