Skip to content

Commit 364ffd2

Browse files
nanpuyuegroeck
authored andcommitted
hwmon: (emc2305) fix pwm never being able to set lower
There are fields 'last_hwmon_state' and 'last_thermal_state' in the structure 'emc2305_cdev_data', which respectively store the cooling state set by the 'hwmon' and 'thermal' subsystem, and the driver author hopes that if the state set by 'hwmon' is lower than the value set by 'thermal', the driver will just save it without actually setting the pwm. Currently, the 'last_thermal_state' also be updated by 'hwmon', which will cause the cooling state to never be set to a lower value. This patch fixes that. Signed-off-by: Xingjiang Qiao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Fixes: 0d8400c ("hwmon: (emc2305) add support for EMC2301/2/3/5 RPM-based PWM Fan Speed Controller.") [groeck: renamed emc2305_set_cur_state_shim -> __emc2305_set_cur_state] Signed-off-by: Guenter Roeck <[email protected]>
1 parent 4d50591 commit 364ffd2

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

drivers/hwmon/emc2305.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -171,22 +171,12 @@ static int emc2305_get_max_state(struct thermal_cooling_device *cdev, unsigned l
171171
return 0;
172172
}
173173

174-
static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
174+
static int __emc2305_set_cur_state(struct emc2305_data *data, int cdev_idx, unsigned long state)
175175
{
176-
int cdev_idx, ret;
177-
struct emc2305_data *data = cdev->devdata;
176+
int ret;
178177
struct i2c_client *client = data->client;
179178
u8 val, i;
180179

181-
if (state > data->max_state)
182-
return -EINVAL;
183-
184-
cdev_idx = emc2305_get_cdev_idx(cdev);
185-
if (cdev_idx < 0)
186-
return cdev_idx;
187-
188-
/* Save thermal state. */
189-
data->cdev_data[cdev_idx].last_thermal_state = state;
190180
state = max_t(unsigned long, state, data->cdev_data[cdev_idx].last_hwmon_state);
191181

192182
val = EMC2305_PWM_STATE2DUTY(state, data->max_state, EMC2305_FAN_MAX);
@@ -211,6 +201,27 @@ static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned l
211201
return 0;
212202
}
213203

204+
static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
205+
{
206+
int cdev_idx, ret;
207+
struct emc2305_data *data = cdev->devdata;
208+
209+
if (state > data->max_state)
210+
return -EINVAL;
211+
212+
cdev_idx = emc2305_get_cdev_idx(cdev);
213+
if (cdev_idx < 0)
214+
return cdev_idx;
215+
216+
/* Save thermal state. */
217+
data->cdev_data[cdev_idx].last_thermal_state = state;
218+
ret = __emc2305_set_cur_state(data, cdev_idx, state);
219+
if (ret < 0)
220+
return ret;
221+
222+
return 0;
223+
}
224+
214225
static const struct thermal_cooling_device_ops emc2305_cooling_ops = {
215226
.get_max_state = emc2305_get_max_state,
216227
.get_cur_state = emc2305_get_cur_state,
@@ -401,7 +412,7 @@ emc2305_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int ch
401412
*/
402413
if (data->cdev_data[cdev_idx].last_hwmon_state >=
403414
data->cdev_data[cdev_idx].last_thermal_state)
404-
return emc2305_set_cur_state(data->cdev_data[cdev_idx].cdev,
415+
return __emc2305_set_cur_state(data, cdev_idx,
405416
data->cdev_data[cdev_idx].last_hwmon_state);
406417
return 0;
407418
}

0 commit comments

Comments
 (0)