From 4af760db64801e0b53809b4f10785c5d71ec3e6a Mon Sep 17 00:00:00 2001 From: "Justin M. Forbes" Date: Wed, 24 Mar 2021 06:38:06 -0500 Subject: kernel-5.11.9-11 * Wed Mar 24 2021 Justin M. Forbes [5.11.9-11] - KVM: PPC: Book3S HV: Save and restore FSCR in the P9 path (Fabiano Rosas) - drm/nouveau/kms/nve4-nv108: Don't advertise 256x256 cursor support yet (Lyude Paul) - platform/x86: intel-vbtn: Stop reporting SW_DOCK events (Hans de Goede) - platform/x86: dell-wmi-sysman: Cleanup create_attributes_level_sysfs_files() (Hans de Goede) - platform/x86: dell-wmi-sysman: Make sysman_init() return -ENODEV of the interfaces are not found (Hans de Goede) - platform/x86: dell-wmi-sysman: Cleanup sysman_init() error-exit handling (Hans de Goede) - platform/x86: dell-wmi-sysman: Fix release_attributes_data() getting called twice on init_bios_attributes() failure (Hans de Goede) - platform/x86: dell-wmi-sysman: Make it safe to call exit_foo_attributes() multiple times (Hans de Goede) - platform/x86: dell-wmi-sysman: Fix possible NULL pointer deref on exit (Hans de Goede) - platform/x86: dell-wmi-sysman: Fix crash caused by calling kset_unregister twice (Hans de Goede) - platform/x86: thinkpad_acpi: Disable DYTC CQL mode around switching to balanced mode (Hans de Goede) - platform/x86: thinkpad_acpi: Allow the FnLock LED to change state (Esteve Varela Colominas) - platform/x86: thinkpad_acpi: check dytc version for lapmode sysfs (Mark Pearson) - platform/x86: intel-hid: Support Lenovo ThinkPad X1 Tablet Gen 2 (Alban Bedel) Resolves: rhbz# Signed-off-by: Justin M. Forbes --- patch-5.11-redhat.patch | 529 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 477 insertions(+), 52 deletions(-) (limited to 'patch-5.11-redhat.patch') diff --git a/patch-5.11-redhat.patch b/patch-5.11-redhat.patch index 47a381e02..86bee73b5 100644 --- a/patch-5.11-redhat.patch +++ b/patch-5.11-redhat.patch @@ -1,7 +1,7 @@ - Documentation/ABI/testing/sysfs-platform_profile | 24 ++ + Documentation/ABI/testing/sysfs-platform_profile | 24 + Documentation/admin-guide/kdump/kdump.rst | 11 + - .../admin-guide/laptops/thinkpad-acpi.rst | 25 ++ - .../bindings/display/panel/xingbangda,xbd599.yaml | 50 +++ + .../admin-guide/laptops/thinkpad-acpi.rst | 25 + + .../bindings/display/panel/xingbangda,xbd599.yaml | 50 ++ Documentation/userspace-api/index.rst | 1 + .../userspace-api/sysfs-platform_profile.rst | 42 ++ Makefile | 1 + @@ -9,6 +9,7 @@ arch/arm/include/asm/uaccess.h | 8 +- arch/arm64/Kconfig | 3 +- .../boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +- + arch/powerpc/kvm/book3s_hv.c | 4 + arch/s390/include/asm/ipl.h | 1 + arch/s390/kernel/ipl.c | 5 + arch/s390/kernel/setup.c | 4 + @@ -18,29 +19,37 @@ drivers/acpi/apei/hest.c | 8 + drivers/acpi/irq.c | 17 +- drivers/acpi/pci_mcfg.c | 7 + - drivers/acpi/platform_profile.c | 177 ++++++++ + drivers/acpi/platform_profile.c | 177 +++++++ drivers/acpi/scan.c | 9 + drivers/ata/libahci.c | 18 + drivers/char/ipmi/ipmi_dmi.c | 15 + drivers/char/ipmi/ipmi_msghandler.c | 16 +- drivers/firmware/efi/Makefile | 1 + - drivers/firmware/efi/efi.c | 124 ++++-- + drivers/firmware/efi/efi.c | 124 +++-- drivers/firmware/efi/secureboot.c | 38 ++ + drivers/gpu/drm/nouveau/dispnv50/disp.c | 12 +- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + - drivers/gpu/drm/panel/panel-xingbangda-xbd599.c | 366 ++++++++++++++++ + drivers/gpu/drm/panel/panel-xingbangda-xbd599.c | 366 +++++++++++++++ drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 10 +- drivers/hid/hid-rmi.c | 64 --- - drivers/input/rmi4/rmi_driver.c | 124 +++--- + drivers/input/rmi4/rmi_driver.c | 124 +++-- drivers/iommu/iommu.c | 22 + drivers/pci/controller/dwc/Kconfig | 10 +- drivers/pci/controller/dwc/Makefile | 2 +- - drivers/pci/controller/dwc/pcie-tegra194.c | 102 +++++ + drivers/pci/controller/dwc/pcie-tegra194.c | 102 ++++ drivers/pci/controller/pcie-brcmstb.c | 1 + - drivers/pci/quirks.c | 24 ++ + drivers/pci/quirks.c | 24 + drivers/platform/x86/Kconfig | 2 + - drivers/platform/x86/ideapad-laptop.c | 289 +++++++++++++ - drivers/platform/x86/thinkpad_acpi.c | 464 ++++++++++++++++++++- + .../platform/x86/dell-wmi-sysman/enum-attributes.c | 3 + + .../platform/x86/dell-wmi-sysman/int-attributes.c | 3 + + .../x86/dell-wmi-sysman/passobj-attributes.c | 3 + + .../x86/dell-wmi-sysman/string-attributes.c | 3 + + drivers/platform/x86/dell-wmi-sysman/sysman.c | 84 ++-- + drivers/platform/x86/ideapad-laptop.c | 289 ++++++++++++ + drivers/platform/x86/intel-hid.c | 7 + + drivers/platform/x86/intel-vbtn.c | 12 +- + drivers/platform/x86/thinkpad_acpi.c | 518 ++++++++++++++++++++- drivers/scsi/smartpqi/smartpqi_init.c | 16 + drivers/usb/core/hub.c | 7 + include/linux/efi.h | 22 +- @@ -59,7 +68,7 @@ security/security.c | 6 + sound/hda/Kconfig | 14 + sound/hda/intel-dsp-config.c | 29 +- - 61 files changed, 2126 insertions(+), 213 deletions(-) + 70 files changed, 2254 insertions(+), 270 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-platform_profile b/Documentation/ABI/testing/sysfs-platform_profile new file mode 100644 @@ -273,7 +282,7 @@ index 000000000000..c33a71263d9e + 2. Add the new profile name, along with a clear description of the + expected behaviour, to the sysfs-platform_profile ABI documentation. diff --git a/Makefile b/Makefile -index d8a39ece170d..1b98067c8aa8 100644 +index 23403c8e0838..f066d200185e 100644 --- a/Makefile +++ b/Makefile @@ -494,6 +494,7 @@ KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE @@ -365,6 +374,28 @@ index 219b7507a10f..45769764425d 100644 }; &cpu_b0 { +diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c +index 6f612d240392..f2ddf7139a2a 100644 +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -3595,6 +3595,7 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, + unsigned long host_tidr = mfspr(SPRN_TIDR); + unsigned long host_iamr = mfspr(SPRN_IAMR); + unsigned long host_amr = mfspr(SPRN_AMR); ++ unsigned long host_fscr = mfspr(SPRN_FSCR); + s64 dec; + u64 tb; + int trap, save_pmu; +@@ -3735,6 +3736,9 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, + if (host_amr != vcpu->arch.amr) + mtspr(SPRN_AMR, host_amr); + ++ if (host_fscr != vcpu->arch.fscr) ++ mtspr(SPRN_FSCR, host_fscr); ++ + msr_check_and_set(MSR_FP | MSR_VEC | MSR_VSX); + store_fp_state(&vcpu->arch.fp); + #ifdef CONFIG_ALTIVEC diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index a9e2c7295b35..6ff11f3a2d47 100644 --- a/arch/s390/include/asm/ipl.h @@ -871,7 +902,7 @@ index 467e94259679..9b6f5b8e5397 100644 obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c -index df3f9bcab581..8d5b6eb36467 100644 +index 4b7ee3fa9224..64b31d852d20 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -31,6 +31,7 @@ @@ -1059,6 +1090,31 @@ index 000000000000..de0a3714a5d4 + } + } +} +diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c +index 5f4f09a601d4..857b76605a9e 100644 +--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c +@@ -2663,9 +2663,19 @@ nv50_display_create(struct drm_device *dev) + else + nouveau_display(dev)->format_modifiers = disp50xx_modifiers; + +- if (disp->disp->object.oclass >= GK104_DISP) { ++ /* FIXME: 256x256 cursors are supported on Kepler, however unlike Maxwell and later ++ * generations Kepler requires that we specify the page type, small (4K) or large (128K), ++ * correctly for the ctxdma being used on curs/ovly. We currently share a ctxdma across all ++ * display planes (except ovly) that defaults to small pages, which results in artifacting ++ * on 256x256 cursors. Until we teach nouveau to create an appropriate ctxdma for the cursor ++ * fb in use, simply avoid advertising support for 256x256 cursors. ++ */ ++ if (disp->disp->object.oclass >= GM107_DISP) { + dev->mode_config.cursor_width = 256; + dev->mode_config.cursor_height = 256; ++ } else if (disp->disp->object.oclass >= GK104_DISP) { ++ dev->mode_config.cursor_width = 128; ++ dev->mode_config.cursor_height = 128; + } else { + dev->mode_config.cursor_width = 64; + dev->mode_config.cursor_height = 64; diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index b4e021ea30f9..5687b745ebe2 100644 --- a/drivers/gpu/drm/panel/Kconfig @@ -2080,6 +2136,252 @@ index ac4125ec0660..3a8ade8bb073 100644 select HWMON select NVRAM select NEW_LEDS +diff --git a/drivers/platform/x86/dell-wmi-sysman/enum-attributes.c b/drivers/platform/x86/dell-wmi-sysman/enum-attributes.c +index 80f4b7785c6c..091e48c217ed 100644 +--- a/drivers/platform/x86/dell-wmi-sysman/enum-attributes.c ++++ b/drivers/platform/x86/dell-wmi-sysman/enum-attributes.c +@@ -185,5 +185,8 @@ void exit_enum_attributes(void) + sysfs_remove_group(wmi_priv.enumeration_data[instance_id].attr_name_kobj, + &enumeration_attr_group); + } ++ wmi_priv.enumeration_instances_count = 0; ++ + kfree(wmi_priv.enumeration_data); ++ wmi_priv.enumeration_data = NULL; + } +diff --git a/drivers/platform/x86/dell-wmi-sysman/int-attributes.c b/drivers/platform/x86/dell-wmi-sysman/int-attributes.c +index 75aedbb733be..8a49ba6e44f9 100644 +--- a/drivers/platform/x86/dell-wmi-sysman/int-attributes.c ++++ b/drivers/platform/x86/dell-wmi-sysman/int-attributes.c +@@ -175,5 +175,8 @@ void exit_int_attributes(void) + sysfs_remove_group(wmi_priv.integer_data[instance_id].attr_name_kobj, + &integer_attr_group); + } ++ wmi_priv.integer_instances_count = 0; ++ + kfree(wmi_priv.integer_data); ++ wmi_priv.integer_data = NULL; + } +diff --git a/drivers/platform/x86/dell-wmi-sysman/passobj-attributes.c b/drivers/platform/x86/dell-wmi-sysman/passobj-attributes.c +index 3abcd95477c0..834b3e82ad9f 100644 +--- a/drivers/platform/x86/dell-wmi-sysman/passobj-attributes.c ++++ b/drivers/platform/x86/dell-wmi-sysman/passobj-attributes.c +@@ -183,5 +183,8 @@ void exit_po_attributes(void) + sysfs_remove_group(wmi_priv.po_data[instance_id].attr_name_kobj, + &po_attr_group); + } ++ wmi_priv.po_instances_count = 0; ++ + kfree(wmi_priv.po_data); ++ wmi_priv.po_data = NULL; + } +diff --git a/drivers/platform/x86/dell-wmi-sysman/string-attributes.c b/drivers/platform/x86/dell-wmi-sysman/string-attributes.c +index ac75dce88a4c..552537852459 100644 +--- a/drivers/platform/x86/dell-wmi-sysman/string-attributes.c ++++ b/drivers/platform/x86/dell-wmi-sysman/string-attributes.c +@@ -155,5 +155,8 @@ void exit_str_attributes(void) + sysfs_remove_group(wmi_priv.str_data[instance_id].attr_name_kobj, + &str_attr_group); + } ++ wmi_priv.str_instances_count = 0; ++ + kfree(wmi_priv.str_data); ++ wmi_priv.str_data = NULL; + } +diff --git a/drivers/platform/x86/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell-wmi-sysman/sysman.c +index cb81010ba1a2..7410ccae650c 100644 +--- a/drivers/platform/x86/dell-wmi-sysman/sysman.c ++++ b/drivers/platform/x86/dell-wmi-sysman/sysman.c +@@ -210,25 +210,17 @@ static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot); + */ + static int create_attributes_level_sysfs_files(void) + { +- int ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); ++ int ret; + +- if (ret) { +- pr_debug("could not create reset_bios file\n"); ++ ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); ++ if (ret) + return ret; +- } + + ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); +- if (ret) { +- pr_debug("could not create changing_pending_reboot file\n"); +- sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); +- } +- return ret; +-} ++ if (ret) ++ return ret; + +-static void release_reset_bios_data(void) +-{ +- sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); +- sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); ++ return 0; + } + + 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) + */ + static void release_attributes_data(void) + { +- release_reset_bios_data(); +- + mutex_lock(&wmi_priv.mutex); + exit_enum_attributes(); + exit_int_attributes(); +@@ -386,11 +376,13 @@ static void release_attributes_data(void) + wmi_priv.authentication_dir_kset = NULL; + } + if (wmi_priv.main_dir_kset) { ++ sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr); ++ sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr); + destroy_attribute_objs(wmi_priv.main_dir_kset); + kset_unregister(wmi_priv.main_dir_kset); ++ wmi_priv.main_dir_kset = NULL; + } + mutex_unlock(&wmi_priv.mutex); +- + } + + /** +@@ -497,7 +489,6 @@ static int init_bios_attributes(int attr_type, const char *guid) + + err_attr_init: + mutex_unlock(&wmi_priv.mutex); +- release_attributes_data(); + kfree(obj); + return retval; + } +@@ -513,102 +504,91 @@ static int __init sysman_init(void) + } + + ret = init_bios_attr_set_interface(); +- if (ret || !wmi_priv.bios_attr_wdev) { +- pr_debug("failed to initialize set interface\n"); +- goto fail_set_interface; +- } ++ if (ret) ++ return ret; + + ret = init_bios_attr_pass_interface(); +- if (ret || !wmi_priv.password_attr_wdev) { +- pr_debug("failed to initialize pass interface\n"); +- goto fail_pass_interface; ++ if (ret) ++ goto err_exit_bios_attr_set_interface; ++ ++ if (!wmi_priv.bios_attr_wdev || !wmi_priv.password_attr_wdev) { ++ pr_debug("failed to find set or pass interface\n"); ++ ret = -ENODEV; ++ goto err_exit_bios_attr_pass_interface; + } + + ret = class_register(&firmware_attributes_class); + if (ret) +- goto fail_class; ++ goto err_exit_bios_attr_pass_interface; + + wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), + NULL, "%s", DRIVER_NAME); + if (IS_ERR(wmi_priv.class_dev)) { + ret = PTR_ERR(wmi_priv.class_dev); +- goto fail_classdev; ++ goto err_unregister_class; + } + + wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL, + &wmi_priv.class_dev->kobj); + if (!wmi_priv.main_dir_kset) { + ret = -ENOMEM; +- goto fail_main_kset; ++ goto err_destroy_classdev; + } + + wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL, + &wmi_priv.class_dev->kobj); + if (!wmi_priv.authentication_dir_kset) { + ret = -ENOMEM; +- goto fail_authentication_kset; ++ goto err_release_attributes_data; + } + + ret = create_attributes_level_sysfs_files(); + if (ret) { + pr_debug("could not create reset BIOS attribute\n"); +- goto fail_reset_bios; ++ goto err_release_attributes_data; + } + + ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); + if (ret) { + pr_debug("failed to populate enumeration type attributes\n"); +- goto fail_create_group; ++ goto err_release_attributes_data; + } + + ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); + if (ret) { + pr_debug("failed to populate integer type attributes\n"); +- goto fail_create_group; ++ goto err_release_attributes_data; + } + + ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); + if (ret) { + pr_debug("failed to populate string type attributes\n"); +- goto fail_create_group; ++ goto err_release_attributes_data; + } + + ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); + if (ret) { + pr_debug("failed to populate pass object type attributes\n"); +- goto fail_create_group; ++ goto err_release_attributes_data; + } + + return 0; + +-fail_create_group: ++err_release_attributes_data: + release_attributes_data(); + +-fail_reset_bios: +- if (wmi_priv.authentication_dir_kset) { +- kset_unregister(wmi_priv.authentication_dir_kset); +- wmi_priv.authentication_dir_kset = NULL; +- } +- +-fail_authentication_kset: +- if (wmi_priv.main_dir_kset) { +- kset_unregister(wmi_priv.main_dir_kset); +- wmi_priv.main_dir_kset = NULL; +- } +- +-fail_main_kset: ++err_destroy_classdev: + device_destroy(&firmware_attributes_class, MKDEV(0, 0)); + +-fail_classdev: ++err_unregister_class: + class_unregister(&firmware_attributes_class); + +-fail_class: ++err_exit_bios_attr_pass_interface: + exit_bios_attr_pass_interface(); + +-fail_pass_interface: ++err_exit_bios_attr_set_interface: + exit_bios_attr_set_interface(); + +-fail_set_interface: + return ret; + } + diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 5b81bafa5c16..cc42af2a0a98 100644 --- a/drivers/platform/x86/ideapad-laptop.c @@ -2429,8 +2731,49 @@ index 5b81bafa5c16..cc42af2a0a98 100644 return 0; } #endif +diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c +index 2f5b8d09143e..57cc92891a57 100644 +--- a/drivers/platform/x86/intel-hid.c ++++ b/drivers/platform/x86/intel-hid.c +@@ -90,6 +90,13 @@ static const struct dmi_system_id button_array_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"), + }, + }, ++ { ++ .ident = "Lenovo ThinkPad X1 Tablet Gen 2", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), ++ }, ++ }, + { } + }; + +diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c +index 30a9062d2b4b..a90c32d072da 100644 +--- a/drivers/platform/x86/intel-vbtn.c ++++ b/drivers/platform/x86/intel-vbtn.c +@@ -47,8 +47,16 @@ static const struct key_entry intel_vbtn_keymap[] = { + }; + + static const struct key_entry intel_vbtn_switchmap[] = { +- { KE_SW, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ +- { KE_SW, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ ++ /* ++ * SW_DOCK should only be reported for docking stations, but DSDTs using the ++ * intel-vbtn code, always seem to use this for 2-in-1s / convertibles and set ++ * SW_DOCK=1 when in laptop-mode (in tandem with setting SW_TABLET_MODE=0). ++ * This causes userspace to think the laptop is docked to a port-replicator ++ * and to disable suspend-on-lid-close, which is undesirable. ++ * Map the dock events to KEY_IGNORE to avoid this broken SW_DOCK reporting. ++ */ ++ { KE_IGNORE, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ ++ { KE_IGNORE, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ + { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ + { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ + }; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index f3e8eca8d86d..5b596a825b24 100644 +index f3e8eca8d86d..9ecf7829b3d8 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -66,6 +66,7 @@ @@ -2441,9 +2784,44 @@ index f3e8eca8d86d..5b596a825b24 100644 #include #include #include -@@ -9855,16 +9856,27 @@ static bool has_lapsensor; +@@ -4080,13 +4081,19 @@ static bool hotkey_notify_6xxx(const u32 hkey, + + case TP_HKEY_EV_KEY_NUMLOCK: + case TP_HKEY_EV_KEY_FN: +- case TP_HKEY_EV_KEY_FN_ESC: + /* key press events, we just ignore them as long as the EC + * is still reporting them in the normal keyboard stream */ + *send_acpi_ev = false; + *ignore_acpi_ev = true; + return true; + ++ case TP_HKEY_EV_KEY_FN_ESC: ++ /* Get the media key status to foce the status LED to update */ ++ acpi_evalf(hkey_handle, NULL, "GMKS", "v"); ++ *send_acpi_ev = false; ++ *ignore_acpi_ev = true; ++ return true; ++ + case TP_HKEY_EV_TABLET_CHANGED: + tpacpi_input_send_tabletsw(); + hotkey_tablet_mode_notify_change(); +@@ -9844,6 +9851,11 @@ static struct ibm_struct lcdshadow_driver_data = { + * Thinkpad sensor interfaces + */ + ++#define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ ++#define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */ ++#define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */ ++#define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */ ++ + #define DYTC_CMD_GET 2 /* To get current IC function and mode */ + #define DYTC_GET_LAPMODE_BIT 17 /* Set when in lapmode */ + +@@ -9854,17 +9866,56 @@ static bool has_palmsensor; + static bool has_lapsensor; static bool palm_state; static bool lap_state; ++static int dytc_version; -static int lapsensor_get(bool *present, bool *state) +static int dytc_command(int command, int *output) @@ -2463,6 +2841,33 @@ index f3e8eca8d86d..5b596a825b24 100644 + return 0; +} + ++static int dytc_get_version(void) ++{ ++ int err, output; ++ ++ /* Check if we've been called before - and just return cached value */ ++ if (dytc_version) ++ return dytc_version; ++ ++ /* Otherwise query DYTC and extract version information */ ++ err = dytc_command(DYTC_CMD_QUERY, &output); ++ /* ++ * If support isn't available (ENODEV) then don't return an error ++ * and don't create the sysfs group ++ */ ++ if (err == -ENODEV) ++ return 0; ++ /* For all other errors we can flag the failure */ ++ if (err) ++ return err; ++ ++ /* Check DYTC is enabled and supports mode setting */ ++ if (output & BIT(DYTC_QUERY_ENABLE_BIT)) ++ dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; ++ ++ return 0; ++} ++ +static int lapsensor_get(bool *present, bool *state) +{ + int output, err; @@ -2474,7 +2879,27 @@ index f3e8eca8d86d..5b596a825b24 100644 *present = true; /*If we get his far, we have lapmode support*/ *state = output & BIT(DYTC_GET_LAPMODE_BIT) ? true : false; -@@ -9983,6 +9995,434 @@ static struct ibm_struct proxsensor_driver_data = { +@@ -9962,7 +10013,18 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm) + if (err) + return err; + } +- if (has_lapsensor) { ++ ++ /* Check if we know the DYTC version, if we don't then get it */ ++ if (!dytc_version) { ++ err = dytc_get_version(); ++ if (err) ++ return err; ++ } ++ /* ++ * Platforms before DYTC version 5 claim to have a lap sensor, but it doesn't work, so we ++ * ignore them ++ */ ++ if (has_lapsensor && (dytc_version >= 5)) { + err = sysfs_create_file(&tpacpi_pdev->dev.kobj, &dev_attr_dytc_lapmode.attr); + if (err) + return err; +@@ -9983,6 +10045,434 @@ static struct ibm_struct proxsensor_driver_data = { .exit = proxsensor_exit, }; @@ -2482,14 +2907,9 @@ index f3e8eca8d86d..5b596a825b24 100644 + * DYTC Platform Profile interface + */ + -+#define DYTC_CMD_QUERY 0 /* To get DYTC status - enable/revision */ +#define DYTC_CMD_SET 1 /* To enable/disable IC function mode */ +#define DYTC_CMD_RESET 0x1ff /* To reset back to default */ + -+#define DYTC_QUERY_ENABLE_BIT 8 /* Bit 8 - 0 = disabled, 1 = enabled */ -+#define DYTC_QUERY_SUBREV_BIT 16 /* Bits 16 - 27 - sub revision */ -+#define DYTC_QUERY_REV_BIT 28 /* Bits 28 - 31 - revision */ -+ +#define DYTC_GET_FUNCTION_BIT 8 /* Bits 8-11 - function setting */ +#define DYTC_GET_MODE_BIT 12 /* Bits 12-15 - mode setting */ + @@ -2625,8 +3045,13 @@ index f3e8eca8d86d..5b596a825b24 100644 + return err; + + if (profile == PLATFORM_PROFILE_BALANCED) { -+ /* To get back to balanced mode we just issue a reset command */ -+ err = dytc_command(DYTC_CMD_RESET, &output); ++ /* ++ * To get back to balanced mode we need to issue a reset command. ++ * Note we still need to disable CQL mode before hand and re-enable ++ * it afterwards, otherwise dytc_lapmode gets reset to 0 and stays ++ * stuck at 0 for aprox. 30 minutes. ++ */ ++ err = dytc_cql_command(DYTC_CMD_RESET, &output); + if (err) + goto unlock; + } else { @@ -2694,28 +3119,28 @@ index f3e8eca8d86d..5b596a825b24 100644 + if (err) + return err; + ++ /* Check if we know the DYTC version, if we don't then get it */ ++ if (!dytc_version) { ++ err = dytc_get_version(); ++ if (err) ++ return err; ++ } + /* Check DYTC is enabled and supports mode setting */ -+ if (output & BIT(DYTC_QUERY_ENABLE_BIT)) { -+ /* Only DYTC v5.0 and later has this feature. */ -+ int dytc_version; ++ if (dytc_version >= 5) { ++ dbg_printk(TPACPI_DBG_INIT, ++ "DYTC version %d: thermal mode available\n", dytc_version); ++ /* Create platform_profile structure and register */ ++ err = platform_profile_register(&dytc_profile); ++ /* ++ * If for some reason platform_profiles aren't enabled ++ * don't quit terminally. ++ */ ++ if (err) ++ return 0; + -+ dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; -+ if (dytc_version >= 5) { -+ dbg_printk(TPACPI_DBG_INIT, -+ "DYTC version %d: thermal mode available\n", dytc_version); -+ /* Create platform_profile structure and register */ -+ err = platform_profile_register(&dytc_profile); -+ /* -+ * If for some reason platform_profiles aren't enabled -+ * don't quit terminally. -+ */ -+ if (err) -+ return 0; -+ -+ dytc_profile_available = true; -+ /* Ensure initial values are correct */ -+ dytc_profile_refresh(); -+ } ++ dytc_profile_available = true; ++ /* Ensure initial values are correct */ ++ dytc_profile_refresh(); + } + return 0; +} @@ -2909,7 +3334,7 @@ index f3e8eca8d86d..5b596a825b24 100644 /**************************************************************************** **************************************************************************** * -@@ -10031,8 +10471,12 @@ static void tpacpi_driver_event(const unsigned int hkey_event) +@@ -10031,8 +10521,12 @@ static void tpacpi_driver_event(const unsigned int hkey_event) mutex_unlock(&kbdlight_mutex); } @@ -2923,7 +3348,7 @@ index f3e8eca8d86d..5b596a825b24 100644 } static void hotkey_driver_event(const unsigned int scancode) -@@ -10475,6 +10919,14 @@ static struct ibm_init_struct ibms_init[] __initdata = { +@@ -10475,6 +10969,14 @@ static struct ibm_init_struct ibms_init[] __initdata = { .init = tpacpi_proxsensor_init, .data = &proxsensor_driver_data, }, @@ -2991,7 +3416,7 @@ index 7f71218cc1e5..283fc0f41cd2 100644 * disconnected while waiting for the lock to succeed. */ usb_lock_device(hdev); diff --git a/include/linux/efi.h b/include/linux/efi.h -index 763b816ba19c..4c55e3aa7e95 100644 +index 119262585e9b..7d67f0187c34 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -43,6 +43,8 @@ @@ -3003,7 +3428,7 @@ index 763b816ba19c..4c55e3aa7e95 100644 typedef unsigned long efi_status_t; typedef u8 efi_bool_t; typedef u16 efi_char16_t; /* UNICODE character */ -@@ -786,6 +788,14 @@ extern int __init efi_setup_pcdp_console(char *); +@@ -788,6 +790,14 @@ extern int __init efi_setup_pcdp_console(char *); #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ #define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */ #define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */ @@ -3018,7 +3443,7 @@ index 763b816ba19c..4c55e3aa7e95 100644 #ifdef CONFIG_EFI /* -@@ -797,6 +807,8 @@ static inline bool efi_enabled(int feature) +@@ -799,6 +809,8 @@ static inline bool efi_enabled(int feature) } extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused); @@ -3027,7 +3452,7 @@ index 763b816ba19c..4c55e3aa7e95 100644 bool __pure __efi_soft_reserve_enabled(void); static inline bool __pure efi_soft_reserve_enabled(void) -@@ -817,6 +829,8 @@ static inline bool efi_enabled(int feature) +@@ -819,6 +831,8 @@ static inline bool efi_enabled(int feature) static inline void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {} @@ -3036,7 +3461,7 @@ index 763b816ba19c..4c55e3aa7e95 100644 static inline bool efi_soft_reserve_enabled(void) { return false; -@@ -829,6 +843,7 @@ static inline bool efi_rt_services_supported(unsigned int mask) +@@ -831,6 +845,7 @@ static inline bool efi_rt_services_supported(unsigned int mask) #endif extern int efi_status_to_err(efi_status_t status); @@ -3044,7 +3469,7 @@ index 763b816ba19c..4c55e3aa7e95 100644 /* * Variable Attributes -@@ -1081,13 +1096,6 @@ static inline bool efi_runtime_disabled(void) { return true; } +@@ -1083,13 +1098,6 @@ static inline bool efi_runtime_disabled(void) { return true; } extern void efi_call_virt_check_flags(unsigned long flags, const char *call); extern unsigned long efi_call_virt_save_flags(void); -- cgit