diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c index ee8375d28672..11de5c70ce4d 100644 --- a/drivers/platform/x86/hp/hp-wmi.c +++ b/drivers/platform/x86/hp/hp-wmi.c @@ -133,24 +133,41 @@ static const struct thermal_profile_params omen_v1_no_ec_thermal_params = { .ec_tp_offset = HP_NO_THERMAL_PROFILE_OFFSET, }; +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; @@ -1813,6 +1830,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, @@ -2432,7 +2481,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; @@ -2444,7 +2493,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) @@ -2453,7 +2502,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; @@ -2477,12 +2526,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) @@ -2506,8 +2555,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) @@ -2516,10 +2565,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); @@ -2553,7 +2602,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) @@ -2570,13 +2619,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); @@ -2642,8 +2691,8 @@ static int hp_wmi_setup_fan_settings(struct hp_wmi_hwmon_priv *priv) /* 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,