diff --git a/drivers/hwmon/mlxreg-fan.c b/drivers/hwmon/mlxreg-fan.c
index 4a8becdb0d58..daae8741ff2b 100644
--- a/drivers/hwmon/mlxreg-fan.c
+++ b/drivers/hwmon/mlxreg-fan.c
@@ -18,15 +18,6 @@
 #define MLXREG_FAN_MAX_STATE		10
 #define MLXREG_FAN_MIN_DUTY		51	/* 20% */
 #define MLXREG_FAN_MAX_DUTY		255	/* 100% */
-/*
- * Minimum and maximum FAN allowed speed in percent: from 20% to 100%. Values
- * MLXREG_FAN_MAX_STATE + x, where x is between 2 and 10 are used for
- * setting FAN speed dynamic minimum. For example, if value is set to 14 (40%)
- * cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to
- * introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100.
- */
-#define MLXREG_FAN_SPEED_MIN			(MLXREG_FAN_MAX_STATE + 2)
-#define MLXREG_FAN_SPEED_MAX			(MLXREG_FAN_MAX_STATE * 2)
 #define MLXREG_FAN_SPEED_MIN_LEVEL		2	/* 20 percent */
 #define MLXREG_FAN_TACHO_SAMPLES_PER_PULSE_DEF	44
 #define MLXREG_FAN_TACHO_DIV_MIN		283
