diff options
author | Guenter Roeck <linux@roeck-us.net> | 2014-07-03 16:44:23 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-07-07 08:49:25 -0400 |
commit | 145e74a4e5022225adb84f4e5d4fff7938475c35 (patch) | |
tree | 4fd28b2112312ff139825dee37600a7f6cda7707 | |
parent | c024044d4da2c9c3b32933b4235df1e409293b84 (diff) |
hwmon: (adm1031) Fix writes to limit registers
Upper limit for write operations to temperature limit registers
was clamped to a fractional value. However, limit registers do
not support fractional values. As a result, upper limits of 127.5
degrees C or higher resulted in a rounded limit of 128 degrees C.
Since limit registers are signed, this was stored as -128 degrees C.
Clamp limits to (-55, +127) degrees C to solve the problem.
Value on writes to auto_temp[12]_min and auto_temp[12]_max were not
clamped at all, but masked. As a result, out-of-range writes resulted
in a more or less arbitrary limit. Clamp those attributes to (0, 127)
degrees C for more predictable results.
Cc: Axel Lin <axel.lin@ingics.com>
Cc: stable@vger.kernel.org
Reviewed-by: Jean Delvare <jdelvare@suse.de>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/adm1031.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index a8a540ca8c34..51c1a5a165ab 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -365,6 +365,7 @@ set_auto_temp_min(struct device *dev, struct device_attribute *attr, | |||
365 | if (ret) | 365 | if (ret) |
366 | return ret; | 366 | return ret; |
367 | 367 | ||
368 | val = clamp_val(val, 0, 127000); | ||
368 | mutex_lock(&data->update_lock); | 369 | mutex_lock(&data->update_lock); |
369 | data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); | 370 | data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); |
370 | adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), | 371 | adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), |
@@ -394,6 +395,7 @@ set_auto_temp_max(struct device *dev, struct device_attribute *attr, | |||
394 | if (ret) | 395 | if (ret) |
395 | return ret; | 396 | return ret; |
396 | 397 | ||
398 | val = clamp_val(val, 0, 127000); | ||
397 | mutex_lock(&data->update_lock); | 399 | mutex_lock(&data->update_lock); |
398 | data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], | 400 | data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], |
399 | data->pwm[nr]); | 401 | data->pwm[nr]); |
@@ -696,7 +698,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
696 | if (ret) | 698 | if (ret) |
697 | return ret; | 699 | return ret; |
698 | 700 | ||
699 | val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875); | 701 | val = clamp_val(val, -55000, 127000); |
700 | mutex_lock(&data->update_lock); | 702 | mutex_lock(&data->update_lock); |
701 | data->temp_min[nr] = TEMP_TO_REG(val); | 703 | data->temp_min[nr] = TEMP_TO_REG(val); |
702 | adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr), | 704 | adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr), |
@@ -717,7 +719,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
717 | if (ret) | 719 | if (ret) |
718 | return ret; | 720 | return ret; |
719 | 721 | ||
720 | val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875); | 722 | val = clamp_val(val, -55000, 127000); |
721 | mutex_lock(&data->update_lock); | 723 | mutex_lock(&data->update_lock); |
722 | data->temp_max[nr] = TEMP_TO_REG(val); | 724 | data->temp_max[nr] = TEMP_TO_REG(val); |
723 | adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr), | 725 | adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr), |
@@ -738,7 +740,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, | |||
738 | if (ret) | 740 | if (ret) |
739 | return ret; | 741 | return ret; |
740 | 742 | ||
741 | val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875); | 743 | val = clamp_val(val, -55000, 127000); |
742 | mutex_lock(&data->update_lock); | 744 | mutex_lock(&data->update_lock); |
743 | data->temp_crit[nr] = TEMP_TO_REG(val); | 745 | data->temp_crit[nr] = TEMP_TO_REG(val); |
744 | adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr), | 746 | adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr), |