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

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.com


Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent d7da7534
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -410,6 +410,7 @@ config HP_WMI
	depends on INPUT
	depends on RFKILL || RFKILL = n
	select INPUT_SPARSEKMAP
	select ACPI_PLATFORM_PROFILE
	help
	 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.
+92 −5
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/platform_device.h>
#include <linux/platform_profile.h>
#include <linux/acpi.h>
#include <linux/rfkill.h>
#include <linux/string.h>
@@ -119,6 +120,12 @@ enum hp_wireless2_bits {
	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_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)

@@ -159,6 +166,8 @@ static const struct key_entry hp_wmi_keymap[] = {

static struct input_dev *hp_wmi_input_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 *bluetooth_rfkill;
@@ -869,11 +878,74 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device)
	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;

	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)
		return tp;

@@ -881,11 +953,23 @@ static int thermal_profile_setup(struct platform_device *device)
	 * call thermal profile write command to ensure that the firmware correctly
	 * sets the OEM variables for the DPTF
	 */
	err = hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY, HPWMI_WRITE, &tp,
							   sizeof(tp), 0);
	err = thermal_profile_set(tp);
	if (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;
}

@@ -900,7 +984,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
	if (hp_wmi_rfkill_setup(device))
		hp_wmi_rfkill2_setup(device);

	thermal_profile_setup(device);
	thermal_profile_setup();

	return 0;
}
@@ -927,6 +1011,9 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
		rfkill_destroy(wwan_rfkill);
	}

	if (platform_profile_support)
		platform_profile_remove();

	return 0;
}