aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adm1031.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-12-02 17:32:42 -0500
committerMark M. Hoffman <mhoffman@lightlink.com>2008-02-07 20:39:43 -0500
commit38a1f0e9aed014be66c474ecd9fe8513646de833 (patch)
treed7a4a529cdd6eed323cce893e70c3861ab243b37 /drivers/hwmon/adm1031.c
parentd5b0b5d62823f08ab4988e1b179fd5a9bddced31 (diff)
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 37cfc101da5e..558d83b25b68 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)
542 return -EINVAL; 542 return -EINVAL;
543 543
544 mutex_lock(&data->update_lock); 544 mutex_lock(&data->update_lock);
545 /* Get fresh readings */
546 data->fan_div[nr] = adm1031_read_value(client,
547 ADM1031_REG_FAN_DIV(nr));
548 data->fan_min[nr] = adm1031_read_value(client,
549 ADM1031_REG_FAN_MIN(nr));
550
551 /* Write the new clock divider and fan min */
545 old_div = FAN_DIV_FROM_REG(data->fan_div[nr]); 552 old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
546 data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]); 553 data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]);
547 new_min = data->fan_min[nr] * old_div / 554 new_min = data->fan_min[nr] * old_div /
548 FAN_DIV_FROM_REG(data->fan_div[nr]); 555 FAN_DIV_FROM_REG(data->fan_div[nr]);
549 data->fan_min[nr] = new_min > 0xff ? 0xff : new_min; 556 data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
550 data->fan[nr] = data->fan[nr] * old_div /
551 FAN_DIV_FROM_REG(data->fan_div[nr]);
552 557
553 adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr), 558 adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr),
554 data->fan_div[nr]); 559 data->fan_div[nr]);
555 adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), 560 adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
556 data->fan_min[nr]); 561 data->fan_min[nr]);
562
563 /* Invalidate the cache: fan speed is no longer valid */
564 data->valid = 0;
557 mutex_unlock(&data->update_lock); 565 mutex_unlock(&data->update_lock);
558 return count; 566 return count;
559} 567}