]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
hwmon: (mlxreg-fan) Separate methods of fan setting coming from different subsystems
authorVadim Pasternak <vadimp@nvidia.com>
Mon, 13 Jan 2025 08:48:58 +0000 (10:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Oct 2025 09:56:29 +0000 (11:56 +0200)
[ Upstream commit c02e4644f8ac9c501077ef5ac53ae7fc51472d49 ]

Distinct between fan speed setting request coming for hwmon and
thermal subsystems.

There are fields 'last_hwmon_state' and 'last_thermal_state' in the
structure 'mlxreg_fan_pwm', which respectively store the cooling state
set by the 'hwmon' and 'thermal' subsystem.
The purpose is to make arbitration of fan speed setting. For example, if
fan speed required to be not lower than some limit, such setting is to
be performed through 'hwmon' subsystem, thus 'thermal' subsystem will
not set fan below this limit.

Currently, the 'last_thermal_state' is also be updated by 'hwmon' causing
cooling state to never be set to a lower value.

Eliminate update of 'last_thermal_state', when request is coming from
'hwmon' subsystem.

Fixes: da74944d3a46 ("hwmon: (mlxreg-fan) Use pwm attribute for setting fan speed low limit")
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
Link: https://lore.kernel.org/r/20250113084859.27064-2-vadimp@nvidia.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/hwmon/mlxreg-fan.c

index 7514d576610480c99af4040259f9dbe0fa966734..fbb18bd3f09b9665a232365b049054efee67b9fa 100644 (file)
@@ -113,8 +113,8 @@ struct mlxreg_fan {
        int divider;
 };
 
-static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
-                                   unsigned long state);
+static int _mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
+                                    unsigned long state, bool thermal);
 
 static int
 mlxreg_fan_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
@@ -224,8 +224,9 @@ mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
                                 * last thermal state.
                                 */
                                if (pwm->last_hwmon_state >= pwm->last_thermal_state)
-                                       return mlxreg_fan_set_cur_state(pwm->cdev,
-                                                                       pwm->last_hwmon_state);
+                                       return _mlxreg_fan_set_cur_state(pwm->cdev,
+                                                                        pwm->last_hwmon_state,
+                                                                        false);
                                return 0;
                        }
                        return regmap_write(fan->regmap, pwm->reg, val);
@@ -347,9 +348,8 @@ static int mlxreg_fan_get_cur_state(struct thermal_cooling_device *cdev,
        return 0;
 }
 
-static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
-                                   unsigned long state)
-
+static int _mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
+                                    unsigned long state, bool thermal)
 {
        struct mlxreg_fan_pwm *pwm = cdev->devdata;
        struct mlxreg_fan *fan = pwm->fan;
@@ -359,7 +359,8 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
                return -EINVAL;
 
        /* Save thermal state. */
-       pwm->last_thermal_state = state;
+       if (thermal)
+               pwm->last_thermal_state = state;
 
        state = max_t(unsigned long, state, pwm->last_hwmon_state);
        err = regmap_write(fan->regmap, pwm->reg,
@@ -371,6 +372,13 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
        return 0;
 }
 
+static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
+                                   unsigned long state)
+
+{
+       return _mlxreg_fan_set_cur_state(cdev, state, true);
+}
+
 static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = {
        .get_max_state  = mlxreg_fan_get_max_state,
        .get_cur_state  = mlxreg_fan_get_cur_state,