aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2014-07-03 16:44:23 -0400
committerGuenter Roeck <linux@roeck-us.net>2014-07-07 08:49:25 -0400
commit145e74a4e5022225adb84f4e5d4fff7938475c35 (patch)
tree4fd28b2112312ff139825dee37600a7f6cda7707
parentc024044d4da2c9c3b32933b4235df1e409293b84 (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.c8
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),