@@ -87,6 +78,7 @@ struct mlxreg_fan_tacho {
  * @connected: indicates if PWM is connected;
  * @reg: register offset;
  * @cooling: cooling device levels;
+ * @last_thermal_state: last cooling state set by thermal subsystem;
  * @cdev: cooling device;
  */
 struct mlxreg_fan_pwm {
@@ -94,6 +86,7 @@ struct mlxreg_fan_pwm {
 	bool connected;
 	u32 reg;
 	u8 cooling_levels[MLXREG_FAN_MAX_STATE + 1];
+	unsigned long last_thermal_state;
 	struct thermal_cooling_device *cdev;
 };
 
@@ -107,6 +100,7 @@ struct mlxreg_fan_pwm {
  * @tachos_per_drwr - number of tachometers per drawer;
  * @samples: minimum allowed samples per pulse;
  * @divider: divider value for tachometer RPM calculation;
+ * @pwm_limit_set: callback to set minimum limit for PWM;
  */
 struct mlxreg_fan {
 	struct device *dev;
@@ -117,6 +111,7 @@ struct mlxreg_fan {
 	int tachos_per_drwr;
 	int samples;
 	int divider;
+	int (*pwm_limit_set)(struct mlxreg_fan *fan, struct mlxreg_fan_pwm *pwm, long val);
 };
 
 static int
@@ -204,6 +199,7 @@ mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 {
 	struct mlxreg_fan *fan = dev_get_drvdata(dev);
 	struct mlxreg_fan_pwm *pwm;
+	int err;
 
 	switch (type) {
 	case hwmon_pwm:
@@ -213,7 +209,11 @@ mlxreg_fan_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
 			    val > MLXREG_FAN_MAX_DUTY)
 				return -EINVAL;
 			pwm = &fan->pwm[channel];
-			return regmap_write(fan->regmap, pwm->reg, val);
+			/* If thermal is configured - handle PWM limit setting. */
+			if (!err && fan->pwm_limit_set)
+				return fan->pwm_limit_set(fan, pwm, val);
+			err = regmap_write(fan->regmap, pwm->reg, val);
+			return err;
 		default:
 			return -EOPNOTSUPP;
 		}
@@ -338,49 +338,13 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
 {
 	struct mlxreg_fan_pwm *pwm = cdev->devdata;
 	struct mlxreg_fan *fan = pwm->fan;
-	unsigned long cur_state;
-	int i, config = 0;
-	u32 regval;
 	int err;
 
-	/*
-	 * Verify if this request is for changing allowed FAN dynamical
-	 * minimum. If it is - update cooling levels accordingly and update
-	 * state, if current state is below the newly requested minimum state.
-	 * For example, if current state is 5, and minimal state is to be
-	 * changed from 4 to 6, fan->cooling_levels[0 to 5] will be changed all
-	 * from 4 to 6. And state 5 (fan->cooling_levels[4]) should be
-	 * overwritten.
-	 */
-	if (state >= MLXREG_FAN_SPEED_MIN && state <= MLXREG_FAN_SPEED_MAX) {
-		/*
-		 * This is configuration change, which is only supported through sysfs.
-		 * For configuration non-zero value is to be returned to avoid thermal
-		 * statistics update.
-		 */
-		config = 1;
-		state -= MLXREG_FAN_MAX_STATE;
-		for (i = 0; i < state; i++)
-			pwm->cooling_levels[i] = state;
-		for (i = state; i <= MLXREG_FAN_MAX_STATE; i++)
-			pwm->cooling_levels[i] = i;
-
-		err = regmap_read(fan->regmap, pwm->reg, &regval);
-		if (err) {
-			dev_err(fan->dev, "Failed to query PWM duty\n");
-			return err;
-		}
-
-		cur_state = MLXREG_FAN_PWM_DUTY2STATE(regval);
-		if (state < cur_state)
-			return config;
-
-		state = cur_state;
-	}
-
 	if (state > MLXREG_FAN_MAX_STATE)
 		return -EINVAL;
 
+	/* Save requested thermal state. */
+	pwm->last_thermal_state = state;
 	/* Normalize the state to the valid speed range. */
 	state = pwm->cooling_levels[state];
 	err = regmap_write(fan->regmap, pwm->reg,
@@ -389,7 +353,7 @@ static int mlxreg_fan_set_cur_state(struct thermal_cooling_device *cdev,
 		dev_err(fan->dev, "Failed to write PWM duty\n");
 		return err;
 	}
-	return config;
+	return 0;
 }
 
 static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = {
@@ -562,6 +526,38 @@ static int mlxreg_fan_config(struct mlxreg_fan *fan,
 	return 0;
 }
 
+static int mlxreg_pwm_limit_set(struct mlxreg_fan *fan, struct mlxreg_fan_pwm *pwm, long val)
+{
+	unsigned long new_state;
+	int i, err = 0;
+	u32 regval;
+
+	/*
+	 * In case thermal subsystem is configured, access for PWM setting through hwmon is used
+	 * for setting fan minimum speed limit. For such case update cooling levels accordingly,
+	 * thus if cooling state has been set to 'n', fan->cooling_levels[0..n] are to be
+	 * converted to the same RPM value. Update PWM in case requested speed is above cooling
+	 * state set by thermal driver.
+	 */
+	err = regmap_read(fan->regmap, pwm->reg, &regval);
+	if (err) {
+		dev_err(fan->dev, "Failed to query PWM duty\n");
+		return err;
+	}
+
+	new_state = MLXREG_FAN_PWM_DUTY2STATE(val);
+
+	for (i = 0; i < new_state; i++)
+		pwm->cooling_levels[i] = new_state;
+	for (i = new_state; i <= MLXREG_FAN_MAX_STATE; i++)
+		pwm->cooling_levels[i] = i;
+	/* Update PWM only in case requested state is above last thermal state. */
+	if (new_state >= pwm->last_thermal_state)
+		err = regmap_write(fan->regmap, pwm->reg, MLXREG_FAN_PWM_STATE2DUTY(new_state));
+
+	return err;
+}
+
 static int mlxreg_fan_cooling_config(struct device *dev, struct mlxreg_fan *fan)
 {
 	int i, j;
@@ -586,6 +582,8 @@ static int mlxreg_fan_cooling_config(struct device *dev, struct mlxreg_fan *fan)
 			pwm->cooling_levels[j] = j;
 	}
 
+	fan->pwm_limit_set = mlxreg_pwm_limit_set;
+
 	return 0;
 }
 
