Commit e2ae0d4a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hwmon-for-v5.16-rc7' of...

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
parents 5b5e3d03 cdc5287a
Loading
Loading
Loading
Loading
+62 −44
Original line number Diff line number Diff line
@@ -35,13 +35,14 @@
 * explicitly as max6659, or if its address is not 0x4c.
 * These chips lack the remote temperature offset feature.
 *
 * This driver also supports the MAX6654 chip made by Maxim. This chip can
 * be at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is
 * otherwise similar to MAX6657/MAX6658/MAX6659. Extended range is available
 * by setting the configuration register accordingly, and is done during
 * initialization. Extended precision is only available at conversion rates
 * of 1 Hz and slower. Note that extended precision is not enabled by
 * default, as this driver initializes all chips to 2 Hz by design.
 * This driver also supports the MAX6654 chip made by Maxim. This chip can be
 * at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is similar
 * to MAX6657/MAX6658/MAX6659, but does not support critical temperature
 * limits. Extended range is available by setting the configuration register
 * accordingly, and is done during initialization. Extended precision is only
 * available at conversion rates of 1 Hz and slower. Note that extended
 * precision is not enabled by default, as this driver initializes all chips
 * to 2 Hz by design.
 *
 * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and
 * 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,
#define LM90_HAVE_BROKEN_ALERT	(1 << 7) /* Broken alert		*/
#define LM90_HAVE_EXTENDED_TEMP	(1 << 8) /* extended temperature support*/
#define LM90_PAUSE_FOR_CONFIG	(1 << 9) /* Pause conversion for config	*/
#define LM90_HAVE_CRIT		(1 << 10)/* Chip supports CRIT/OVERT register	*/
#define LM90_HAVE_CRIT_ALRM_SWP	(1 << 11)/* critical alarm bits swapped	*/

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

#define MAX6696_STATUS2_R2THRM	(1 << 1) /* remote2 THERM limit tripped */
#define MAX6696_STATUS2_R2OPEN	(1 << 2) /* remote2 is an open circuit */
@@ -354,38 +358,43 @@ struct lm90_params {
static const struct lm90_params lm90_params[] = {
	[adm1032] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_BROKEN_ALERT,
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 10,
	},
	[adt7461] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP
		  | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 10,
	},
	[g781] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_BROKEN_ALERT,
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 8,
	},
	[lm86] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_CRIT,
		.alert_alarms = 0x7b,
		.max_convrate = 9,
	},
	[lm90] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_CRIT,
		.alert_alarms = 0x7b,
		.max_convrate = 9,
	},
	[lm99] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_CRIT,
		.alert_alarms = 0x7b,
		.max_convrate = 9,
	},
	[max6646] = {
		.flags = LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 6,
		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
@@ -396,50 +405,51 @@ static const struct lm90_params lm90_params[] = {
		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
	},
	[max6657] = {
		.flags = LM90_PAUSE_FOR_CONFIG,
		.flags = LM90_PAUSE_FOR_CONFIG | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 8,
		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
	},
	[max6659] = {
		.flags = LM90_HAVE_EMERGENCY,
		.flags = LM90_HAVE_EMERGENCY | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 8,
		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
	},
	[max6680] = {
		.flags = LM90_HAVE_OFFSET,
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT
		  | LM90_HAVE_CRIT_ALRM_SWP,
		.alert_alarms = 0x7c,
		.max_convrate = 7,
	},
	[max6696] = {
		.flags = LM90_HAVE_EMERGENCY
		  | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3,
		  | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3 | LM90_HAVE_CRIT,
		.alert_alarms = 0x1c7c,
		.max_convrate = 6,
		.reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL,
	},
	[w83l771] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 8,
	},
	[sa56004] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT,
		.alert_alarms = 0x7b,
		.max_convrate = 9,
		.reg_local_ext = SA56004_REG_R_LOCAL_TEMPL,
	},
	[tmp451] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 9,
		.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
	},
	[tmp461] = {
		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP,
		  | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT,
		.alert_alarms = 0x7c,
		.max_convrate = 9,
		.reg_local_ext = TMP451_REG_R_LOCAL_TEMPL,
@@ -668,6 +678,7 @@ static int lm90_update_limits(struct device *dev)
	struct i2c_client *client = data->client;
	int val;

	if (data->flags & LM90_HAVE_CRIT) {
		val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
		if (val < 0)
			return val;
@@ -682,6 +693,7 @@ static int lm90_update_limits(struct device *dev)
		if (val < 0)
			return val;
		data->temp_hyst = val;
	}

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

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

	/* prevent integer underflow */
	val = max(val, -128000l);
	/* prevent integer overflow/underflow */
	val = clamp_val(val, -128000l, 255000l);

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

@@ -1217,6 +1230,9 @@ static int lm90_temp_read(struct device *dev, u32 attr, int channel, long *val)
		*val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1;
		break;
	case hwmon_temp_crit_alarm:
		if (data->flags & LM90_HAVE_CRIT_ALRM_SWP)
			*val = (data->alarms >> lm90_crit_alarm_bits_swapped[channel]) & 1;
		else
			*val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1;
		break;
	case hwmon_temp_emergency_alarm:
@@ -1465,12 +1481,11 @@ static int lm90_detect(struct i2c_client *client,
	if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0)
		return -ENODEV;

	if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) {
	if (man_id == 0x01 || man_id == 0x5C || man_id == 0xA1) {
		config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2);
		if (config2 < 0)
			return -ENODEV;
	} else
		config2 = 0;		/* Make compiler happy */
	}

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

	data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
		HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
		HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM;
		HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM;
	data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
		HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
		HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT;
		HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_FAULT;

	if (data->flags & LM90_HAVE_CRIT) {
		data->channel_config[0] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
		data->channel_config[1] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST;
	}

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