aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adm1031.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-12-02 23:32:42 +0100
committerMark M. Hoffman <mhoffman@lightlink.com>2008-02-07 20:39:43 -0500
commit38a1f0e9aed014be66c474ecd9fe8513646de833 (patch)
treed7a4a529cdd6eed323cce893e70c3861ab243b37 /drivers/hwmon/adm1031.c
parentd5b0b5d62823f08ab4988e1b179fd5a9bddced31 (diff)
downloadkernel_samsung_smdk4412-38a1f0e9aed014be66c474ecd9fe8513646de833.zip
kernel_samsung_smdk4412-38a1f0e9aed014be66c474ecd9fe8513646de833.tar.gz
kernel_samsung_smdk4412-38a1f0e9aed014be66c474ecd9fe8513646de833.tar.bz2
hwmon: (adm1031) Fix register overwrite in set_fan_div()
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>
Diffstat (limited to 'drivers/hwmon/adm1031.c')
-rw-r--r--drivers/hwmon/adm1031.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 37cfc10..558d83b 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -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;
}