On Fri, Jun 28, 2019 at 07:06:36PM +0000, Boyang Yu wrote: > max6658 may report unrealistically high temperature during > the driver initialization, for which, its overtemp alarm pin > also gets asserted. For certain devices implementing overtemp > protection based on that pin, it may further trigger a reset to > the device. By reproducing the problem, the wrong reading is > found to be coincident with changing the conversion rate. > > To mitigate this issue, set the stop bit before changing the > conversion rate and unset it thereafter. After such change, the > wrong reading is not reproduced. Apply this change only to the > max6657 kind for now, controlled by flag LM90_PAUSE_ON_CONFIG. > > Signed-off-by: Boyang Yu <byu@xxxxxxxxxx> Applied. Thanks, Guenter > --- > drivers/hwmon/lm90.c | 42 ++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 38 insertions(+), 4 deletions(-) > > diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c > index e562a578f20e..bd00d8eac066 100644 > --- a/drivers/hwmon/lm90.c > +++ b/drivers/hwmon/lm90.c > @@ -174,6 +174,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, > #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */ > #define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */ > #define LM90_HAVE_BROKEN_ALERT (1 << 7) /* Broken alert */ > +#define LM90_PAUSE_FOR_CONFIG (1 << 8) /* Pause conversion for config */ > > /* LM90 status */ > #define LM90_STATUS_LTHRM (1 << 0) /* local THERM limit tripped */ > @@ -367,6 +368,7 @@ static const struct lm90_params lm90_params[] = { > .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, > }, > [max6657] = { > + .flags = LM90_PAUSE_FOR_CONFIG, > .alert_alarms = 0x7c, > .max_convrate = 8, > .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, > @@ -567,6 +569,38 @@ static inline int lm90_select_remote_channel(struct i2c_client *client, > return 0; > } > > +static int lm90_write_convrate(struct i2c_client *client, > + struct lm90_data *data, int val) > +{ > + int err; > + int config_orig, config_stop; > + > + /* Save config and pause conversion */ > + if (data->flags & LM90_PAUSE_FOR_CONFIG) { > + config_orig = lm90_read_reg(client, LM90_REG_R_CONFIG1); > + if (config_orig < 0) > + return config_orig; > + config_stop = config_orig | 0x40; > + if (config_orig != config_stop) { > + err = i2c_smbus_write_byte_data(client, > + LM90_REG_W_CONFIG1, > + config_stop); > + if (err < 0) > + return err; > + } > + } > + > + /* Set conv rate */ > + err = i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, val); > + > + /* Revert change to config */ > + if (data->flags & LM90_PAUSE_FOR_CONFIG && config_orig != config_stop) > + i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, > + config_orig); > + > + return err; > +} > + > /* > * Set conversion rate. > * client->update_lock must be held when calling this function (unless we are > @@ -587,7 +621,7 @@ static int lm90_set_convrate(struct i2c_client *client, struct lm90_data *data, > if (interval >= update_interval * 3 / 4) > break; > > - err = i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, i); > + err = lm90_write_convrate(client, data, i); > data->update_interval = DIV_ROUND_CLOSEST(update_interval, 64); > return err; > } > @@ -1593,8 +1627,7 @@ static void lm90_restore_conf(void *_data) > struct i2c_client *client = data->client; > > /* Restore initial configuration */ > - i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, > - data->convrate_orig); > + lm90_write_convrate(client, data, data->convrate_orig); > i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, > data->config_orig); > } > @@ -1611,12 +1644,13 @@ static int lm90_init_client(struct i2c_client *client, struct lm90_data *data) > /* > * Start the conversions. > */ > - lm90_set_convrate(client, data, 500); /* 500ms; 2Hz conversion rate */ > config = lm90_read_reg(client, LM90_REG_R_CONFIG1); > if (config < 0) > return config; > data->config_orig = config; > > + lm90_set_convrate(client, data, 500); /* 500ms; 2Hz conversion rate */ > + > /* Check Temperature Range Select */ > if (data->kind == adt7461 || data->kind == tmp451) { > if (config & 0x04)