Commit 4296f679 authored by Elia Devito's avatar Elia Devito Committed by Hans de Goede

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

Implement support for cool, balanced and performance thermal profile
Signed-off-by: default avatarElia Devito <eliadevito@gmail.com>
Link: https://lore.kernel.org/r/20210221221339.12395-1-eliadevito@gmail.comReviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent d7da7534
...@@ -410,6 +410,7 @@ config HP_WMI ...@@ -410,6 +410,7 @@ config HP_WMI
depends on INPUT depends on INPUT
depends on RFKILL || RFKILL = n depends on RFKILL || RFKILL = n
select INPUT_SPARSEKMAP select INPUT_SPARSEKMAP
select ACPI_PLATFORM_PROFILE
help help
Say Y here if you want to support WMI-based hotkeys on HP laptops and Say Y here if you want to support WMI-based hotkeys on HP laptops and
to read data from WMI such as docking or ambient light sensor state. to read data from WMI such as docking or ambient light sensor state.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/input/sparse-keymap.h> #include <linux/input/sparse-keymap.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_profile.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/rfkill.h> #include <linux/rfkill.h>
#include <linux/string.h> #include <linux/string.h>
...@@ -119,6 +120,12 @@ enum hp_wireless2_bits { ...@@ -119,6 +120,12 @@ enum hp_wireless2_bits {
HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD, HPWMI_POWER_FW_OR_HW = HPWMI_POWER_BIOS | HPWMI_POWER_HARD,
}; };
enum hp_thermal_profile {
HP_THERMAL_PROFILE_PERFORMANCE = 0x00,
HP_THERMAL_PROFILE_DEFAULT = 0x01,
HP_THERMAL_PROFILE_COOL = 0x02
};
#define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW) #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
#define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT) #define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
...@@ -159,6 +166,8 @@ static const struct key_entry hp_wmi_keymap[] = { ...@@ -159,6 +166,8 @@ static const struct key_entry hp_wmi_keymap[] = {
static struct input_dev *hp_wmi_input_dev; static struct input_dev *hp_wmi_input_dev;
static struct platform_device *hp_wmi_platform_dev; static struct platform_device *hp_wmi_platform_dev;
static struct platform_profile_handler platform_profile_handler;
static bool platform_profile_support;
static struct rfkill *wifi_rfkill; static struct rfkill *wifi_rfkill;
static struct rfkill *bluetooth_rfkill; static struct rfkill *bluetooth_rfkill;
...@@ -869,11 +878,74 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device) ...@@ -869,11 +878,74 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
return err; return err;
} }
static int thermal_profile_setup(struct platform_device *device) static int thermal_profile_get(void)
{
return hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY);
}
static int thermal_profile_set(int thermal_profile)
{
return hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &thermal_profile,
sizeof(thermal_profile), 0);
}
static int platform_profile_get(struct platform_profile_handler *pprof,
enum platform_profile_option *profile)
{
int tp;
tp = thermal_profile_get();
if (tp < 0)
return tp;
switch (tp) {
case HP_THERMAL_PROFILE_PERFORMANCE:
*profile = PLATFORM_PROFILE_PERFORMANCE;
break;
case HP_THERMAL_PROFILE_DEFAULT:
*profile = PLATFORM_PROFILE_BALANCED;
break;
case HP_THERMAL_PROFILE_COOL:
*profile = PLATFORM_PROFILE_COOL;
break;
default:
return -EINVAL;
}
return 0;
}
static int platform_profile_set(struct platform_profile_handler *pprof,
enum platform_profile_option profile)
{ {
int err, tp; int err, tp;
tp = hp_wmi_read_int(HPWMI_THERMAL_PROFILE_QUERY); switch (profile) {
case PLATFORM_PROFILE_PERFORMANCE:
tp = HP_THERMAL_PROFILE_PERFORMANCE;
break;
case PLATFORM_PROFILE_BALANCED:
tp = HP_THERMAL_PROFILE_DEFAULT;
break;
case PLATFORM_PROFILE_COOL:
tp = HP_THERMAL_PROFILE_COOL;
break;
default:
return -EOPNOTSUPP;
}
err = thermal_profile_set(tp);
if (err)
return err;
return 0;
}
static int thermal_profile_setup(void)
{
int err, tp;
tp = thermal_profile_get();
if (tp < 0) if (tp < 0)
return tp; return tp;
...@@ -881,11 +953,23 @@ static int thermal_profile_setup(struct platform_device *device) ...@@ -881,11 +953,23 @@ static int thermal_profile_setup(struct platform_device *device)
* call thermal profile write command to ensure that the firmware correctly * call thermal profile write command to ensure that the firmware correctly
* sets the OEM variables for the DPTF * sets the OEM variables for the DPTF
*/ */
err = hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &tp, err = thermal_profile_set(tp);
sizeof(tp), 0);
if (err) if (err)
return err; return err;
platform_profile_handler.profile_get = platform_profile_get,
platform_profile_handler.profile_set = platform_profile_set,
set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
set_bit(PLATFORM_PROFILE_BALANCED, platform_profile_handler.choices);
set_bit(PLATFORM_PROFILE_PERFORMANCE, platform_profile_handler.choices);
err = platform_profile_register(&platform_profile_handler);
if (err)
return err;
platform_profile_support = true;
return 0; return 0;
} }
...@@ -900,7 +984,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) ...@@ -900,7 +984,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
if (hp_wmi_rfkill_setup(device)) if (hp_wmi_rfkill_setup(device))
hp_wmi_rfkill2_setup(device); hp_wmi_rfkill2_setup(device);
thermal_profile_setup(device); thermal_profile_setup();
return 0; return 0;
} }
...@@ -927,6 +1011,9 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device) ...@@ -927,6 +1011,9 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
rfkill_destroy(wwan_rfkill); rfkill_destroy(wwan_rfkill);
} }
if (platform_profile_support)
platform_profile_remove();
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment