Skip to content

Commit

Permalink
hwmon: (adm1031) Fix register overwrite in set_fan_div()
Browse files Browse the repository at this point in the history
Don't rely on the register cache when setting a new fan clock divider.
For one thing, the cache might not have been initialized at all if the
driver has just been loaded. For another, the cached values may be old
and you never know what can happen in the driver's back.

Also invalidate the cache instead of trying to adjust the measured fan
speed: the whole point of changing the clock divider is to get a better
reading.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
  • Loading branch information
Jean Delvare authored and Mark M. Hoffman committed Feb 8, 2008
1 parent d5b0b5d commit 38a1f0e
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions drivers/hwmon/adm1031.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,18 +542,26 @@ set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
return -EINVAL;

mutex_lock(&data->update_lock);
/* Get fresh readings */
data->fan_div[nr] = adm1031_read_value(client,
ADM1031_REG_FAN_DIV(nr));
data->fan_min[nr] = adm1031_read_value(client,
ADM1031_REG_FAN_MIN(nr));

/* Write the new clock divider and fan min */
old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]);
new_min = data->fan_min[nr] * old_div /
FAN_DIV_FROM_REG(data->fan_div[nr]);
data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
data->fan[nr] = data->fan[nr] * old_div /
FAN_DIV_FROM_REG(data->fan_div[nr]);

adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr),
data->fan_div[nr]);
adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
data->fan_min[nr]);

/* Invalidate the cache: fan speed is no longer valid */
data->valid = 0;
mutex_unlock(&data->update_lock);
return count;
}
Expand Down

0 comments on commit 38a1f0e

Please sign in to comment.