Skip to content

Commit e2ae0d4

Browse files
committed
Merge tag 'hwmon-for-v5.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon fixes from Guenter Roeck: "A couple of lm90 driver fixes. None of them are critical, but they should nevertheless be fixed" * tag 'hwmon-for-v5.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: hwmon: (lm90) Do not report 'busy' status bit as alarm hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681 hwmon: (lm90) Drop critical attribute support for MAX6654 hwmon: (lm90) Prevent integer overflow/underflow in hysteresis calculations hwmon: (lm90) Fix usage of CONFIG2 register in detect function
2 parents 5b5e3d0 + cdc5287 commit e2ae0d4

File tree

1 file changed

+62
-44
lines changed

1 file changed

+62
-44
lines changed

drivers/hwmon/lm90.c

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,14 @@
3535
* explicitly as max6659, or if its address is not 0x4c.
3636
* These chips lack the remote temperature offset feature.
3737
*
38-
* This driver also supports the MAX6654 chip made by Maxim. This chip can
39-
* be at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is
40-
* otherwise similar to MAX6657/MAX6658/MAX6659. Extended range is available
41-
* by setting the configuration register accordingly, and is done during
42-
* initialization. Extended precision is only available at conversion rates
43-
* of 1 Hz and slower. Note that extended precision is not enabled by
44-
* default, as this driver initializes all chips to 2 Hz by design.
38+
* This driver also supports the MAX6654 chip made by Maxim. This chip can be
39+
* at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is similar
40+
* to MAX6657/MAX6658/MAX6659, but does not support critical temperature
41+
* limits. Extended range is available by setting the configuration register
42+
* accordingly, and is done during initialization. Extended precision is only
43+
* available at conversion rates of 1 Hz and slower. Note that extended
44+
* precision is not enabled by default, as this driver initializes all chips
45+
* to 2 Hz by design.
4546
*
4647
* This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
4748
* MAX6692 chips made by Maxim. These are again similar to the LM86,
@@ -188,6 +189,8 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
188189
#define LM90_HAVE_BROKEN_ALERT (1 << 7) /* Broken alert */
189190
#define LM90_HAVE_EXTENDED_TEMP (1 << 8) /* extended temperature support*/
190191
#define LM90_PAUSE_FOR_CONFIG (1 << 9) /* Pause conversion for config */
192+
#define LM90_HAVE_CRIT (1 << 10)/* Chip supports CRIT/OVERT register */
193+
#define LM90_HAVE_CRIT_ALRM_SWP (1 << 11)/* critical alarm bits swapped */
191194

192195
/* LM90 status */
193196
#define LM90_STATUS_LTHRM (1 << 0) /* local THERM limit tripped */
@@ -197,6 +200,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
197200
#define LM90_STATUS_RHIGH (1 << 4) /* remote high temp limit tripped */
198201
#define LM90_STATUS_LLOW (1 << 5) /* local low temp limit tripped */
199202
#define LM90_STATUS_LHIGH (1 << 6) /* local high temp limit tripped */
203+
#define LM90_STATUS_BUSY (1 << 7) /* conversion is ongoing */
200204

201205
#define MAX6696_STATUS2_R2THRM (1 << 1) /* remote2 THERM limit tripped */
202206
#define MAX6696_STATUS2_R2OPEN (1 << 2) /* remote2 is an open circuit */
@@ -354,38 +358,43 @@ struct lm90_params {
354358
static const struct lm90_params lm90_params[] = {
355359
[adm1032] = {
356360
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
357-
| LM90_HAVE_BROKEN_ALERT,
361+
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT,
358362
.alert_alarms = 0x7c,
359363
.max_convrate = 10,
360364
},
361365
[adt7461] = {
362366
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
363-
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
367+
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP
368+
| LM90_HAVE_CRIT,
364369
.alert_alarms = 0x7c,
365370
.max_convrate = 10,
366371
},
367372
[g781] = {
368373
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
369-
| LM90_HAVE_BROKEN_ALERT,
374+
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT,
370375
.alert_alarms = 0x7c,
371376
.max_convrate = 8,
372377
},
373378
[lm86] = {
374-
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
379+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
380+
| LM90_HAVE_CRIT,
375381
.alert_alarms = 0x7b,
376382
.max_convrate = 9,
377383
},
378384
[lm90] = {
379-
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
385+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
386+
| LM90_HAVE_CRIT,
380387
.alert_alarms = 0x7b,
381388
.max_convrate = 9,
382389
},
383390
[lm99] = {
384-
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
391+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
392+
| LM90_HAVE_CRIT,
385393
.alert_alarms = 0x7b,
386394
.max_convrate = 9,
387395
},
388396
[max6646] = {
397+
.flags = LM90_HAVE_CRIT,
389398
.alert_alarms = 0x7c,
390399
.max_convrate = 6,
391400
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
@@ -396,50 +405,51 @@ static const struct lm90_params lm90_params[] = {
396405
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
397406
},
398407
[max6657] = {
399-
.flags = LM90_PAUSE_FOR_CONFIG,
408+
.flags = LM90_PAUSE_FOR_CONFIG | LM90_HAVE_CRIT,
400409
.alert_alarms = 0x7c,
401410
.max_convrate = 8,
402411
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
403412
},
404413
[max6659] = {
405-
.flags = LM90_HAVE_EMERGENCY,
414+
.flags = LM90_HAVE_EMERGENCY | LM90_HAVE_CRIT,
406415
.alert_alarms = 0x7c,
407416
.max_convrate = 8,
408417
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
409418
},
410419
[max6680] = {
411-
.flags = LM90_HAVE_OFFSET,
420+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT
421+
| LM90_HAVE_CRIT_ALRM_SWP,
412422
.alert_alarms = 0x7c,
413423
.max_convrate = 7,
414424
},
415425
[max6696] = {
416426
.flags = LM90_HAVE_EMERGENCY
417-
| LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3,
427+
| LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3 | LM90_HAVE_CRIT,
418428
.alert_alarms = 0x1c7c,
419429
.max_convrate = 6,
420430
.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
421431
},
422432
[w83l771] = {
423-
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
433+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
424434
.alert_alarms = 0x7c,
425435
.max_convrate = 8,
426436
},
427437
[sa56004] = {
428-
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
438+
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
429439
.alert_alarms = 0x7b,
430440
.max_convrate = 9,
431441
.reg_local_ext = SA56004_REG_R_LOCAL_TEMPL,
432442
},
433443
[tmp451] = {
434444
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
435-
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
445+
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
436446
.alert_alarms = 0x7c,
437447
.max_convrate = 9,
438448
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
439449
},
440450
[tmp461] = {
441451
.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
442-
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
452+
| LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
443453
.alert_alarms = 0x7c,
444454
.max_convrate = 9,
445455
.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
@@ -668,20 +678,22 @@ static int lm90_update_limits(struct device *dev)
668678
struct i2c_client *client = data->client;
669679
int val;
670680

671-
val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
672-
if (val < 0)
673-
return val;
674-
data->temp8[LOCAL_CRIT] = val;
681+
if (data->flags & LM90_HAVE_CRIT) {
682+
val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
683+
if (val < 0)
684+
return val;
685+
data->temp8[LOCAL_CRIT] = val;
675686

676-
val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
677-
if (val < 0)
678-
return val;
679-
data->temp8[REMOTE_CRIT] = val;
687+
val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
688+
if (val < 0)
689+
return val;
690+
data->temp8[REMOTE_CRIT] = val;
680691

681-
val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST);
682-
if (val < 0)
683-
return val;
684-
data->temp_hyst = val;
692+
val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST);
693+
if (val < 0)
694+
return val;
695+
data->temp_hyst = val;
696+
}
685697

686698
val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH);
687699
if (val < 0)
@@ -809,7 +821,7 @@ static int lm90_update_device(struct device *dev)
809821
val = lm90_read_reg(client, LM90_REG_R_STATUS);
810822
if (val < 0)
811823
return val;
812-
data->alarms = val; /* lower 8 bit of alarms */
824+
data->alarms = val & ~LM90_STATUS_BUSY;
813825

814826
if (data->kind == max6696) {
815827
val = lm90_select_remote_channel(data, 1);
@@ -1160,8 +1172,8 @@ static int lm90_set_temphyst(struct lm90_data *data, long val)
11601172
else
11611173
temp = temp_from_s8(data->temp8[LOCAL_CRIT]);
11621174

1163-
/* prevent integer underflow */
1164-
val = max(val, -128000l);
1175+
/* prevent integer overflow/underflow */
1176+
val = clamp_val(val, -128000l, 255000l);
11651177

11661178
data->temp_hyst = hyst_to_reg(temp - val);
11671179
err = i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
@@ -1192,6 +1204,7 @@ static const u8 lm90_temp_emerg_index[3] = {
11921204
static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 };
11931205
static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 };
11941206
static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 };
1207+
static const u8 lm90_crit_alarm_bits_swapped[3] = { 1, 0, 9 };
11951208
static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 };
11961209
static const u8 lm90_fault_bits[3] = { 0, 2, 10 };
11971210

@@ -1217,7 +1230,10 @@ static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val)
12171230
*val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1;
12181231
break;
12191232
case hwmon_temp_crit_alarm:
1220-
*val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1;
1233+
if (data->flags & LM90_HAVE_CRIT_ALRM_SWP)
1234+
*val = (data->alarms >> lm90_crit_alarm_bits_swapped[channel]) & 1;
1235+
else
1236+
*val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1;
12211237
break;
12221238
case hwmon_temp_emergency_alarm:
12231239
*val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1;
@@ -1465,12 +1481,11 @@ static int lm90_detect(struct i2c_client *client,
14651481
if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
14661482
return -ENODEV;
14671483

1468-
if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
1484+
if (man_id == 0x01 || man_id == 0x5C || man_id == 0xA1) {
14691485
config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
14701486
if (config2 < 0)
14711487
return -ENODEV;
1472-
} else
1473-
config2 = 0; /* Make compiler happy */
1488+
}
14741489

14751490
if ((address == 0x4C || address == 0x4D)
14761491
&& man_id == 0x01) { /* National Semiconductor */
@@ -1903,11 +1918,14 @@ static int lm90_probe(struct i2c_client *client)
19031918
info->config = data->channel_config;
19041919

19051920
data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
1906-
HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
1907-
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM;
1921+
HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM;
19081922
data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
1909-
HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
1910-
HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT;
1923+
HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_FAULT;
1924+
1925+
if (data->flags & LM90_HAVE_CRIT) {
1926+
data->channel_config[0] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
1927+
data->channel_config[1] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
1928+
}
19111929

19121930
if (data->flags & LM90_HAVE_OFFSET)
19131931
data->channel_config[1] |= HWMON_T_OFFSET;

0 commit comments

Comments
 (0)