aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/nct6775.c
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2013-06-22 19:15:31 -0400
committerGuenter Roeck <linux@roeck-us.net>2013-06-27 13:31:43 -0400
commitb1d2bff6a61140454b9d203519cc686a2e9ef32f (patch)
tree66fe81c78328fd9d3bffa5889dc7c707aead8103 /drivers/hwmon/nct6775.c
parent594fbe713bf60073ed884dc317a74dd5b327aba7 (diff)
hwmon: (nct6775) Fix temperature alarm attributes
Driver displays wrong alarms for temperature attributes. Turns out that temperature alarm bits are not fixed, but determined by temperature source mapping. To fix the problem, walk through the temperature sources to determine the correct alarm bit associated with a given attribute. Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/nct6775.c')
-rw-r--r--drivers/hwmon/nct6775.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c
index 04638aee9039..2405ab439e80 100644
--- a/drivers/hwmon/nct6775.c
+++ b/drivers/hwmon/nct6775.c
@@ -625,6 +625,7 @@ struct nct6775_data {
625 u8 has_fan_min; /* some fans don't have min register */ 625 u8 has_fan_min; /* some fans don't have min register */
626 bool has_fan_div; 626 bool has_fan_div;
627 627
628 u8 num_temp_alarms; /* 2 or 3 */
628 u8 temp_fixed_num; /* 3 or 6 */ 629 u8 temp_fixed_num; /* 3 or 6 */
629 u8 temp_type[NUM_TEMP_FIXED]; 630 u8 temp_type[NUM_TEMP_FIXED];
630 s8 temp_offset[NUM_TEMP_FIXED]; 631 s8 temp_offset[NUM_TEMP_FIXED];
@@ -1193,6 +1194,42 @@ show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1193 (unsigned int)((data->alarms >> nr) & 0x01)); 1194 (unsigned int)((data->alarms >> nr) & 0x01));
1194} 1195}
1195 1196
1197static int find_temp_source(struct nct6775_data *data, int index, int count)
1198{
1199 int source = data->temp_src[index];
1200 int nr;
1201
1202 for (nr = 0; nr < count; nr++) {
1203 int src;
1204
1205 src = nct6775_read_value(data,
1206 data->REG_TEMP_SOURCE[nr]) & 0x1f;
1207 if (src == source)
1208 return nr;
1209 }
1210 return -1;
1211}
1212
1213static ssize_t
1214show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
1215{
1216 struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
1217 struct nct6775_data *data = nct6775_update_device(dev);
1218 unsigned int alarm = 0;
1219 int nr;
1220
1221 /*
1222 * For temperatures, there is no fixed mapping from registers to alarm
1223 * bits. Alarm bits are determined by the temperature source mapping.
1224 */
1225 nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
1226 if (nr >= 0) {
1227 int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
1228 alarm = (data->alarms >> bit) & 0x01;
1229 }
1230 return sprintf(buf, "%u\n", alarm);
1231}
1232
1196static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0); 1233static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
1197static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0); 1234static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
1198static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0); 1235static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
@@ -1874,22 +1911,18 @@ static struct sensor_device_attribute sda_temp_type[] = {
1874}; 1911};
1875 1912
1876static struct sensor_device_attribute sda_temp_alarm[] = { 1913static struct sensor_device_attribute sda_temp_alarm[] = {
1877 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 1914 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0),
1878 TEMP_ALARM_BASE), 1915 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1),
1879 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 1916 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2),
1880 TEMP_ALARM_BASE + 1), 1917 SENSOR_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3),
1881 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 1918 SENSOR_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4),
1882 TEMP_ALARM_BASE + 2), 1919 SENSOR_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5),
1883 SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 1920 SENSOR_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6),
1884 TEMP_ALARM_BASE + 3), 1921 SENSOR_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7),
1885 SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 1922 SENSOR_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8),
1886 TEMP_ALARM_BASE + 4), 1923 SENSOR_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9),
1887 SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL,
1888 TEMP_ALARM_BASE + 5),
1889}; 1924};
1890 1925
1891#define NUM_TEMP_ALARM ARRAY_SIZE(sda_temp_alarm)
1892
1893static ssize_t 1926static ssize_t
1894show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) 1927show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
1895{ 1928{
@@ -3215,13 +3248,11 @@ static void nct6775_device_remove_files(struct device *dev)
3215 device_remove_file(dev, &sda_temp_max[i].dev_attr); 3248 device_remove_file(dev, &sda_temp_max[i].dev_attr);
3216 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr); 3249 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
3217 device_remove_file(dev, &sda_temp_crit[i].dev_attr); 3250 device_remove_file(dev, &sda_temp_crit[i].dev_attr);
3251 device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
3218 if (!(data->have_temp_fixed & (1 << i))) 3252 if (!(data->have_temp_fixed & (1 << i)))
3219 continue; 3253 continue;
3220 device_remove_file(dev, &sda_temp_type[i].dev_attr); 3254 device_remove_file(dev, &sda_temp_type[i].dev_attr);
3221 device_remove_file(dev, &sda_temp_offset[i].dev_attr); 3255 device_remove_file(dev, &sda_temp_offset[i].dev_attr);
3222 if (i >= NUM_TEMP_ALARM)
3223 continue;
3224 device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
3225 } 3256 }
3226 3257
3227 device_remove_file(dev, &sda_caseopen[0].dev_attr); 3258 device_remove_file(dev, &sda_caseopen[0].dev_attr);
@@ -3419,6 +3450,7 @@ static int nct6775_probe(struct platform_device *pdev)
3419 data->auto_pwm_num = 6; 3450 data->auto_pwm_num = 6;
3420 data->has_fan_div = true; 3451 data->has_fan_div = true;
3421 data->temp_fixed_num = 3; 3452 data->temp_fixed_num = 3;
3453 data->num_temp_alarms = 3;
3422 3454
3423 data->ALARM_BITS = NCT6775_ALARM_BITS; 3455 data->ALARM_BITS = NCT6775_ALARM_BITS;
3424 3456
@@ -3483,6 +3515,7 @@ static int nct6775_probe(struct platform_device *pdev)
3483 data->auto_pwm_num = 4; 3515 data->auto_pwm_num = 4;
3484 data->has_fan_div = false; 3516 data->has_fan_div = false;
3485 data->temp_fixed_num = 3; 3517 data->temp_fixed_num = 3;
3518 data->num_temp_alarms = 3;
3486 3519
3487 data->ALARM_BITS = NCT6776_ALARM_BITS; 3520 data->ALARM_BITS = NCT6776_ALARM_BITS;
3488 3521
@@ -3547,6 +3580,7 @@ static int nct6775_probe(struct platform_device *pdev)
3547 data->auto_pwm_num = 4; 3580 data->auto_pwm_num = 4;
3548 data->has_fan_div = false; 3581 data->has_fan_div = false;
3549 data->temp_fixed_num = 6; 3582 data->temp_fixed_num = 6;
3583 data->num_temp_alarms = 2;
3550 3584
3551 data->ALARM_BITS = NCT6779_ALARM_BITS; 3585 data->ALARM_BITS = NCT6779_ALARM_BITS;
3552 3586
@@ -3897,6 +3931,12 @@ static int nct6775_probe(struct platform_device *pdev)
3897 if (err) 3931 if (err)
3898 goto exit_remove; 3932 goto exit_remove;
3899 } 3933 }
3934 if (find_temp_source(data, i, data->num_temp_alarms) >= 0) {
3935 err = device_create_file(dev,
3936 &sda_temp_alarm[i].dev_attr);
3937 if (err)
3938 goto exit_remove;
3939 }
3900 if (!(data->have_temp_fixed & (1 << i))) 3940 if (!(data->have_temp_fixed & (1 << i)))
3901 continue; 3941 continue;
3902 err = device_create_file(dev, &sda_temp_type[i].dev_attr); 3942 err = device_create_file(dev, &sda_temp_type[i].dev_attr);
@@ -3905,12 +3945,6 @@ static int nct6775_probe(struct platform_device *pdev)
3905 err = device_create_file(dev, &sda_temp_offset[i].dev_attr); 3945 err = device_create_file(dev, &sda_temp_offset[i].dev_attr);
3906 if (err) 3946 if (err)
3907 goto exit_remove; 3947 goto exit_remove;
3908 if (i >= NUM_TEMP_ALARM ||
3909 data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0)
3910 continue;
3911 err = device_create_file(dev, &sda_temp_alarm[i].dev_attr);
3912 if (err)
3913 goto exit_remove;
3914 } 3948 }
3915 3949
3916 for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) { 3950 for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {