From: Guenter Roeck <linux@roeck-us.net>
To: Boyang Yu <byu@arista.com>
Cc: Jean Delvare <jdelvare@suse.com>,
linux-hwmon@vger.kernel.org, deank@arista.com, ryant@arista.com
Subject: Re: [PATCH v2] hwmon: (lm90) Fix max6658 sporadic wrong temperature reading
Date: Sun, 30 Jun 2019 13:39:03 -0700 [thread overview]
Message-ID: <20190630203903.GA24590@roeck-us.net> (raw)
In-Reply-To: <20190628190636.5565-1-byu@arista.com>
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@arista.com>
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)
prev parent reply other threads:[~2019-06-30 20:39 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-28 19:06 [PATCH v2] hwmon: (lm90) Fix max6658 sporadic wrong temperature reading Boyang Yu
2019-06-30 20:39 ` Guenter Roeck [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190630203903.GA24590@roeck-us.net \
--to=linux@roeck-us.net \
--cc=byu@arista.com \
--cc=deank@arista.com \
--cc=jdelvare@suse.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=ryant@arista.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox