* [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
@ 2026-05-20 14:07 Radhey Kalra
2026-05-20 14:07 ` [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data Radhey Kalra
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Radhey Kalra @ 2026-05-20 14:07 UTC (permalink / raw)
To: platform-driver-x86
Cc: ilpo.jarvinen, hdegoede, krishna.chomal108, Radhey Kalra
Hi,
This is a smaller v5 split for the Victus 15-fb0xxx fan-control change.
Patch 1 prepares the hp-wmi board data and hwmon fan-control selection
so fan support can be described independently from Victus S thermal
profiles. Patch 2 adds fan-control support for Victus 15-fb0xxx board
8A3D.
Based on platform-drivers-x86/for-next commit:
165e81354eefd5551358112773f24027aac59d5a
Tested on a Victus by HP Gaming Laptop 15-fb0xxx, board 8A3D, BIOS
F.22. With the series applied, pwm1 and pwm1_enable are exposed and
the EC-layout warning is not emitted for 8A3D.
Radhey Kalra (2):
platform/x86: hp-wmi: Prepare Victus fan control board data
platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
drivers/platform/x86/hp/hp-wmi.c | 212 ++++++++++++++++++++++---------
1 file changed, 153 insertions(+), 59 deletions(-)
---
Changes in v5:
- Reduce the series to two patches: one preparatory board-data/hwmon
patch and one focused 8A3D enablement patch.
- Drop the active_thermal_profile_params global and dereference the
thermal-profile data through active_board_params.
- Wrap the setup comment added in the preparatory patch to stay under
80 columns.
Changes in v4:
- Split v3 into two no-functional-changes-intended refactors, one
fan-table parsing fix, and one 8A3D support patch.
- Rebase on platform-drivers-x86/for-next commit 165e81354eefd555.
- Move revision notes to the cover letter.
Changes in v3:
- Rebase on platform-drivers-x86/for-next commit 165e81354eefd555.
- Keep the v2 board-data approach and 8A3D fan-control-only handling.
Changes in v2:
- Use real name in Signed-off-by.
- Replace the ad-hoc fan-control DMI table with board data in
.driver_data.
- Keep 8A3D fan-control-only instead of enabling Victus S thermal
profiles.
- Use the fixed fan-table parser path and derive gpu_delta from the
first non-zero GPU row.
--
2.54.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data
2026-05-20 14:07 [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
@ 2026-05-20 14:07 ` Radhey Kalra
2026-05-21 13:02 ` Ilpo Järvinen
2026-05-20 14:07 ` [PATCH v5 2/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
2026-05-20 17:50 ` [PATCH v5 0/2] " Krishna Chomal
2 siblings, 1 reply; 9+ messages in thread
From: Radhey Kalra @ 2026-05-20 14:07 UTC (permalink / raw)
To: platform-driver-x86
Cc: ilpo.jarvinen, hdegoede, krishna.chomal108, Radhey Kalra
Move the Victus S thermal-profile DMI data behind hp_wmi_board_params so
board-specific feature data can describe thermal-profile and fan-control
support together.
Use the active board data for fan-control decisions instead of checking
is_victus_s_thermal_profile() in the hwmon path. Also derive gpu_delta
from the first non-zero GPU RPM row so fan tables whose first GPU RPM is
zero still produce valid fan settings.
No fan-control support changes intended for existing boards. Fan tables
with an initial zero GPU RPM row now produce a valid GPU delta.
Signed-off-by: Radhey Kalra <radheykalra901@gmail.com>
---
drivers/platform/x86/hp/hp-wmi.c | 204 ++++++++++++++++++++++---------
1 file changed, 145 insertions(+), 59 deletions(-)
diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index d1cc6e7..dcfffe6 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -133,11 +133,52 @@ static const struct thermal_profile_params omen_v1_no_ec_thermal_params = {
.ec_tp_offset = HP_NO_THERMAL_PROFILE_OFFSET,
};
-/*
- * A generic pointer for the currently-active board's thermal profile
- * parameters.
- */
-static struct thermal_profile_params *active_thermal_profile_params;
+struct hp_wmi_fan_profile_params {
+ int (*get_fan_speed)(int fan);
+ bool fan_table;
+};
+
+struct hp_wmi_board_params {
+ const struct thermal_profile_params *thermal_profile;
+ const struct hp_wmi_fan_profile_params *fan_profile;
+};
+
+static int hp_wmi_get_fan_speed_victus_s(int fan);
+
+static const struct hp_wmi_fan_profile_params victus_s_fan_profile_params = {
+ .get_fan_speed = hp_wmi_get_fan_speed_victus_s,
+ .fan_table = true,
+};
+
+static const struct hp_wmi_board_params victus_s_board_params = {
+ .thermal_profile = &victus_s_thermal_params,
+ .fan_profile = &victus_s_fan_profile_params,
+};
+
+static const struct hp_wmi_board_params omen_v1_board_params = {
+ .thermal_profile = &omen_v1_thermal_params,
+ .fan_profile = &victus_s_fan_profile_params,
+};
+
+static const struct hp_wmi_board_params omen_v1_legacy_board_params = {
+ .thermal_profile = &omen_v1_legacy_thermal_params,
+ .fan_profile = &victus_s_fan_profile_params,
+};
+
+static const struct hp_wmi_board_params omen_v1_no_ec_board_params = {
+ .thermal_profile = &omen_v1_no_ec_thermal_params,
+ .fan_profile = &victus_s_fan_profile_params,
+};
+
+static const struct hp_wmi_board_params *active_board_params;
+
+static const struct thermal_profile_params *hp_wmi_thermal_profile(void)
+{
+ if (!active_board_params)
+ return NULL;
+
+ return active_board_params->thermal_profile;
+}
/* DMI board names of devices that should use the omen specific path for
* thermal profiles.
@@ -187,67 +228,67 @@ static const char * const victus_thermal_profile_boards[] = {
"8A25",
};
-/* DMI Board names of Victus 16-r and Victus 16-s laptops */
-static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = {
+/* DMI board-specific feature data for Omen and Victus laptops. */
+static const struct dmi_system_id hp_wmi_feature_boards[] __initconst = {
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8A44") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8A4D") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCA") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD5") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C76") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C77") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C78") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C99") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C9C") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8D41") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8D87") },
- .driver_data = (void *)&omen_v1_no_ec_thermal_params,
+ .driver_data = (void *)&omen_v1_no_ec_board_params,
},
{},
};
@@ -1769,6 +1810,38 @@ static bool is_victus_s_thermal_profile(void)
return is_victus_s_board;
}
+static const struct hp_wmi_fan_profile_params *hp_wmi_fan_profile(void)
+{
+ if (!active_board_params)
+ return NULL;
+
+ return active_board_params->fan_profile;
+}
+
+static bool hp_wmi_fan_control_supported(void)
+{
+ const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
+
+ return params && params->get_fan_speed;
+}
+
+static bool hp_wmi_fan_table_supported(void)
+{
+ const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
+
+ return params && params->fan_table;
+}
+
+static int hp_wmi_get_active_fan_speed(int fan)
+{
+ const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
+
+ if (!params || !params->get_fan_speed)
+ return -EOPNOTSUPP;
+
+ return params->get_fan_speed(fan);
+}
+
static int victus_s_gpu_thermal_profile_get(bool *ctgp_enable,
bool *ppab_enable,
u8 *dstate,
@@ -1854,7 +1927,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
u8 current_dstate, current_gpu_slowdown_temp, tp;
const struct thermal_profile_params *params;
- params = active_thermal_profile_params;
+ params = hp_wmi_thermal_profile();
+ if (!params)
+ return -ENODEV;
+
if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
*profile = active_platform_profile;
@@ -1866,10 +1942,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
return ret;
/*
- * We cannot use active_thermal_profile_params here, because boards
- * like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
- * it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
- * Gaming Hub on windows. Hence accept both of these values.
+ * Boards like 8C78 have tp == 0x0 || tp == 0x1 after cold boot,
+ * but logically it should have tp == 0x30 || tp == 0x31, as
+ * corrected by the Omen Gaming Hub on windows. Hence accept both
+ * of these values.
*/
if (tp == victus_s_thermal_params.performance ||
tp == omen_v1_thermal_params.performance) {
@@ -1904,12 +1980,12 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
{
- struct thermal_profile_params *params;
+ const struct thermal_profile_params *params;
bool gpu_ctgp_enable, gpu_ppab_enable;
u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */
int err, tp;
- params = active_thermal_profile_params;
+ params = hp_wmi_thermal_profile();
if (!params)
return -ENODEV;
@@ -2175,6 +2251,7 @@ static const struct platform_profile_ops hp_wmi_platform_profile_ops = {
static int thermal_profile_setup(struct platform_device *device)
{
const struct platform_profile_ops *ops;
+ const struct thermal_profile_params *params;
int err, tp;
if (is_omen_thermal_profile()) {
@@ -2206,13 +2283,17 @@ static int thermal_profile_setup(struct platform_device *device)
ops = &platform_profile_victus_ops;
} else if (is_victus_s_thermal_profile()) {
+ params = hp_wmi_thermal_profile();
+ if (!params)
+ return -ENODEV;
+
/*
* For an unknown EC layout board, platform_profile_victus_s_get_ec(),
* behaves like a wrapper around active_platform_profile, to avoid using
* uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
*/
- if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
- active_thermal_profile_params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
+ if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
+ params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
active_platform_profile = PLATFORM_PROFILE_BALANCED;
} else {
err = platform_profile_victus_s_get_ec(&active_platform_profile);
@@ -2380,7 +2461,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
switch (priv->mode) {
case PWM_MODE_MAX:
- if (is_victus_s_thermal_profile()) {
+ if (hp_wmi_fan_control_supported()) {
ret = hp_wmi_get_fan_count_userdefine_trigger();
if (ret < 0)
return ret;
@@ -2392,7 +2473,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
return 0;
case PWM_MODE_MANUAL:
- if (!is_victus_s_thermal_profile())
+ if (!hp_wmi_fan_control_supported())
return -EOPNOTSUPP;
ret = hp_wmi_fan_speed_set(priv, pwm_to_rpm(priv->pwm, priv));
if (ret < 0)
@@ -2401,7 +2482,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
return 0;
case PWM_MODE_AUTO:
- if (is_victus_s_thermal_profile()) {
+ if (hp_wmi_fan_control_supported()) {
ret = hp_wmi_get_fan_count_userdefine_trigger();
if (ret < 0)
return ret;
@@ -2425,12 +2506,12 @@ static umode_t hp_wmi_hwmon_is_visible(const void *data,
{
switch (type) {
case hwmon_pwm:
- if (attr == hwmon_pwm_input && !is_victus_s_thermal_profile())
+ if (attr == hwmon_pwm_input && !hp_wmi_fan_control_supported())
return 0;
return 0644;
case hwmon_fan:
- if (is_victus_s_thermal_profile()) {
- if (hp_wmi_get_fan_speed_victus_s(channel) >= 0)
+ if (hp_wmi_fan_control_supported()) {
+ if (hp_wmi_get_active_fan_speed(channel) >= 0)
return 0444;
} else {
if (hp_wmi_get_fan_speed(channel) >= 0)
@@ -2454,8 +2535,8 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
priv = dev_get_drvdata(dev);
switch (type) {
case hwmon_fan:
- if (is_victus_s_thermal_profile())
- ret = hp_wmi_get_fan_speed_victus_s(channel);
+ if (hp_wmi_fan_control_supported())
+ ret = hp_wmi_get_active_fan_speed(channel);
else
ret = hp_wmi_get_fan_speed(channel);
if (ret < 0)
@@ -2464,10 +2545,10 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
return 0;
case hwmon_pwm:
if (attr == hwmon_pwm_input) {
- if (!is_victus_s_thermal_profile())
+ if (!hp_wmi_fan_control_supported())
return -EOPNOTSUPP;
- rpm = hp_wmi_get_fan_speed_victus_s(channel);
+ rpm = hp_wmi_get_active_fan_speed(channel);
if (rpm < 0)
return rpm;
*val = rpm_to_pwm(rpm / 100, priv);
@@ -2501,7 +2582,7 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
switch (type) {
case hwmon_pwm:
if (attr == hwmon_pwm_input) {
- if (!is_victus_s_thermal_profile())
+ if (!hp_wmi_fan_control_supported())
return -EOPNOTSUPP;
/* PWM input is invalid when not in manual mode */
if (priv->mode != PWM_MODE_MANUAL)
@@ -2518,13 +2599,13 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
priv->mode = PWM_MODE_MAX;
return hp_wmi_apply_fan_settings(priv);
case PWM_MODE_MANUAL:
- if (!is_victus_s_thermal_profile())
+ if (!hp_wmi_fan_control_supported())
return -EOPNOTSUPP;
/*
* When switching to manual mode, set fan speed to
* current RPM values to ensure a smooth transition.
*/
- rpm = hp_wmi_get_fan_speed_victus_s(channel);
+ rpm = hp_wmi_get_active_fan_speed(channel);
if (rpm < 0)
return rpm;
priv->pwm = rpm_to_pwm(rpm / 100, priv);
@@ -2585,13 +2666,14 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
u8 min_rpm, max_rpm;
u8 cpu_rpm, gpu_rpm, noise_db;
int gpu_delta, i, num_entries, ret;
+ bool gpu_delta_found = false;
size_t header_size, entry_size;
/* Default behaviour on hwmon init is automatic mode */
priv->mode = PWM_MODE_AUTO;
- /* Bypass all non-Victus S devices */
- if (!is_victus_s_thermal_profile())
+ /* Bypass devices without fan control support. */
+ if (!hp_wmi_fan_table_supported())
return 0;
ret = hp_wmi_perform_query(HPWMI_VICTUS_S_GET_FAN_TABLE_QUERY,
@@ -2625,12 +2707,15 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
min_rpm = cpu_rpm;
if (cpu_rpm > max_rpm)
max_rpm = cpu_rpm;
+ if (!gpu_delta_found && gpu_rpm > 0) {
+ gpu_delta = gpu_rpm - cpu_rpm;
+ gpu_delta_found = true;
+ }
}
- if (min_rpm == U8_MAX || max_rpm == 0)
+ if (min_rpm == U8_MAX || max_rpm == 0 || !gpu_delta_found)
return -EINVAL;
- gpu_delta = fan_table->entries[0].gpu_rpm - fan_table->entries[0].cpu_rpm;
priv->min_rpm = min_rpm;
priv->max_rpm = max_rpm;
priv->gpu_delta = gpu_delta;
@@ -2673,24 +2758,25 @@ static int hp_wmi_hwmon_init(void)
return 0;
}
-static void __init setup_active_thermal_profile_params(void)
+static void __init setup_active_board_params(void)
{
const struct dmi_system_id *id;
+ const struct thermal_profile_params *params;
- /*
- * Currently only victus_s devices use the
- * active_thermal_profile_params
- */
- id = dmi_first_match(victus_s_thermal_profile_boards);
+ id = dmi_first_match(hp_wmi_feature_boards);
if (id) {
+ active_board_params = id->driver_data;
+ params = hp_wmi_thermal_profile();
+ if (!params)
+ return;
+
/*
* Marking this boolean is required to ensure that
* is_victus_s_thermal_profile() behaves like a valid
* wrapper.
*/
is_victus_s_board = true;
- active_thermal_profile_params = id->driver_data;
- if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
+ if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
pr_warn("Unknown EC layout for board %s. Thermal profile readback will be disabled. Please report this to platform-driver-x86@vger.kernel.org\n",
dmi_get_system_info(DMI_BOARD_NAME));
}
@@ -2725,10 +2811,10 @@ static int __init hp_wmi_init(void)
}
/*
- * Setup active board's thermal profile parameters before
- * starting platform driver probe.
+ * Setup active board feature data before starting platform
+ * driver probe.
*/
- setup_active_thermal_profile_params();
+ setup_active_board_params();
err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
if (err)
goto err_unregister_device;
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v5 2/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
2026-05-20 14:07 [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
2026-05-20 14:07 ` [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data Radhey Kalra
@ 2026-05-20 14:07 ` Radhey Kalra
2026-05-20 17:50 ` [PATCH v5 0/2] " Krishna Chomal
2 siblings, 0 replies; 9+ messages in thread
From: Radhey Kalra @ 2026-05-20 14:07 UTC (permalink / raw)
To: platform-driver-x86
Cc: ilpo.jarvinen, hdegoede, krishna.chomal108, Radhey Kalra
HP Victus 15-fb0xxx board 8A3D exposes the Victus fan table and accepts
the existing Victus fan-speed WMI control path. Add it as a
fan-control-only board so the hwmon PWM interface is enabled without
forcing Victus S thermal-profile handling on this model.
Tested on a Victus by HP Gaming Laptop 15-fb0xxx, board 8A3D, BIOS
F.22. The fan table query succeeded and returned rows including
cpu=23/gpu=0 followed by cpu=24/gpu=22. With 8A3D enabled in the
fan-control path, pwm1 and pwm1_enable were exposed through hwmon.
Signed-off-by: Radhey Kalra <radheykalra901@gmail.com>
---
drivers/platform/x86/hp/hp-wmi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index dcfffe6..f463823 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -170,6 +170,10 @@ static const struct hp_wmi_board_params omen_v1_no_ec_board_params = {
.fan_profile = &victus_s_fan_profile_params,
};
+static const struct hp_wmi_board_params victus_8a3d_board_params = {
+ .fan_profile = &victus_s_fan_profile_params,
+};
+
static const struct hp_wmi_board_params *active_board_params;
static const struct thermal_profile_params *hp_wmi_thermal_profile(void)
@@ -230,6 +234,10 @@ static const char * const victus_thermal_profile_boards[] = {
/* DMI board-specific feature data for Omen and Victus laptops. */
static const struct dmi_system_id hp_wmi_feature_boards[] __initconst = {
+ {
+ .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A3D") },
+ .driver_data = (void *)&victus_8a3d_board_params,
+ },
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8A44") },
.driver_data = (void *)&omen_v1_legacy_board_params,
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
2026-05-20 14:07 [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
2026-05-20 14:07 ` [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data Radhey Kalra
2026-05-20 14:07 ` [PATCH v5 2/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
@ 2026-05-20 17:50 ` Krishna Chomal
2026-05-21 12:49 ` Radhey Kalra
2 siblings, 1 reply; 9+ messages in thread
From: Krishna Chomal @ 2026-05-20 17:50 UTC (permalink / raw)
To: Radhey Kalra; +Cc: platform-driver-x86, ilpo.jarvinen, hdegoede
On Wed, May 20, 2026 at 07:37:46PM +0530, Radhey Kalra wrote:
>Hi,
>
>This is a smaller v5 split for the Victus 15-fb0xxx fan-control change.
>Patch 1 prepares the hp-wmi board data and hwmon fan-control selection
>so fan support can be described independently from Victus S thermal
>profiles. Patch 2 adds fan-control support for Victus 15-fb0xxx board
>8A3D.
>
I am sure I must be missing something but I don't see why this isn't
just a DMI table addition?
I understand that you want to refactor the structs to decouple fan control
from platform profile so that you can just use fan control feature and
ignore platform profile, but I don't understand why that is done?
If I use victus_8a3d_board_params quirk on my device (8C78), it effectively
removes platform profile support, why is this choice made?
>Based on platform-drivers-x86/for-next commit:
>165e81354eefd5551358112773f24027aac59d5a
>
>Tested on a Victus by HP Gaming Laptop 15-fb0xxx, board 8A3D, BIOS
>F.22. With the series applied, pwm1 and pwm1_enable are exposed and
>the EC-layout warning is not emitted for 8A3D.
>
>Radhey Kalra (2):
> platform/x86: hp-wmi: Prepare Victus fan control board data
> platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
>
> drivers/platform/x86/hp/hp-wmi.c | 212 ++++++++++++++++++++++---------
> 1 file changed, 153 insertions(+), 59 deletions(-)
>
>---
>Changes in v5:
>- Reduce the series to two patches: one preparatory board-data/hwmon
> patch and one focused 8A3D enablement patch.
>- Drop the active_thermal_profile_params global and dereference the
> thermal-profile data through active_board_params.
>- Wrap the setup comment added in the preparatory patch to stay under
> 80 columns.
>
>Changes in v4:
>- Split v3 into two no-functional-changes-intended refactors, one
> fan-table parsing fix, and one 8A3D support patch.
>- Rebase on platform-drivers-x86/for-next commit 165e81354eefd555.
>- Move revision notes to the cover letter.
>
>Changes in v3:
>- Rebase on platform-drivers-x86/for-next commit 165e81354eefd555.
>- Keep the v2 board-data approach and 8A3D fan-control-only handling.
>
>Changes in v2:
>- Use real name in Signed-off-by.
>- Replace the ad-hoc fan-control DMI table with board data in
> .driver_data.
>- Keep 8A3D fan-control-only instead of enabling Victus S thermal
> profiles.
>- Use the fixed fan-table parser path and derive gpu_delta from the
> first non-zero GPU row.
>
>--
>2.54.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
2026-05-20 17:50 ` [PATCH v5 0/2] " Krishna Chomal
@ 2026-05-21 12:49 ` Radhey Kalra
2026-05-21 13:36 ` Krishna Chomal
0 siblings, 1 reply; 9+ messages in thread
From: Radhey Kalra @ 2026-05-21 12:49 UTC (permalink / raw)
To: Krishna Chomal; +Cc: platform-driver-x86, ilpo.jarvinen
Hi Krishna,
I tested the current platform-profile behavior on 8A3D more carefully.
The board already exposes the generic hp-wmi platform-profile choices:
cool quiet balanced performance
Writes to all choices succeed and read back correctly, and I do not
see hp_wmi errors in dmesg.
However, under full CPU load I could not confirm that these profiles
change CPU power behavior. Across quiet/balanced/performance/cool, CPU
frequency stayed around 3.27 GHz and the reported PPT stayed around 33
W. Fan RPM rose somewhat later in the test, but the system was also
heating up, so I cannot separate that from normal firmware thermal fan
ramping.
So I should not claim that platform-profile policy is meaningfully
validated for 8A3D. What I have verified is that the Victus
fan-control path works.
That is why I avoided a plain addition to
victus_s_thermal_profile_boards: it would move 8A3D from the existing
generic platform-profile path to the Victus S-specific
platform-profile path, which I have not verified on this board.
Thanks, Radhey
On Wed, May 20, 2026 at 11:20 PM Krishna Chomal
<krishna.chomal108@gmail.com> wrote:
>
> On Wed, May 20, 2026 at 07:37:46PM +0530, Radhey Kalra wrote:
> >Hi,
> >
> >This is a smaller v5 split for the Victus 15-fb0xxx fan-control change.
> >Patch 1 prepares the hp-wmi board data and hwmon fan-control selection
> >so fan support can be described independently from Victus S thermal
> >profiles. Patch 2 adds fan-control support for Victus 15-fb0xxx board
> >8A3D.
> >
>
> I am sure I must be missing something but I don't see why this isn't
> just a DMI table addition?
>
> I understand that you want to refactor the structs to decouple fan control
> from platform profile so that you can just use fan control feature and
> ignore platform profile, but I don't understand why that is done?
>
> If I use victus_8a3d_board_params quirk on my device (8C78), it effectively
> removes platform profile support, why is this choice made?
>
> >Based on platform-drivers-x86/for-next commit:
> >165e81354eefd5551358112773f24027aac59d5a
> >
> >Tested on a Victus by HP Gaming Laptop 15-fb0xxx, board 8A3D, BIOS
> >F.22. With the series applied, pwm1 and pwm1_enable are exposed and
> >the EC-layout warning is not emitted for 8A3D.
> >
> >Radhey Kalra (2):
> > platform/x86: hp-wmi: Prepare Victus fan control board data
> > platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
> >
> > drivers/platform/x86/hp/hp-wmi.c | 212 ++++++++++++++++++++++---------
> > 1 file changed, 153 insertions(+), 59 deletions(-)
> >
> >---
> >Changes in v5:
> >- Reduce the series to two patches: one preparatory board-data/hwmon
> > patch and one focused 8A3D enablement patch.
> >- Drop the active_thermal_profile_params global and dereference the
> > thermal-profile data through active_board_params.
> >- Wrap the setup comment added in the preparatory patch to stay under
> > 80 columns.
> >
> >Changes in v4:
> >- Split v3 into two no-functional-changes-intended refactors, one
> > fan-table parsing fix, and one 8A3D support patch.
> >- Rebase on platform-drivers-x86/for-next commit 165e81354eefd555.
> >- Move revision notes to the cover letter.
> >
> >Changes in v3:
> >- Rebase on platform-drivers-x86/for-next commit 165e81354eefd555.
> >- Keep the v2 board-data approach and 8A3D fan-control-only handling.
> >
> >Changes in v2:
> >- Use real name in Signed-off-by.
> >- Replace the ad-hoc fan-control DMI table with board data in
> > .driver_data.
> >- Keep 8A3D fan-control-only instead of enabling Victus S thermal
> > profiles.
> >- Use the fixed fan-table parser path and derive gpu_delta from the
> > first non-zero GPU row.
> >
> >--
> >2.54.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data
2026-05-20 14:07 ` [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data Radhey Kalra
@ 2026-05-21 13:02 ` Ilpo Järvinen
2026-05-21 13:06 ` Radhey Kalra
0 siblings, 1 reply; 9+ messages in thread
From: Ilpo Järvinen @ 2026-05-21 13:02 UTC (permalink / raw)
To: Radhey Kalra; +Cc: platform-driver-x86, hdegoede, krishna.chomal108
On Wed, 20 May 2026, Radhey Kalra wrote:
> Move the Victus S thermal-profile DMI data behind hp_wmi_board_params so
> board-specific feature data can describe thermal-profile and fan-control
> support together.
>
> Use the active board data for fan-control decisions instead of checking
> is_victus_s_thermal_profile() in the hwmon path.
> Also derive gpu_delta
> from the first non-zero GPU RPM row so fan tables whose first GPU RPM is
> zero still produce valid fan settings.
Unfortunately, moving gpu_delta things from own patch to the refactor
patch is a step backwards.
Why would it logically belong to this patch??
--
i.
> No fan-control support changes intended for existing boards. Fan tables
> with an initial zero GPU RPM row now produce a valid GPU delta.
>
> Signed-off-by: Radhey Kalra <radheykalra901@gmail.com>
> ---
> drivers/platform/x86/hp/hp-wmi.c | 204 ++++++++++++++++++++++---------
> 1 file changed, 145 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
> index d1cc6e7..dcfffe6 100644
> --- a/drivers/platform/x86/hp/hp-wmi.c
> +++ b/drivers/platform/x86/hp/hp-wmi.c
> @@ -133,11 +133,52 @@ static const struct thermal_profile_params omen_v1_no_ec_thermal_params = {
> .ec_tp_offset = HP_NO_THERMAL_PROFILE_OFFSET,
> };
>
> -/*
> - * A generic pointer for the currently-active board's thermal profile
> - * parameters.
> - */
> -static struct thermal_profile_params *active_thermal_profile_params;
> +struct hp_wmi_fan_profile_params {
> + int (*get_fan_speed)(int fan);
> + bool fan_table;
> +};
> +
> +struct hp_wmi_board_params {
> + const struct thermal_profile_params *thermal_profile;
> + const struct hp_wmi_fan_profile_params *fan_profile;
> +};
> +
> +static int hp_wmi_get_fan_speed_victus_s(int fan);
> +
> +static const struct hp_wmi_fan_profile_params victus_s_fan_profile_params = {
> + .get_fan_speed = hp_wmi_get_fan_speed_victus_s,
> + .fan_table = true,
> +};
> +
> +static const struct hp_wmi_board_params victus_s_board_params = {
> + .thermal_profile = &victus_s_thermal_params,
> + .fan_profile = &victus_s_fan_profile_params,
> +};
> +
> +static const struct hp_wmi_board_params omen_v1_board_params = {
> + .thermal_profile = &omen_v1_thermal_params,
> + .fan_profile = &victus_s_fan_profile_params,
> +};
> +
> +static const struct hp_wmi_board_params omen_v1_legacy_board_params = {
> + .thermal_profile = &omen_v1_legacy_thermal_params,
> + .fan_profile = &victus_s_fan_profile_params,
> +};
> +
> +static const struct hp_wmi_board_params omen_v1_no_ec_board_params = {
> + .thermal_profile = &omen_v1_no_ec_thermal_params,
> + .fan_profile = &victus_s_fan_profile_params,
> +};
> +
> +static const struct hp_wmi_board_params *active_board_params;
> +
> +static const struct thermal_profile_params *hp_wmi_thermal_profile(void)
> +{
> + if (!active_board_params)
> + return NULL;
> +
> + return active_board_params->thermal_profile;
> +}
>
> /* DMI board names of devices that should use the omen specific path for
> * thermal profiles.
> @@ -187,67 +228,67 @@ static const char * const victus_thermal_profile_boards[] = {
> "8A25",
> };
>
> -/* DMI Board names of Victus 16-r and Victus 16-s laptops */
> -static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = {
> +/* DMI board-specific feature data for Omen and Victus laptops. */
> +static const struct dmi_system_id hp_wmi_feature_boards[] __initconst = {
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A44") },
> - .driver_data = (void *)&omen_v1_legacy_thermal_params,
> + .driver_data = (void *)&omen_v1_legacy_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A4D") },
> - .driver_data = (void *)&omen_v1_legacy_thermal_params,
> + .driver_data = (void *)&omen_v1_legacy_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") },
> - .driver_data = (void *)&omen_v1_thermal_params,
> + .driver_data = (void *)&omen_v1_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") },
> - .driver_data = (void *)&victus_s_thermal_params,
> + .driver_data = (void *)&victus_s_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCA") },
> - .driver_data = (void *)&omen_v1_thermal_params,
> + .driver_data = (void *)&omen_v1_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") },
> - .driver_data = (void *)&omen_v1_thermal_params,
> + .driver_data = (void *)&omen_v1_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") },
> - .driver_data = (void *)&victus_s_thermal_params,
> + .driver_data = (void *)&victus_s_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD5") },
> - .driver_data = (void *)&victus_s_thermal_params,
> + .driver_data = (void *)&victus_s_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C76") },
> - .driver_data = (void *)&omen_v1_thermal_params,
> + .driver_data = (void *)&omen_v1_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C77") },
> - .driver_data = (void *)&omen_v1_thermal_params,
> + .driver_data = (void *)&omen_v1_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C78") },
> - .driver_data = (void *)&omen_v1_thermal_params,
> + .driver_data = (void *)&omen_v1_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C99") },
> - .driver_data = (void *)&victus_s_thermal_params,
> + .driver_data = (void *)&victus_s_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C9C") },
> - .driver_data = (void *)&victus_s_thermal_params,
> + .driver_data = (void *)&victus_s_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8D41") },
> - .driver_data = (void *)&victus_s_thermal_params,
> + .driver_data = (void *)&victus_s_board_params,
> },
> {
> .matches = { DMI_MATCH(DMI_BOARD_NAME, "8D87") },
> - .driver_data = (void *)&omen_v1_no_ec_thermal_params,
> + .driver_data = (void *)&omen_v1_no_ec_board_params,
> },
> {},
> };
> @@ -1769,6 +1810,38 @@ static bool is_victus_s_thermal_profile(void)
> return is_victus_s_board;
> }
>
> +static const struct hp_wmi_fan_profile_params *hp_wmi_fan_profile(void)
> +{
> + if (!active_board_params)
> + return NULL;
> +
> + return active_board_params->fan_profile;
> +}
> +
> +static bool hp_wmi_fan_control_supported(void)
> +{
> + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> +
> + return params && params->get_fan_speed;
> +}
> +
> +static bool hp_wmi_fan_table_supported(void)
> +{
> + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> +
> + return params && params->fan_table;
> +}
> +
> +static int hp_wmi_get_active_fan_speed(int fan)
> +{
> + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> +
> + if (!params || !params->get_fan_speed)
> + return -EOPNOTSUPP;
> +
> + return params->get_fan_speed(fan);
> +}
> +
> static int victus_s_gpu_thermal_profile_get(bool *ctgp_enable,
> bool *ppab_enable,
> u8 *dstate,
> @@ -1854,7 +1927,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> u8 current_dstate, current_gpu_slowdown_temp, tp;
> const struct thermal_profile_params *params;
>
> - params = active_thermal_profile_params;
> + params = hp_wmi_thermal_profile();
> + if (!params)
> + return -ENODEV;
> +
> if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> *profile = active_platform_profile;
> @@ -1866,10 +1942,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> return ret;
>
> /*
> - * We cannot use active_thermal_profile_params here, because boards
> - * like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
> - * it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
> - * Gaming Hub on windows. Hence accept both of these values.
> + * Boards like 8C78 have tp == 0x0 || tp == 0x1 after cold boot,
> + * but logically it should have tp == 0x30 || tp == 0x31, as
> + * corrected by the Omen Gaming Hub on windows. Hence accept both
> + * of these values.
> */
> if (tp == victus_s_thermal_params.performance ||
> tp == omen_v1_thermal_params.performance) {
> @@ -1904,12 +1980,12 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
>
> static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
> {
> - struct thermal_profile_params *params;
> + const struct thermal_profile_params *params;
> bool gpu_ctgp_enable, gpu_ppab_enable;
> u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */
> int err, tp;
>
> - params = active_thermal_profile_params;
> + params = hp_wmi_thermal_profile();
> if (!params)
> return -ENODEV;
>
> @@ -2175,6 +2251,7 @@ static const struct platform_profile_ops hp_wmi_platform_profile_ops = {
> static int thermal_profile_setup(struct platform_device *device)
> {
> const struct platform_profile_ops *ops;
> + const struct thermal_profile_params *params;
> int err, tp;
>
> if (is_omen_thermal_profile()) {
> @@ -2206,13 +2283,17 @@ static int thermal_profile_setup(struct platform_device *device)
>
> ops = &platform_profile_victus_ops;
> } else if (is_victus_s_thermal_profile()) {
> + params = hp_wmi_thermal_profile();
> + if (!params)
> + return -ENODEV;
> +
> /*
> * For an unknown EC layout board, platform_profile_victus_s_get_ec(),
> * behaves like a wrapper around active_platform_profile, to avoid using
> * uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
> */
> - if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> - active_thermal_profile_params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> + if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> + params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> active_platform_profile = PLATFORM_PROFILE_BALANCED;
> } else {
> err = platform_profile_victus_s_get_ec(&active_platform_profile);
> @@ -2380,7 +2461,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
>
> switch (priv->mode) {
> case PWM_MODE_MAX:
> - if (is_victus_s_thermal_profile()) {
> + if (hp_wmi_fan_control_supported()) {
> ret = hp_wmi_get_fan_count_userdefine_trigger();
> if (ret < 0)
> return ret;
> @@ -2392,7 +2473,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
> return 0;
> case PWM_MODE_MANUAL:
> - if (!is_victus_s_thermal_profile())
> + if (!hp_wmi_fan_control_supported())
> return -EOPNOTSUPP;
> ret = hp_wmi_fan_speed_set(priv, pwm_to_rpm(priv->pwm, priv));
> if (ret < 0)
> @@ -2401,7 +2482,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
> return 0;
> case PWM_MODE_AUTO:
> - if (is_victus_s_thermal_profile()) {
> + if (hp_wmi_fan_control_supported()) {
> ret = hp_wmi_get_fan_count_userdefine_trigger();
> if (ret < 0)
> return ret;
> @@ -2425,12 +2506,12 @@ static umode_t hp_wmi_hwmon_is_visible(const void *data,
> {
> switch (type) {
> case hwmon_pwm:
> - if (attr == hwmon_pwm_input && !is_victus_s_thermal_profile())
> + if (attr == hwmon_pwm_input && !hp_wmi_fan_control_supported())
> return 0;
> return 0644;
> case hwmon_fan:
> - if (is_victus_s_thermal_profile()) {
> - if (hp_wmi_get_fan_speed_victus_s(channel) >= 0)
> + if (hp_wmi_fan_control_supported()) {
> + if (hp_wmi_get_active_fan_speed(channel) >= 0)
> return 0444;
> } else {
> if (hp_wmi_get_fan_speed(channel) >= 0)
> @@ -2454,8 +2535,8 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> priv = dev_get_drvdata(dev);
> switch (type) {
> case hwmon_fan:
> - if (is_victus_s_thermal_profile())
> - ret = hp_wmi_get_fan_speed_victus_s(channel);
> + if (hp_wmi_fan_control_supported())
> + ret = hp_wmi_get_active_fan_speed(channel);
> else
> ret = hp_wmi_get_fan_speed(channel);
> if (ret < 0)
> @@ -2464,10 +2545,10 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> return 0;
> case hwmon_pwm:
> if (attr == hwmon_pwm_input) {
> - if (!is_victus_s_thermal_profile())
> + if (!hp_wmi_fan_control_supported())
> return -EOPNOTSUPP;
>
> - rpm = hp_wmi_get_fan_speed_victus_s(channel);
> + rpm = hp_wmi_get_active_fan_speed(channel);
> if (rpm < 0)
> return rpm;
> *val = rpm_to_pwm(rpm / 100, priv);
> @@ -2501,7 +2582,7 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
> switch (type) {
> case hwmon_pwm:
> if (attr == hwmon_pwm_input) {
> - if (!is_victus_s_thermal_profile())
> + if (!hp_wmi_fan_control_supported())
> return -EOPNOTSUPP;
> /* PWM input is invalid when not in manual mode */
> if (priv->mode != PWM_MODE_MANUAL)
> @@ -2518,13 +2599,13 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
> priv->mode = PWM_MODE_MAX;
> return hp_wmi_apply_fan_settings(priv);
> case PWM_MODE_MANUAL:
> - if (!is_victus_s_thermal_profile())
> + if (!hp_wmi_fan_control_supported())
> return -EOPNOTSUPP;
> /*
> * When switching to manual mode, set fan speed to
> * current RPM values to ensure a smooth transition.
> */
> - rpm = hp_wmi_get_fan_speed_victus_s(channel);
> + rpm = hp_wmi_get_active_fan_speed(channel);
> if (rpm < 0)
> return rpm;
> priv->pwm = rpm_to_pwm(rpm / 100, priv);
> @@ -2585,13 +2666,14 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
> u8 min_rpm, max_rpm;
> u8 cpu_rpm, gpu_rpm, noise_db;
> int gpu_delta, i, num_entries, ret;
> + bool gpu_delta_found = false;
> size_t header_size, entry_size;
>
> /* Default behaviour on hwmon init is automatic mode */
> priv->mode = PWM_MODE_AUTO;
>
> - /* Bypass all non-Victus S devices */
> - if (!is_victus_s_thermal_profile())
> + /* Bypass devices without fan control support. */
> + if (!hp_wmi_fan_table_supported())
> return 0;
>
> ret = hp_wmi_perform_query(HPWMI_VICTUS_S_GET_FAN_TABLE_QUERY,
> @@ -2625,12 +2707,15 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
> min_rpm = cpu_rpm;
> if (cpu_rpm > max_rpm)
> max_rpm = cpu_rpm;
> + if (!gpu_delta_found && gpu_rpm > 0) {
> + gpu_delta = gpu_rpm - cpu_rpm;
> + gpu_delta_found = true;
> + }
> }
>
> - if (min_rpm == U8_MAX || max_rpm == 0)
> + if (min_rpm == U8_MAX || max_rpm == 0 || !gpu_delta_found)
> return -EINVAL;
>
> - gpu_delta = fan_table->entries[0].gpu_rpm - fan_table->entries[0].cpu_rpm;
> priv->min_rpm = min_rpm;
> priv->max_rpm = max_rpm;
> priv->gpu_delta = gpu_delta;
> @@ -2673,24 +2758,25 @@ static int hp_wmi_hwmon_init(void)
> return 0;
> }
>
> -static void __init setup_active_thermal_profile_params(void)
> +static void __init setup_active_board_params(void)
> {
> const struct dmi_system_id *id;
> + const struct thermal_profile_params *params;
>
> - /*
> - * Currently only victus_s devices use the
> - * active_thermal_profile_params
> - */
> - id = dmi_first_match(victus_s_thermal_profile_boards);
> + id = dmi_first_match(hp_wmi_feature_boards);
> if (id) {
> + active_board_params = id->driver_data;
> + params = hp_wmi_thermal_profile();
> + if (!params)
> + return;
> +
> /*
> * Marking this boolean is required to ensure that
> * is_victus_s_thermal_profile() behaves like a valid
> * wrapper.
> */
> is_victus_s_board = true;
> - active_thermal_profile_params = id->driver_data;
> - if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
> + if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
> pr_warn("Unknown EC layout for board %s. Thermal profile readback will be disabled. Please report this to platform-driver-x86@vger.kernel.org\n",
> dmi_get_system_info(DMI_BOARD_NAME));
> }
> @@ -2725,10 +2811,10 @@ static int __init hp_wmi_init(void)
> }
>
> /*
> - * Setup active board's thermal profile parameters before
> - * starting platform driver probe.
> + * Setup active board feature data before starting platform
> + * driver probe.
> */
> - setup_active_thermal_profile_params();
> + setup_active_board_params();
> err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
> if (err)
> goto err_unregister_device;
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data
2026-05-21 13:02 ` Ilpo Järvinen
@ 2026-05-21 13:06 ` Radhey Kalra
2026-05-21 13:17 ` Ilpo Järvinen
0 siblings, 1 reply; 9+ messages in thread
From: Radhey Kalra @ 2026-05-21 13:06 UTC (permalink / raw)
To: Ilpo Järvinen; +Cc: platform-driver-x86, krishna.chomal108
Hi Ilpo,
Agreed, that was a mistake. The gpu_delta parsing change does not
logically belong in the board-data refactor.
I folded it into the preparatory patch while trying to reduce the
series size, but that made the patch less focused. I will split it
back out so the series is:
board-data / fan-control selection refactor
fan-table gpu_delta parsing fix
8A3D board addition
Thanks, Radhey
On Thu, May 21, 2026 at 6:33 PM Ilpo Järvinen
<ilpo.jarvinen@linux.intel.com> wrote:
>
> On Wed, 20 May 2026, Radhey Kalra wrote:
>
> > Move the Victus S thermal-profile DMI data behind hp_wmi_board_params so
> > board-specific feature data can describe thermal-profile and fan-control
> > support together.
> >
> > Use the active board data for fan-control decisions instead of checking
> > is_victus_s_thermal_profile() in the hwmon path.
>
> > Also derive gpu_delta
> > from the first non-zero GPU RPM row so fan tables whose first GPU RPM is
> > zero still produce valid fan settings.
>
> Unfortunately, moving gpu_delta things from own patch to the refactor
> patch is a step backwards.
>
> Why would it logically belong to this patch??
>
> --
> i.
>
> > No fan-control support changes intended for existing boards. Fan tables
> > with an initial zero GPU RPM row now produce a valid GPU delta.
> >
> > Signed-off-by: Radhey Kalra <radheykalra901@gmail.com>
> > ---
> > drivers/platform/x86/hp/hp-wmi.c | 204 ++++++++++++++++++++++---------
> > 1 file changed, 145 insertions(+), 59 deletions(-)
> >
> > diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
> > index d1cc6e7..dcfffe6 100644
> > --- a/drivers/platform/x86/hp/hp-wmi.c
> > +++ b/drivers/platform/x86/hp/hp-wmi.c
> > @@ -133,11 +133,52 @@ static const struct thermal_profile_params omen_v1_no_ec_thermal_params = {
> > .ec_tp_offset = HP_NO_THERMAL_PROFILE_OFFSET,
> > };
> >
> > -/*
> > - * A generic pointer for the currently-active board's thermal profile
> > - * parameters.
> > - */
> > -static struct thermal_profile_params *active_thermal_profile_params;
> > +struct hp_wmi_fan_profile_params {
> > + int (*get_fan_speed)(int fan);
> > + bool fan_table;
> > +};
> > +
> > +struct hp_wmi_board_params {
> > + const struct thermal_profile_params *thermal_profile;
> > + const struct hp_wmi_fan_profile_params *fan_profile;
> > +};
> > +
> > +static int hp_wmi_get_fan_speed_victus_s(int fan);
> > +
> > +static const struct hp_wmi_fan_profile_params victus_s_fan_profile_params = {
> > + .get_fan_speed = hp_wmi_get_fan_speed_victus_s,
> > + .fan_table = true,
> > +};
> > +
> > +static const struct hp_wmi_board_params victus_s_board_params = {
> > + .thermal_profile = &victus_s_thermal_params,
> > + .fan_profile = &victus_s_fan_profile_params,
> > +};
> > +
> > +static const struct hp_wmi_board_params omen_v1_board_params = {
> > + .thermal_profile = &omen_v1_thermal_params,
> > + .fan_profile = &victus_s_fan_profile_params,
> > +};
> > +
> > +static const struct hp_wmi_board_params omen_v1_legacy_board_params = {
> > + .thermal_profile = &omen_v1_legacy_thermal_params,
> > + .fan_profile = &victus_s_fan_profile_params,
> > +};
> > +
> > +static const struct hp_wmi_board_params omen_v1_no_ec_board_params = {
> > + .thermal_profile = &omen_v1_no_ec_thermal_params,
> > + .fan_profile = &victus_s_fan_profile_params,
> > +};
> > +
> > +static const struct hp_wmi_board_params *active_board_params;
> > +
> > +static const struct thermal_profile_params *hp_wmi_thermal_profile(void)
> > +{
> > + if (!active_board_params)
> > + return NULL;
> > +
> > + return active_board_params->thermal_profile;
> > +}
> >
> > /* DMI board names of devices that should use the omen specific path for
> > * thermal profiles.
> > @@ -187,67 +228,67 @@ static const char * const victus_thermal_profile_boards[] = {
> > "8A25",
> > };
> >
> > -/* DMI Board names of Victus 16-r and Victus 16-s laptops */
> > -static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = {
> > +/* DMI board-specific feature data for Omen and Victus laptops. */
> > +static const struct dmi_system_id hp_wmi_feature_boards[] __initconst = {
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A44") },
> > - .driver_data = (void *)&omen_v1_legacy_thermal_params,
> > + .driver_data = (void *)&omen_v1_legacy_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A4D") },
> > - .driver_data = (void *)&omen_v1_legacy_thermal_params,
> > + .driver_data = (void *)&omen_v1_legacy_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") },
> > - .driver_data = (void *)&omen_v1_thermal_params,
> > + .driver_data = (void *)&omen_v1_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") },
> > - .driver_data = (void *)&victus_s_thermal_params,
> > + .driver_data = (void *)&victus_s_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCA") },
> > - .driver_data = (void *)&omen_v1_thermal_params,
> > + .driver_data = (void *)&omen_v1_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") },
> > - .driver_data = (void *)&omen_v1_thermal_params,
> > + .driver_data = (void *)&omen_v1_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") },
> > - .driver_data = (void *)&victus_s_thermal_params,
> > + .driver_data = (void *)&victus_s_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD5") },
> > - .driver_data = (void *)&victus_s_thermal_params,
> > + .driver_data = (void *)&victus_s_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C76") },
> > - .driver_data = (void *)&omen_v1_thermal_params,
> > + .driver_data = (void *)&omen_v1_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C77") },
> > - .driver_data = (void *)&omen_v1_thermal_params,
> > + .driver_data = (void *)&omen_v1_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C78") },
> > - .driver_data = (void *)&omen_v1_thermal_params,
> > + .driver_data = (void *)&omen_v1_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C99") },
> > - .driver_data = (void *)&victus_s_thermal_params,
> > + .driver_data = (void *)&victus_s_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C9C") },
> > - .driver_data = (void *)&victus_s_thermal_params,
> > + .driver_data = (void *)&victus_s_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8D41") },
> > - .driver_data = (void *)&victus_s_thermal_params,
> > + .driver_data = (void *)&victus_s_board_params,
> > },
> > {
> > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8D87") },
> > - .driver_data = (void *)&omen_v1_no_ec_thermal_params,
> > + .driver_data = (void *)&omen_v1_no_ec_board_params,
> > },
> > {},
> > };
> > @@ -1769,6 +1810,38 @@ static bool is_victus_s_thermal_profile(void)
> > return is_victus_s_board;
> > }
> >
> > +static const struct hp_wmi_fan_profile_params *hp_wmi_fan_profile(void)
> > +{
> > + if (!active_board_params)
> > + return NULL;
> > +
> > + return active_board_params->fan_profile;
> > +}
> > +
> > +static bool hp_wmi_fan_control_supported(void)
> > +{
> > + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> > +
> > + return params && params->get_fan_speed;
> > +}
> > +
> > +static bool hp_wmi_fan_table_supported(void)
> > +{
> > + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> > +
> > + return params && params->fan_table;
> > +}
> > +
> > +static int hp_wmi_get_active_fan_speed(int fan)
> > +{
> > + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> > +
> > + if (!params || !params->get_fan_speed)
> > + return -EOPNOTSUPP;
> > +
> > + return params->get_fan_speed(fan);
> > +}
> > +
> > static int victus_s_gpu_thermal_profile_get(bool *ctgp_enable,
> > bool *ppab_enable,
> > u8 *dstate,
> > @@ -1854,7 +1927,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> > u8 current_dstate, current_gpu_slowdown_temp, tp;
> > const struct thermal_profile_params *params;
> >
> > - params = active_thermal_profile_params;
> > + params = hp_wmi_thermal_profile();
> > + if (!params)
> > + return -ENODEV;
> > +
> > if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> > params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> > *profile = active_platform_profile;
> > @@ -1866,10 +1942,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> > return ret;
> >
> > /*
> > - * We cannot use active_thermal_profile_params here, because boards
> > - * like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
> > - * it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
> > - * Gaming Hub on windows. Hence accept both of these values.
> > + * Boards like 8C78 have tp == 0x0 || tp == 0x1 after cold boot,
> > + * but logically it should have tp == 0x30 || tp == 0x31, as
> > + * corrected by the Omen Gaming Hub on windows. Hence accept both
> > + * of these values.
> > */
> > if (tp == victus_s_thermal_params.performance ||
> > tp == omen_v1_thermal_params.performance) {
> > @@ -1904,12 +1980,12 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> >
> > static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
> > {
> > - struct thermal_profile_params *params;
> > + const struct thermal_profile_params *params;
> > bool gpu_ctgp_enable, gpu_ppab_enable;
> > u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */
> > int err, tp;
> >
> > - params = active_thermal_profile_params;
> > + params = hp_wmi_thermal_profile();
> > if (!params)
> > return -ENODEV;
> >
> > @@ -2175,6 +2251,7 @@ static const struct platform_profile_ops hp_wmi_platform_profile_ops = {
> > static int thermal_profile_setup(struct platform_device *device)
> > {
> > const struct platform_profile_ops *ops;
> > + const struct thermal_profile_params *params;
> > int err, tp;
> >
> > if (is_omen_thermal_profile()) {
> > @@ -2206,13 +2283,17 @@ static int thermal_profile_setup(struct platform_device *device)
> >
> > ops = &platform_profile_victus_ops;
> > } else if (is_victus_s_thermal_profile()) {
> > + params = hp_wmi_thermal_profile();
> > + if (!params)
> > + return -ENODEV;
> > +
> > /*
> > * For an unknown EC layout board, platform_profile_victus_s_get_ec(),
> > * behaves like a wrapper around active_platform_profile, to avoid using
> > * uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
> > */
> > - if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> > - active_thermal_profile_params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> > + if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> > + params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> > active_platform_profile = PLATFORM_PROFILE_BALANCED;
> > } else {
> > err = platform_profile_victus_s_get_ec(&active_platform_profile);
> > @@ -2380,7 +2461,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> >
> > switch (priv->mode) {
> > case PWM_MODE_MAX:
> > - if (is_victus_s_thermal_profile()) {
> > + if (hp_wmi_fan_control_supported()) {
> > ret = hp_wmi_get_fan_count_userdefine_trigger();
> > if (ret < 0)
> > return ret;
> > @@ -2392,7 +2473,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
> > return 0;
> > case PWM_MODE_MANUAL:
> > - if (!is_victus_s_thermal_profile())
> > + if (!hp_wmi_fan_control_supported())
> > return -EOPNOTSUPP;
> > ret = hp_wmi_fan_speed_set(priv, pwm_to_rpm(priv->pwm, priv));
> > if (ret < 0)
> > @@ -2401,7 +2482,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
> > return 0;
> > case PWM_MODE_AUTO:
> > - if (is_victus_s_thermal_profile()) {
> > + if (hp_wmi_fan_control_supported()) {
> > ret = hp_wmi_get_fan_count_userdefine_trigger();
> > if (ret < 0)
> > return ret;
> > @@ -2425,12 +2506,12 @@ static umode_t hp_wmi_hwmon_is_visible(const void *data,
> > {
> > switch (type) {
> > case hwmon_pwm:
> > - if (attr == hwmon_pwm_input && !is_victus_s_thermal_profile())
> > + if (attr == hwmon_pwm_input && !hp_wmi_fan_control_supported())
> > return 0;
> > return 0644;
> > case hwmon_fan:
> > - if (is_victus_s_thermal_profile()) {
> > - if (hp_wmi_get_fan_speed_victus_s(channel) >= 0)
> > + if (hp_wmi_fan_control_supported()) {
> > + if (hp_wmi_get_active_fan_speed(channel) >= 0)
> > return 0444;
> > } else {
> > if (hp_wmi_get_fan_speed(channel) >= 0)
> > @@ -2454,8 +2535,8 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> > priv = dev_get_drvdata(dev);
> > switch (type) {
> > case hwmon_fan:
> > - if (is_victus_s_thermal_profile())
> > - ret = hp_wmi_get_fan_speed_victus_s(channel);
> > + if (hp_wmi_fan_control_supported())
> > + ret = hp_wmi_get_active_fan_speed(channel);
> > else
> > ret = hp_wmi_get_fan_speed(channel);
> > if (ret < 0)
> > @@ -2464,10 +2545,10 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> > return 0;
> > case hwmon_pwm:
> > if (attr == hwmon_pwm_input) {
> > - if (!is_victus_s_thermal_profile())
> > + if (!hp_wmi_fan_control_supported())
> > return -EOPNOTSUPP;
> >
> > - rpm = hp_wmi_get_fan_speed_victus_s(channel);
> > + rpm = hp_wmi_get_active_fan_speed(channel);
> > if (rpm < 0)
> > return rpm;
> > *val = rpm_to_pwm(rpm / 100, priv);
> > @@ -2501,7 +2582,7 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
> > switch (type) {
> > case hwmon_pwm:
> > if (attr == hwmon_pwm_input) {
> > - if (!is_victus_s_thermal_profile())
> > + if (!hp_wmi_fan_control_supported())
> > return -EOPNOTSUPP;
> > /* PWM input is invalid when not in manual mode */
> > if (priv->mode != PWM_MODE_MANUAL)
> > @@ -2518,13 +2599,13 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
> > priv->mode = PWM_MODE_MAX;
> > return hp_wmi_apply_fan_settings(priv);
> > case PWM_MODE_MANUAL:
> > - if (!is_victus_s_thermal_profile())
> > + if (!hp_wmi_fan_control_supported())
> > return -EOPNOTSUPP;
> > /*
> > * When switching to manual mode, set fan speed to
> > * current RPM values to ensure a smooth transition.
> > */
> > - rpm = hp_wmi_get_fan_speed_victus_s(channel);
> > + rpm = hp_wmi_get_active_fan_speed(channel);
> > if (rpm < 0)
> > return rpm;
> > priv->pwm = rpm_to_pwm(rpm / 100, priv);
> > @@ -2585,13 +2666,14 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > u8 min_rpm, max_rpm;
> > u8 cpu_rpm, gpu_rpm, noise_db;
> > int gpu_delta, i, num_entries, ret;
> > + bool gpu_delta_found = false;
> > size_t header_size, entry_size;
> >
> > /* Default behaviour on hwmon init is automatic mode */
> > priv->mode = PWM_MODE_AUTO;
> >
> > - /* Bypass all non-Victus S devices */
> > - if (!is_victus_s_thermal_profile())
> > + /* Bypass devices without fan control support. */
> > + if (!hp_wmi_fan_table_supported())
> > return 0;
> >
> > ret = hp_wmi_perform_query(HPWMI_VICTUS_S_GET_FAN_TABLE_QUERY,
> > @@ -2625,12 +2707,15 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > min_rpm = cpu_rpm;
> > if (cpu_rpm > max_rpm)
> > max_rpm = cpu_rpm;
> > + if (!gpu_delta_found && gpu_rpm > 0) {
> > + gpu_delta = gpu_rpm - cpu_rpm;
> > + gpu_delta_found = true;
> > + }
> > }
> >
> > - if (min_rpm == U8_MAX || max_rpm == 0)
> > + if (min_rpm == U8_MAX || max_rpm == 0 || !gpu_delta_found)
> > return -EINVAL;
> >
> > - gpu_delta = fan_table->entries[0].gpu_rpm - fan_table->entries[0].cpu_rpm;
> > priv->min_rpm = min_rpm;
> > priv->max_rpm = max_rpm;
> > priv->gpu_delta = gpu_delta;
> > @@ -2673,24 +2758,25 @@ static int hp_wmi_hwmon_init(void)
> > return 0;
> > }
> >
> > -static void __init setup_active_thermal_profile_params(void)
> > +static void __init setup_active_board_params(void)
> > {
> > const struct dmi_system_id *id;
> > + const struct thermal_profile_params *params;
> >
> > - /*
> > - * Currently only victus_s devices use the
> > - * active_thermal_profile_params
> > - */
> > - id = dmi_first_match(victus_s_thermal_profile_boards);
> > + id = dmi_first_match(hp_wmi_feature_boards);
> > if (id) {
> > + active_board_params = id->driver_data;
> > + params = hp_wmi_thermal_profile();
> > + if (!params)
> > + return;
> > +
> > /*
> > * Marking this boolean is required to ensure that
> > * is_victus_s_thermal_profile() behaves like a valid
> > * wrapper.
> > */
> > is_victus_s_board = true;
> > - active_thermal_profile_params = id->driver_data;
> > - if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
> > + if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
> > pr_warn("Unknown EC layout for board %s. Thermal profile readback will be disabled. Please report this to platform-driver-x86@vger.kernel.org\n",
> > dmi_get_system_info(DMI_BOARD_NAME));
> > }
> > @@ -2725,10 +2811,10 @@ static int __init hp_wmi_init(void)
> > }
> >
> > /*
> > - * Setup active board's thermal profile parameters before
> > - * starting platform driver probe.
> > + * Setup active board feature data before starting platform
> > + * driver probe.
> > */
> > - setup_active_thermal_profile_params();
> > + setup_active_board_params();
> > err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
> > if (err)
> > goto err_unregister_device;
> >
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data
2026-05-21 13:06 ` Radhey Kalra
@ 2026-05-21 13:17 ` Ilpo Järvinen
0 siblings, 0 replies; 9+ messages in thread
From: Ilpo Järvinen @ 2026-05-21 13:17 UTC (permalink / raw)
To: Radhey Kalra; +Cc: platform-driver-x86, krishna.chomal108
[-- Attachment #1: Type: text/plain, Size: 23003 bytes --]
On Thu, 21 May 2026, Radhey Kalra wrote:
> Hi Ilpo,
>
> Agreed, that was a mistake. The gpu_delta parsing change does not
> logically belong in the board-data refactor.
>
> I folded it into the preparatory patch while trying to reduce the
> series size, but that made the patch less focused.
If we're talking about < 25 patches, you should not even think of the
series length. Many focused patches is almost always better from
reviewer's perspective than a large chunk which mixes things up (it's
also used if somebody looks these commits from git history later,
smaller changes are just easier to check for correctness).
--
i.
> I will split it
> back out so the series is:
>
> board-data / fan-control selection refactor
> fan-table gpu_delta parsing fix
> 8A3D board addition
>
> Thanks, Radhey
>
>
> On Thu, May 21, 2026 at 6:33 PM Ilpo Järvinen
> <ilpo.jarvinen@linux.intel.com> wrote:
> >
> > On Wed, 20 May 2026, Radhey Kalra wrote:
> >
> > > Move the Victus S thermal-profile DMI data behind hp_wmi_board_params so
> > > board-specific feature data can describe thermal-profile and fan-control
> > > support together.
> > >
> > > Use the active board data for fan-control decisions instead of checking
> > > is_victus_s_thermal_profile() in the hwmon path.
> >
> > > Also derive gpu_delta
> > > from the first non-zero GPU RPM row so fan tables whose first GPU RPM is
> > > zero still produce valid fan settings.
> >
> > Unfortunately, moving gpu_delta things from own patch to the refactor
> > patch is a step backwards.
> >
> > Why would it logically belong to this patch??
> >
> > --
> > i.
> >
> > > No fan-control support changes intended for existing boards. Fan tables
> > > with an initial zero GPU RPM row now produce a valid GPU delta.
> > >
> > > Signed-off-by: Radhey Kalra <radheykalra901@gmail.com>
> > > ---
> > > drivers/platform/x86/hp/hp-wmi.c | 204 ++++++++++++++++++++++---------
> > > 1 file changed, 145 insertions(+), 59 deletions(-)
> > >
> > > diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
> > > index d1cc6e7..dcfffe6 100644
> > > --- a/drivers/platform/x86/hp/hp-wmi.c
> > > +++ b/drivers/platform/x86/hp/hp-wmi.c
> > > @@ -133,11 +133,52 @@ static const struct thermal_profile_params omen_v1_no_ec_thermal_params = {
> > > .ec_tp_offset = HP_NO_THERMAL_PROFILE_OFFSET,
> > > };
> > >
> > > -/*
> > > - * A generic pointer for the currently-active board's thermal profile
> > > - * parameters.
> > > - */
> > > -static struct thermal_profile_params *active_thermal_profile_params;
> > > +struct hp_wmi_fan_profile_params {
> > > + int (*get_fan_speed)(int fan);
> > > + bool fan_table;
> > > +};
> > > +
> > > +struct hp_wmi_board_params {
> > > + const struct thermal_profile_params *thermal_profile;
> > > + const struct hp_wmi_fan_profile_params *fan_profile;
> > > +};
> > > +
> > > +static int hp_wmi_get_fan_speed_victus_s(int fan);
> > > +
> > > +static const struct hp_wmi_fan_profile_params victus_s_fan_profile_params = {
> > > + .get_fan_speed = hp_wmi_get_fan_speed_victus_s,
> > > + .fan_table = true,
> > > +};
> > > +
> > > +static const struct hp_wmi_board_params victus_s_board_params = {
> > > + .thermal_profile = &victus_s_thermal_params,
> > > + .fan_profile = &victus_s_fan_profile_params,
> > > +};
> > > +
> > > +static const struct hp_wmi_board_params omen_v1_board_params = {
> > > + .thermal_profile = &omen_v1_thermal_params,
> > > + .fan_profile = &victus_s_fan_profile_params,
> > > +};
> > > +
> > > +static const struct hp_wmi_board_params omen_v1_legacy_board_params = {
> > > + .thermal_profile = &omen_v1_legacy_thermal_params,
> > > + .fan_profile = &victus_s_fan_profile_params,
> > > +};
> > > +
> > > +static const struct hp_wmi_board_params omen_v1_no_ec_board_params = {
> > > + .thermal_profile = &omen_v1_no_ec_thermal_params,
> > > + .fan_profile = &victus_s_fan_profile_params,
> > > +};
> > > +
> > > +static const struct hp_wmi_board_params *active_board_params;
> > > +
> > > +static const struct thermal_profile_params *hp_wmi_thermal_profile(void)
> > > +{
> > > + if (!active_board_params)
> > > + return NULL;
> > > +
> > > + return active_board_params->thermal_profile;
> > > +}
> > >
> > > /* DMI board names of devices that should use the omen specific path for
> > > * thermal profiles.
> > > @@ -187,67 +228,67 @@ static const char * const victus_thermal_profile_boards[] = {
> > > "8A25",
> > > };
> > >
> > > -/* DMI Board names of Victus 16-r and Victus 16-s laptops */
> > > -static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = {
> > > +/* DMI board-specific feature data for Omen and Victus laptops. */
> > > +static const struct dmi_system_id hp_wmi_feature_boards[] __initconst = {
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A44") },
> > > - .driver_data = (void *)&omen_v1_legacy_thermal_params,
> > > + .driver_data = (void *)&omen_v1_legacy_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8A4D") },
> > > - .driver_data = (void *)&omen_v1_legacy_thermal_params,
> > > + .driver_data = (void *)&omen_v1_legacy_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") },
> > > - .driver_data = (void *)&omen_v1_thermal_params,
> > > + .driver_data = (void *)&omen_v1_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") },
> > > - .driver_data = (void *)&victus_s_thermal_params,
> > > + .driver_data = (void *)&victus_s_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCA") },
> > > - .driver_data = (void *)&omen_v1_thermal_params,
> > > + .driver_data = (void *)&omen_v1_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") },
> > > - .driver_data = (void *)&omen_v1_thermal_params,
> > > + .driver_data = (void *)&omen_v1_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") },
> > > - .driver_data = (void *)&victus_s_thermal_params,
> > > + .driver_data = (void *)&victus_s_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD5") },
> > > - .driver_data = (void *)&victus_s_thermal_params,
> > > + .driver_data = (void *)&victus_s_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C76") },
> > > - .driver_data = (void *)&omen_v1_thermal_params,
> > > + .driver_data = (void *)&omen_v1_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C77") },
> > > - .driver_data = (void *)&omen_v1_thermal_params,
> > > + .driver_data = (void *)&omen_v1_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C78") },
> > > - .driver_data = (void *)&omen_v1_thermal_params,
> > > + .driver_data = (void *)&omen_v1_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C99") },
> > > - .driver_data = (void *)&victus_s_thermal_params,
> > > + .driver_data = (void *)&victus_s_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8C9C") },
> > > - .driver_data = (void *)&victus_s_thermal_params,
> > > + .driver_data = (void *)&victus_s_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8D41") },
> > > - .driver_data = (void *)&victus_s_thermal_params,
> > > + .driver_data = (void *)&victus_s_board_params,
> > > },
> > > {
> > > .matches = { DMI_MATCH(DMI_BOARD_NAME, "8D87") },
> > > - .driver_data = (void *)&omen_v1_no_ec_thermal_params,
> > > + .driver_data = (void *)&omen_v1_no_ec_board_params,
> > > },
> > > {},
> > > };
> > > @@ -1769,6 +1810,38 @@ static bool is_victus_s_thermal_profile(void)
> > > return is_victus_s_board;
> > > }
> > >
> > > +static const struct hp_wmi_fan_profile_params *hp_wmi_fan_profile(void)
> > > +{
> > > + if (!active_board_params)
> > > + return NULL;
> > > +
> > > + return active_board_params->fan_profile;
> > > +}
> > > +
> > > +static bool hp_wmi_fan_control_supported(void)
> > > +{
> > > + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> > > +
> > > + return params && params->get_fan_speed;
> > > +}
> > > +
> > > +static bool hp_wmi_fan_table_supported(void)
> > > +{
> > > + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> > > +
> > > + return params && params->fan_table;
> > > +}
> > > +
> > > +static int hp_wmi_get_active_fan_speed(int fan)
> > > +{
> > > + const struct hp_wmi_fan_profile_params *params = hp_wmi_fan_profile();
> > > +
> > > + if (!params || !params->get_fan_speed)
> > > + return -EOPNOTSUPP;
> > > +
> > > + return params->get_fan_speed(fan);
> > > +}
> > > +
> > > static int victus_s_gpu_thermal_profile_get(bool *ctgp_enable,
> > > bool *ppab_enable,
> > > u8 *dstate,
> > > @@ -1854,7 +1927,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> > > u8 current_dstate, current_gpu_slowdown_temp, tp;
> > > const struct thermal_profile_params *params;
> > >
> > > - params = active_thermal_profile_params;
> > > + params = hp_wmi_thermal_profile();
> > > + if (!params)
> > > + return -ENODEV;
> > > +
> > > if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> > > params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> > > *profile = active_platform_profile;
> > > @@ -1866,10 +1942,10 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> > > return ret;
> > >
> > > /*
> > > - * We cannot use active_thermal_profile_params here, because boards
> > > - * like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
> > > - * it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
> > > - * Gaming Hub on windows. Hence accept both of these values.
> > > + * Boards like 8C78 have tp == 0x0 || tp == 0x1 after cold boot,
> > > + * but logically it should have tp == 0x30 || tp == 0x31, as
> > > + * corrected by the Omen Gaming Hub on windows. Hence accept both
> > > + * of these values.
> > > */
> > > if (tp == victus_s_thermal_params.performance ||
> > > tp == omen_v1_thermal_params.performance) {
> > > @@ -1904,12 +1980,12 @@ static int platform_profile_victus_s_get_ec(enum platform_profile_option *profil
> > >
> > > static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
> > > {
> > > - struct thermal_profile_params *params;
> > > + const struct thermal_profile_params *params;
> > > bool gpu_ctgp_enable, gpu_ppab_enable;
> > > u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */
> > > int err, tp;
> > >
> > > - params = active_thermal_profile_params;
> > > + params = hp_wmi_thermal_profile();
> > > if (!params)
> > > return -ENODEV;
> > >
> > > @@ -2175,6 +2251,7 @@ static const struct platform_profile_ops hp_wmi_platform_profile_ops = {
> > > static int thermal_profile_setup(struct platform_device *device)
> > > {
> > > const struct platform_profile_ops *ops;
> > > + const struct thermal_profile_params *params;
> > > int err, tp;
> > >
> > > if (is_omen_thermal_profile()) {
> > > @@ -2206,13 +2283,17 @@ static int thermal_profile_setup(struct platform_device *device)
> > >
> > > ops = &platform_profile_victus_ops;
> > > } else if (is_victus_s_thermal_profile()) {
> > > + params = hp_wmi_thermal_profile();
> > > + if (!params)
> > > + return -ENODEV;
> > > +
> > > /*
> > > * For an unknown EC layout board, platform_profile_victus_s_get_ec(),
> > > * behaves like a wrapper around active_platform_profile, to avoid using
> > > * uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
> > > */
> > > - if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> > > - active_thermal_profile_params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> > > + if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
> > > + params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
> > > active_platform_profile = PLATFORM_PROFILE_BALANCED;
> > > } else {
> > > err = platform_profile_victus_s_get_ec(&active_platform_profile);
> > > @@ -2380,7 +2461,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > >
> > > switch (priv->mode) {
> > > case PWM_MODE_MAX:
> > > - if (is_victus_s_thermal_profile()) {
> > > + if (hp_wmi_fan_control_supported()) {
> > > ret = hp_wmi_get_fan_count_userdefine_trigger();
> > > if (ret < 0)
> > > return ret;
> > > @@ -2392,7 +2473,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > > secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
> > > return 0;
> > > case PWM_MODE_MANUAL:
> > > - if (!is_victus_s_thermal_profile())
> > > + if (!hp_wmi_fan_control_supported())
> > > return -EOPNOTSUPP;
> > > ret = hp_wmi_fan_speed_set(priv, pwm_to_rpm(priv->pwm, priv));
> > > if (ret < 0)
> > > @@ -2401,7 +2482,7 @@ static int hp_wmi_apply_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > > secs_to_jiffies(KEEP_ALIVE_DELAY_SECS));
> > > return 0;
> > > case PWM_MODE_AUTO:
> > > - if (is_victus_s_thermal_profile()) {
> > > + if (hp_wmi_fan_control_supported()) {
> > > ret = hp_wmi_get_fan_count_userdefine_trigger();
> > > if (ret < 0)
> > > return ret;
> > > @@ -2425,12 +2506,12 @@ static umode_t hp_wmi_hwmon_is_visible(const void *data,
> > > {
> > > switch (type) {
> > > case hwmon_pwm:
> > > - if (attr == hwmon_pwm_input && !is_victus_s_thermal_profile())
> > > + if (attr == hwmon_pwm_input && !hp_wmi_fan_control_supported())
> > > return 0;
> > > return 0644;
> > > case hwmon_fan:
> > > - if (is_victus_s_thermal_profile()) {
> > > - if (hp_wmi_get_fan_speed_victus_s(channel) >= 0)
> > > + if (hp_wmi_fan_control_supported()) {
> > > + if (hp_wmi_get_active_fan_speed(channel) >= 0)
> > > return 0444;
> > > } else {
> > > if (hp_wmi_get_fan_speed(channel) >= 0)
> > > @@ -2454,8 +2535,8 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> > > priv = dev_get_drvdata(dev);
> > > switch (type) {
> > > case hwmon_fan:
> > > - if (is_victus_s_thermal_profile())
> > > - ret = hp_wmi_get_fan_speed_victus_s(channel);
> > > + if (hp_wmi_fan_control_supported())
> > > + ret = hp_wmi_get_active_fan_speed(channel);
> > > else
> > > ret = hp_wmi_get_fan_speed(channel);
> > > if (ret < 0)
> > > @@ -2464,10 +2545,10 @@ static int hp_wmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> > > return 0;
> > > case hwmon_pwm:
> > > if (attr == hwmon_pwm_input) {
> > > - if (!is_victus_s_thermal_profile())
> > > + if (!hp_wmi_fan_control_supported())
> > > return -EOPNOTSUPP;
> > >
> > > - rpm = hp_wmi_get_fan_speed_victus_s(channel);
> > > + rpm = hp_wmi_get_active_fan_speed(channel);
> > > if (rpm < 0)
> > > return rpm;
> > > *val = rpm_to_pwm(rpm / 100, priv);
> > > @@ -2501,7 +2582,7 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
> > > switch (type) {
> > > case hwmon_pwm:
> > > if (attr == hwmon_pwm_input) {
> > > - if (!is_victus_s_thermal_profile())
> > > + if (!hp_wmi_fan_control_supported())
> > > return -EOPNOTSUPP;
> > > /* PWM input is invalid when not in manual mode */
> > > if (priv->mode != PWM_MODE_MANUAL)
> > > @@ -2518,13 +2599,13 @@ static int hp_wmi_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
> > > priv->mode = PWM_MODE_MAX;
> > > return hp_wmi_apply_fan_settings(priv);
> > > case PWM_MODE_MANUAL:
> > > - if (!is_victus_s_thermal_profile())
> > > + if (!hp_wmi_fan_control_supported())
> > > return -EOPNOTSUPP;
> > > /*
> > > * When switching to manual mode, set fan speed to
> > > * current RPM values to ensure a smooth transition.
> > > */
> > > - rpm = hp_wmi_get_fan_speed_victus_s(channel);
> > > + rpm = hp_wmi_get_active_fan_speed(channel);
> > > if (rpm < 0)
> > > return rpm;
> > > priv->pwm = rpm_to_pwm(rpm / 100, priv);
> > > @@ -2585,13 +2666,14 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > > u8 min_rpm, max_rpm;
> > > u8 cpu_rpm, gpu_rpm, noise_db;
> > > int gpu_delta, i, num_entries, ret;
> > > + bool gpu_delta_found = false;
> > > size_t header_size, entry_size;
> > >
> > > /* Default behaviour on hwmon init is automatic mode */
> > > priv->mode = PWM_MODE_AUTO;
> > >
> > > - /* Bypass all non-Victus S devices */
> > > - if (!is_victus_s_thermal_profile())
> > > + /* Bypass devices without fan control support. */
> > > + if (!hp_wmi_fan_table_supported())
> > > return 0;
> > >
> > > ret = hp_wmi_perform_query(HPWMI_VICTUS_S_GET_FAN_TABLE_QUERY,
> > > @@ -2625,12 +2707,15 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv)
> > > min_rpm = cpu_rpm;
> > > if (cpu_rpm > max_rpm)
> > > max_rpm = cpu_rpm;
> > > + if (!gpu_delta_found && gpu_rpm > 0) {
> > > + gpu_delta = gpu_rpm - cpu_rpm;
> > > + gpu_delta_found = true;
> > > + }
> > > }
> > >
> > > - if (min_rpm == U8_MAX || max_rpm == 0)
> > > + if (min_rpm == U8_MAX || max_rpm == 0 || !gpu_delta_found)
> > > return -EINVAL;
> > >
> > > - gpu_delta = fan_table->entries[0].gpu_rpm - fan_table->entries[0].cpu_rpm;
> > > priv->min_rpm = min_rpm;
> > > priv->max_rpm = max_rpm;
> > > priv->gpu_delta = gpu_delta;
> > > @@ -2673,24 +2758,25 @@ static int hp_wmi_hwmon_init(void)
> > > return 0;
> > > }
> > >
> > > -static void __init setup_active_thermal_profile_params(void)
> > > +static void __init setup_active_board_params(void)
> > > {
> > > const struct dmi_system_id *id;
> > > + const struct thermal_profile_params *params;
> > >
> > > - /*
> > > - * Currently only victus_s devices use the
> > > - * active_thermal_profile_params
> > > - */
> > > - id = dmi_first_match(victus_s_thermal_profile_boards);
> > > + id = dmi_first_match(hp_wmi_feature_boards);
> > > if (id) {
> > > + active_board_params = id->driver_data;
> > > + params = hp_wmi_thermal_profile();
> > > + if (!params)
> > > + return;
> > > +
> > > /*
> > > * Marking this boolean is required to ensure that
> > > * is_victus_s_thermal_profile() behaves like a valid
> > > * wrapper.
> > > */
> > > is_victus_s_board = true;
> > > - active_thermal_profile_params = id->driver_data;
> > > - if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
> > > + if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
> > > pr_warn("Unknown EC layout for board %s. Thermal profile readback will be disabled. Please report this to platform-driver-x86@vger.kernel.org\n",
> > > dmi_get_system_info(DMI_BOARD_NAME));
> > > }
> > > @@ -2725,10 +2811,10 @@ static int __init hp_wmi_init(void)
> > > }
> > >
> > > /*
> > > - * Setup active board's thermal profile parameters before
> > > - * starting platform driver probe.
> > > + * Setup active board feature data before starting platform
> > > + * driver probe.
> > > */
> > > - setup_active_thermal_profile_params();
> > > + setup_active_board_params();
> > > err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
> > > if (err)
> > > goto err_unregister_device;
> > >
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control
2026-05-21 12:49 ` Radhey Kalra
@ 2026-05-21 13:36 ` Krishna Chomal
0 siblings, 0 replies; 9+ messages in thread
From: Krishna Chomal @ 2026-05-21 13:36 UTC (permalink / raw)
To: Radhey Kalra; +Cc: platform-driver-x86, ilpo.jarvinen
On Thu, May 21, 2026 at 06:19:48PM +0530, Radhey Kalra wrote:
>Hi Krishna,
>
>I tested the current platform-profile behavior on 8A3D more carefully.
>
>The board already exposes the generic hp-wmi platform-profile choices:
>
>cool quiet balanced performance
>
>Writes to all choices succeed and read back correctly, and I do not
>see hp_wmi errors in dmesg.
>
>However, under full CPU load I could not confirm that these profiles
>change CPU power behavior. Across quiet/balanced/performance/cool, CPU
>frequency stayed around 3.27 GHz and the reported PPT stayed around 33
>W. Fan RPM rose somewhat later in the test, but the system was also
>heating up, so I cannot separate that from normal firmware thermal fan
>ramping.
You are right. Because your board is not registered in any list, so it
goes to a fallback route and registers quiet/balanced/performance/cool.
Changes to platform profile are handled through this chain:
hp_wmi_platform_profile_set
-> thermal_profile_set
-> hp_wmi_perform_query(HPWMI_THERMAL_PROFILE_QUERY)
For my device, when I selected victus_8a3d_board_params quirk, the driver
tried to use this query HPWMI_THERMAL_PROFILE_QUERY which failed and
caused the driver to not load. In you case, it looks like the query does
not return an error. However, not returning an error does not necessarily
imply that it is working correctly, which can be further confirmed when
you mention that changing power modes has no physical effect on the system.
>So I should not claim that platform-profile policy is meaningfully
>validated for 8A3D. What I have verified is that the Victus
>fan-control path works.
>
>That is why I avoided a plain addition to
>victus_s_thermal_profile_boards: it would move 8A3D from the existing
>generic platform-profile path to the Victus S-specific
>platform-profile path, which I have not verified on this board.
>
I think your board does need Victus-S-specific platform-profile path
because the old/legacy queries did not have any effect on the system.
>Thanks, Radhey
>
[...]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-05-21 13:36 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-20 14:07 [PATCH v5 0/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
2026-05-20 14:07 ` [PATCH v5 1/2] platform/x86: hp-wmi: Prepare Victus fan control board data Radhey Kalra
2026-05-21 13:02 ` Ilpo Järvinen
2026-05-21 13:06 ` Radhey Kalra
2026-05-21 13:17 ` Ilpo Järvinen
2026-05-20 14:07 ` [PATCH v5 2/2] platform/x86: hp-wmi: Add Victus 15-fb0xxx fan control Radhey Kalra
2026-05-20 17:50 ` [PATCH v5 0/2] " Krishna Chomal
2026-05-21 12:49 ` Radhey Kalra
2026-05-21 13:36 ` Krishna Chomal
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.