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.

platform/x86: hp-wmi: add platform profile support

Implement support for cool, balanced and performance thermal profile

Signed-off-by: Elia Devito <eliadevito@gmail.com>
Link: https://lore.kernel.org/r/20210221221339.12395-1-eliadevito@gmail.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>

authored by

Elia Devito and committed by
Hans de Goede
4296f679 d7da7534

+93 -5
+1
drivers/platform/x86/Kconfig
··· 410 410 depends on INPUT 411 411 depends on RFKILL || RFKILL = n 412 412 select INPUT_SPARSEKMAP 413 + select ACPI_PLATFORM_PROFILE 413 414 help 414 415 Say Y here if you want to support WMI-based hotkeys on HP laptops and 415 416 to read data from WMI such as docking or ambient light sensor state.
+92 -5
drivers/platform/x86/hp-wmi.c
··· 21 21 #include <linux/input.h> 22 22 #include <linux/input/sparse-keymap.h> 23 23 #include <linux/platform_device.h> 24 + #include <linux/platform_profile.h> 24 25 #include <linux/acpi.h> 25 26 #include <linux/rfkill.h> 26 27 #include <linux/string.h> ··· 120 119 HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD, 121 120 }; 122 121 122 + enum hp_thermal_profile { 123 + HP_THERMAL_PROFILE_PERFORMANCE = 0x00, 124 + HP_THERMAL_PROFILE_DEFAULT = 0x01, 125 + HP_THERMAL_PROFILE_COOL = 0x02 126 + }; 127 + 123 128 #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW) 124 129 #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT) 125 130 ··· 166 159 167 160 static struct input_dev *hp_wmi_input_dev; 168 161 static struct platform_device *hp_wmi_platform_dev; 162 + static struct platform_profile_handler platform_profile_handler; 163 + static bool platform_profile_support; 169 164 170 165 static struct rfkill *wifi_rfkill; 171 166 static struct rfkill *bluetooth_rfkill; ··· 878 869 return err; 879 870 } 880 871 881 - static int thermal_profile_setup(struct platform_device *device) 872 + static int thermal_profile_get(void) 873 + { 874 + return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY); 875 + } 876 + 877 + static int thermal_profile_set(int thermal_profile) 878 + { 879 + return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile, 880 + sizeof(thermal_profile), 0); 881 + } 882 + 883 + static int platform_profile_get(struct platform_profile_handler *pprof, 884 + enum platform_profile_option *profile) 885 + { 886 + int tp; 887 + 888 + tp = thermal_profile_get(); 889 + if (tp < 0) 890 + return tp; 891 + 892 + switch (tp) { 893 + case HP_THERMAL_PROFILE_PERFORMANCE: 894 + *profile = PLATFORM_PROFILE_PERFORMANCE; 895 + break; 896 + case HP_THERMAL_PROFILE_DEFAULT: 897 + *profile = PLATFORM_PROFILE_BALANCED; 898 + break; 899 + case HP_THERMAL_PROFILE_COOL: 900 + *profile = PLATFORM_PROFILE_COOL; 901 + break; 902 + default: 903 + return -EINVAL; 904 + } 905 + 906 + return 0; 907 + } 908 + 909 + static int platform_profile_set(struct platform_profile_handler *pprof, 910 + enum platform_profile_option profile) 882 911 { 883 912 int err, tp; 884 913 885 - tp = hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY); 914 + switch (profile) { 915 + case PLATFORM_PROFILE_PERFORMANCE: 916 + tp = HP_THERMAL_PROFILE_PERFORMANCE; 917 + break; 918 + case PLATFORM_PROFILE_BALANCED: 919 + tp = HP_THERMAL_PROFILE_DEFAULT; 920 + break; 921 + case PLATFORM_PROFILE_COOL: 922 + tp = HP_THERMAL_PROFILE_COOL; 923 + break; 924 + default: 925 + return -EOPNOTSUPP; 926 + } 927 + 928 + err = thermal_profile_set(tp); 929 + if (err) 930 + return err; 931 + 932 + return 0; 933 + } 934 + 935 + static int thermal_profile_setup(void) 936 + { 937 + int err, tp; 938 + 939 + tp = thermal_profile_get(); 886 940 if (tp < 0) 887 941 return tp; 888 942 ··· 953 881 * call thermal profile write command to ensure that the firmware correctly 954 882 * sets the OEM variables for the DPTF 955 883 */ 956 - err = hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &tp, 957 - sizeof(tp), 0); 884 + err = thermal_profile_set(tp); 958 885 if (err) 959 886 return err; 887 + 888 + platform_profile_handler.profile_get = platform_profile_get, 889 + platform_profile_handler.profile_set = platform_profile_set, 890 + 891 + set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices); 892 + set_bit(PLATFORM_PROFILE_BALANCED, platform_profile_handler.choices); 893 + set_bit(PLATFORM_PROFILE_PERFORMANCE, platform_profile_handler.choices); 894 + 895 + err = platform_profile_register(&platform_profile_handler); 896 + if (err) 897 + return err; 898 + 899 + platform_profile_support = true; 960 900 961 901 return 0; 962 902 } ··· 984 900 if (hp_wmi_rfkill_setup(device)) 985 901 hp_wmi_rfkill2_setup(device); 986 902 987 - thermal_profile_setup(device); 903 + thermal_profile_setup(); 988 904 989 905 return 0; 990 906 } ··· 1010 926 rfkill_unregister(wwan_rfkill); 1011 927 rfkill_destroy(wwan_rfkill); 1012 928 } 929 + 930 + if (platform_profile_support) 931 + platform_profile_remove(); 1013 932 1014 933 return 0; 1015 934 }