* [PATCH v2 0/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt
@ 2022-05-18 14:48 Eddie James
2022-05-18 14:48 ` [PATCH v2 1/2] iio: pressure: dps310: Refactor startup procedure Eddie James
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Eddie James @ 2022-05-18 14:48 UTC (permalink / raw)
To: linux-iio; +Cc: linux-kernel, lars, jic23, joel, Eddie James
Corruption of the MEAS_CFG register has been observed soon after
system boot. In order to recover this scenario, check MEAS_CFG if
measurement isn't ready, and if it's incorrect, reset the DPS310
and execute the startup procedure. Include a patch to move the
startup procedure into a function.
Changes since v1:
- Separate into two patches
- Rename 'dps310_verify_meas_cfg' to 'dps310_check_reset_meas_cfg'
Eddie James (2):
iio: pressure: dps310: Refactor startup procedure
iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt
drivers/iio/pressure/dps310.c | 281 +++++++++++++++++++++-------------
1 file changed, 174 insertions(+), 107 deletions(-)
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v2 1/2] iio: pressure: dps310: Refactor startup procedure 2022-05-18 14:48 [PATCH v2 0/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James @ 2022-05-18 14:48 ` Eddie James 2022-05-18 14:48 ` [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James 2022-05-22 11:41 ` [PATCH v2 0/2] " Jonathan Cameron 2 siblings, 0 replies; 6+ messages in thread From: Eddie James @ 2022-05-18 14:48 UTC (permalink / raw) To: linux-iio; +Cc: linux-kernel, lars, jic23, joel, Eddie James Move the startup procedure into a function, and correct a missing check on the return code for writing the PRS_CFG register. Signed-off-by: Eddie James <eajames@linux.ibm.com> --- drivers/iio/pressure/dps310.c | 192 ++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 89 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 36fb7ae0d0a9..f79b274bb38d 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -159,6 +159,106 @@ static int dps310_get_coefs(struct dps310_data *data) return 0; } +/* + * Some verions of chip will read temperatures in the ~60C range when + * its actually ~20C. This is the manufacturer recommended workaround + * to correct the issue. The registers used below are undocumented. + */ +static int dps310_temp_workaround(struct dps310_data *data) +{ + int rc; + int reg; + + rc = regmap_read(data->regmap, 0x32, ®); + if (rc < 0) + return rc; + + /* + * If bit 1 is set then the device is okay, and the workaround does not + * need to be applied + */ + if (reg & BIT(1)) + return 0; + + rc = regmap_write(data->regmap, 0x0e, 0xA5); + if (rc < 0) + return rc; + + rc = regmap_write(data->regmap, 0x0f, 0x96); + if (rc < 0) + return rc; + + rc = regmap_write(data->regmap, 0x62, 0x02); + if (rc < 0) + return rc; + + rc = regmap_write(data->regmap, 0x0e, 0x00); + if (rc < 0) + return rc; + + return regmap_write(data->regmap, 0x0f, 0x00); +} + +static int dps310_startup(struct dps310_data *data) +{ + int rc; + int ready; + + /* + * Set up pressure sensor in single sample, one measurement per second + * mode + */ + rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); + if (rc < 0) + return rc; + + /* + * Set up external (MEMS) temperature sensor in single sample, one + * measurement per second mode + */ + rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); + if (rc < 0) + return rc; + + /* Temp and pressure shifts are disabled when PRC <= 8 */ + rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, + DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); + if (rc < 0) + return rc; + + /* MEAS_CFG doesn't update correctly unless first written with 0 */ + rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, + DPS310_MEAS_CTRL_BITS, 0); + if (rc < 0) + return rc; + + /* Turn on temperature and pressure measurement in the background */ + rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, + DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | + DPS310_TEMP_EN | DPS310_BACKGROUND); + if (rc < 0) + return rc; + + /* + * Calibration coefficients required for reporting temperature. + * They are available 40ms after the device has started + */ + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, + ready & DPS310_COEF_RDY, 10000, 40000); + if (rc < 0) + return rc; + + rc = dps310_get_coefs(data); + if (rc < 0) + return rc; + + rc = dps310_temp_workaround(data); + if (rc < 0) + return rc; + + return 0; +} + static int dps310_get_pres_precision(struct dps310_data *data) { int rc; @@ -677,52 +777,12 @@ static const struct iio_info dps310_info = { .write_raw = dps310_write_raw, }; -/* - * Some verions of chip will read temperatures in the ~60C range when - * its actually ~20C. This is the manufacturer recommended workaround - * to correct the issue. The registers used below are undocumented. - */ -static int dps310_temp_workaround(struct dps310_data *data) -{ - int rc; - int reg; - - rc = regmap_read(data->regmap, 0x32, ®); - if (rc < 0) - return rc; - - /* - * If bit 1 is set then the device is okay, and the workaround does not - * need to be applied - */ - if (reg & BIT(1)) - return 0; - - rc = regmap_write(data->regmap, 0x0e, 0xA5); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x0f, 0x96); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x62, 0x02); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x0e, 0x00); - if (rc < 0) - return rc; - - return regmap_write(data->regmap, 0x0f, 0x00); -} - static int dps310_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct dps310_data *data; struct iio_dev *iio; - int rc, ready; + int rc; iio = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!iio) @@ -747,54 +807,8 @@ static int dps310_probe(struct i2c_client *client, if (rc) return rc; - /* - * Set up pressure sensor in single sample, one measurement per second - * mode - */ - rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); - - /* - * Set up external (MEMS) temperature sensor in single sample, one - * measurement per second mode - */ - rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); - if (rc < 0) - return rc; - - /* Temp and pressure shifts are disabled when PRC <= 8 */ - rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, - DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); - if (rc < 0) - return rc; - - /* MEAS_CFG doesn't update correctly unless first written with 0 */ - rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, - DPS310_MEAS_CTRL_BITS, 0); - if (rc < 0) - return rc; - - /* Turn on temperature and pressure measurement in the background */ - rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, - DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | - DPS310_TEMP_EN | DPS310_BACKGROUND); - if (rc < 0) - return rc; - - /* - * Calibration coefficients required for reporting temperature. - * They are available 40ms after the device has started - */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_COEF_RDY, 10000, 40000); - if (rc < 0) - return rc; - - rc = dps310_get_coefs(data); - if (rc < 0) - return rc; - - rc = dps310_temp_workaround(data); - if (rc < 0) + rc = dps310_startup(data); + if (rc) return rc; rc = devm_iio_device_register(&client->dev, iio); -- 2.27.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt 2022-05-18 14:48 [PATCH v2 0/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James 2022-05-18 14:48 ` [PATCH v2 1/2] iio: pressure: dps310: Refactor startup procedure Eddie James @ 2022-05-18 14:48 ` Eddie James 2022-05-24 2:12 ` Joel Stanley 2022-05-22 11:41 ` [PATCH v2 0/2] " Jonathan Cameron 2 siblings, 1 reply; 6+ messages in thread From: Eddie James @ 2022-05-18 14:48 UTC (permalink / raw) To: linux-iio; +Cc: linux-kernel, lars, jic23, joel, Eddie James Corruption of the MEAS_CFG register has been observed soon after system boot. In order to recover this scenario, check MEAS_CFG if measurement isn't ready, and if it's incorrect, reset the DPS310 and execute the startup procedure. Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310") Signed-off-by: Eddie James <eajames@linux.ibm.com> --- drivers/iio/pressure/dps310.c | 89 ++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 18 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index f79b274bb38d..c6d02679ef33 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -397,6 +397,39 @@ static int dps310_get_temp_k(struct dps310_data *data) return scale_factors[ilog2(rc)]; } +/* Called with lock held */ +static int dps310_check_reset_meas_cfg(struct dps310_data *data, int ready_bit) +{ + int en = DPS310_PRS_EN | DPS310_TEMP_EN | DPS310_BACKGROUND; + int meas_cfg; + int rc = regmap_read(data->regmap, DPS310_MEAS_CFG, &meas_cfg); + + if (rc < 0) + return rc; + + if (meas_cfg & ready_bit) + return 0; + + if ((meas_cfg & en) != en) { + /* DPS310 register state corrupt, better start from scratch */ + rc = regmap_write(data->regmap, DPS310_RESET, + DPS310_RESET_MAGIC); + if (rc < 0) + return rc; + + /* Wait for device chip access: 2.5ms in specification */ + usleep_range(2500, 12000); + rc = dps310_startup(data); + if (rc) + return rc; + + dev_info(&data->client->dev, + "recovered from corrupted MEAS_CFG=%02x\n", meas_cfg); + } + + return 1; +} + static int dps310_read_pres_raw(struct dps310_data *data) { int rc; @@ -409,15 +442,25 @@ static int dps310_read_pres_raw(struct dps310_data *data) if (mutex_lock_interruptible(&data->lock)) return -EINTR; - rate = dps310_get_pres_samp_freq(data); - timeout = DPS310_POLL_TIMEOUT_US(rate); - - /* Poll for sensor readiness; base the timeout upon the sample rate. */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_PRS_RDY, - DPS310_POLL_SLEEP_US(timeout), timeout); - if (rc) - goto done; + rc = dps310_check_reset_meas_cfg(data, DPS310_PRS_RDY); + if (rc) { + if (rc < 0) + goto done; + + rate = dps310_get_pres_samp_freq(data); + timeout = DPS310_POLL_TIMEOUT_US(rate); + + /* + * Poll for sensor readiness; base the timeout upon the sample + * rate. + */ + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, + ready, ready & DPS310_PRS_RDY, + DPS310_POLL_SLEEP_US(timeout), + timeout); + if (rc) + goto done; + } rc = regmap_bulk_read(data->regmap, DPS310_PRS_BASE, val, sizeof(val)); if (rc < 0) @@ -458,15 +501,25 @@ static int dps310_read_temp_raw(struct dps310_data *data) if (mutex_lock_interruptible(&data->lock)) return -EINTR; - rate = dps310_get_temp_samp_freq(data); - timeout = DPS310_POLL_TIMEOUT_US(rate); - - /* Poll for sensor readiness; base the timeout upon the sample rate. */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_TMP_RDY, - DPS310_POLL_SLEEP_US(timeout), timeout); - if (rc < 0) - goto done; + rc = dps310_check_reset_meas_cfg(data, DPS310_TMP_RDY); + if (rc) { + if (rc < 0) + goto done; + + rate = dps310_get_temp_samp_freq(data); + timeout = DPS310_POLL_TIMEOUT_US(rate); + + /* + * Poll for sensor readiness; base the timeout upon the sample + * rate. + */ + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, + ready, ready & DPS310_TMP_RDY, + DPS310_POLL_SLEEP_US(timeout), + timeout); + if (rc < 0) + goto done; + } rc = dps310_read_temp_ready(data); -- 2.27.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt 2022-05-18 14:48 ` [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James @ 2022-05-24 2:12 ` Joel Stanley 2022-05-24 14:18 ` Eddie James 0 siblings, 1 reply; 6+ messages in thread From: Joel Stanley @ 2022-05-24 2:12 UTC (permalink / raw) To: Eddie James Cc: linux-iio, Linux Kernel Mailing List, Lars-Peter Clausen, Jonathan Cameron On Wed, 18 May 2022 at 14:48, Eddie James <eajames@linux.ibm.com> wrote: > > Corruption of the MEAS_CFG register has been observed soon after > system boot. In order to recover this scenario, check MEAS_CFG if > measurement isn't ready, and if it's incorrect, reset the DPS310 > and execute the startup procedure. I have some suggestions below on how to rework to make the code easier to understand. But before we got to that, I had some high level questions: You don't seem to be setting the en bits in the CFG register after doing the reset. Is that required? Are we ok to sleep for 2.5ms in the iio_info->read_raw callback? > > Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310") > Signed-off-by: Eddie James <eajames@linux.ibm.com> > --- > drivers/iio/pressure/dps310.c | 89 ++++++++++++++++++++++++++++------- > 1 file changed, 71 insertions(+), 18 deletions(-) > > diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c > index f79b274bb38d..c6d02679ef33 100644 > --- a/drivers/iio/pressure/dps310.c > +++ b/drivers/iio/pressure/dps310.c > @@ -397,6 +397,39 @@ static int dps310_get_temp_k(struct dps310_data *data) > return scale_factors[ilog2(rc)]; > } > > +/* Called with lock held */ Perhaps add this to your comment: Returns a negative value on error, a positive value when the device is not ready (and may have been reset due to corruption), and zero when the device is ready. > +static int dps310_check_reset_meas_cfg(struct dps310_data *data, int ready_bit) > +{ > + int en = DPS310_PRS_EN | DPS310_TEMP_EN | DPS310_BACKGROUND; > + int meas_cfg; > + int rc = regmap_read(data->regmap, DPS310_MEAS_CFG, &meas_cfg); > + > + if (rc < 0) > + return rc; > + > + if (meas_cfg & ready_bit) > + return 0; > + > + if ((meas_cfg & en) != en) { > + /* DPS310 register state corrupt, better start from scratch */ > + rc = regmap_write(data->regmap, DPS310_RESET, > + DPS310_RESET_MAGIC); > + if (rc < 0) > + return rc; > + > + /* Wait for device chip access: 2.5ms in specification */ > + usleep_range(2500, 12000); > + rc = dps310_startup(data); > + if (rc) > + return rc; > + > + dev_info(&data->client->dev, > + "recovered from corrupted MEAS_CFG=%02x\n", meas_cfg); > + } > + > + return 1; I'm confused about this case. We get there when the device doesn't have ready_bit set in meas_cfg and we've done a reset, but we also get here when the bit isn't set and we haven't done anything to resolve it (after re-reading the code I understand now, but perhaps reworking it as follows will make it clear): Could we write it like this: if (meas_cfg & ready_bit) { /* Device ready, must be okay */ return 0; } if (meas_cfg & en) { /* Device okay (but not ready), no action required */ return 1; } /* DPS310 register state corrupt, better start from scratch */ ... return 1; > +} > + > static int dps310_read_pres_raw(struct dps310_data *data) > { > int rc; > @@ -409,15 +442,25 @@ static int dps310_read_pres_raw(struct dps310_data *data) > if (mutex_lock_interruptible(&data->lock)) > return -EINTR; > > - rate = dps310_get_pres_samp_freq(data); > - timeout = DPS310_POLL_TIMEOUT_US(rate); > - > - /* Poll for sensor readiness; base the timeout upon the sample rate. */ > - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, > - ready & DPS310_PRS_RDY, > - DPS310_POLL_SLEEP_US(timeout), timeout); > - if (rc) > - goto done; > + rc = dps310_check_reset_meas_cfg(data, DPS310_PRS_RDY); can we do this: if (rc < 0) goto done; if (rc > 0) { } The rework I suggest makes it clearer that we've considered the '0' case, when the device is ready before this code runs. > + if (rc) { > + if (rc < 0) > + goto done; > + > + rate = dps310_get_pres_samp_freq(data); > + timeout = DPS310_POLL_TIMEOUT_US(rate); > + > + /* > + * Poll for sensor readiness; base the timeout upon the sample > + * rate. > + */ > + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, > + ready, ready & DPS310_PRS_RDY, > + DPS310_POLL_SLEEP_US(timeout), > + timeout); > + if (rc) > + goto done; > + } > > rc = regmap_bulk_read(data->regmap, DPS310_PRS_BASE, val, sizeof(val)); > if (rc < 0) > @@ -458,15 +501,25 @@ static int dps310_read_temp_raw(struct dps310_data *data) > if (mutex_lock_interruptible(&data->lock)) > return -EINTR; > > - rate = dps310_get_temp_samp_freq(data); > - timeout = DPS310_POLL_TIMEOUT_US(rate); > - > - /* Poll for sensor readiness; base the timeout upon the sample rate. */ > - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, > - ready & DPS310_TMP_RDY, > - DPS310_POLL_SLEEP_US(timeout), timeout); > - if (rc < 0) > - goto done; > + rc = dps310_check_reset_meas_cfg(data, DPS310_TMP_RDY); > + if (rc) { > + if (rc < 0) > + goto done; > + > + rate = dps310_get_temp_samp_freq(data); > + timeout = DPS310_POLL_TIMEOUT_US(rate); > + > + /* > + * Poll for sensor readiness; base the timeout upon the sample > + * rate. > + */ > + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, > + ready, ready & DPS310_TMP_RDY, > + DPS310_POLL_SLEEP_US(timeout), > + timeout); > + if (rc < 0) > + goto done; > + } > > rc = dps310_read_temp_ready(data); > > -- > 2.27.0 > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt 2022-05-24 2:12 ` Joel Stanley @ 2022-05-24 14:18 ` Eddie James 0 siblings, 0 replies; 6+ messages in thread From: Eddie James @ 2022-05-24 14:18 UTC (permalink / raw) To: Joel Stanley Cc: linux-iio, Linux Kernel Mailing List, Lars-Peter Clausen, Jonathan Cameron On 5/23/22 21:12, Joel Stanley wrote: > On Wed, 18 May 2022 at 14:48, Eddie James <eajames@linux.ibm.com> wrote: >> Corruption of the MEAS_CFG register has been observed soon after >> system boot. In order to recover this scenario, check MEAS_CFG if >> measurement isn't ready, and if it's incorrect, reset the DPS310 >> and execute the startup procedure. > I have some suggestions below on how to rework to make the code easier > to understand. But before we got to that, I had some high level > questions: > > > You don't seem to be setting the en bits in the CFG register after > doing the reset. Is that required? It does set the enable bits in the startup procedure, called after the reset. > > Are we ok to sleep for 2.5ms in the iio_info->read_raw callback? I believe it's safe... the code already has a mutex, so its not called in atomic context. > > >> Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310") >> Signed-off-by: Eddie James <eajames@linux.ibm.com> >> --- >> drivers/iio/pressure/dps310.c | 89 ++++++++++++++++++++++++++++------- >> 1 file changed, 71 insertions(+), 18 deletions(-) >> >> diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c >> index f79b274bb38d..c6d02679ef33 100644 >> --- a/drivers/iio/pressure/dps310.c >> +++ b/drivers/iio/pressure/dps310.c >> @@ -397,6 +397,39 @@ static int dps310_get_temp_k(struct dps310_data *data) >> return scale_factors[ilog2(rc)]; >> } >> >> +/* Called with lock held */ > Perhaps add this to your comment: Returns a negative value on error, a > positive value when the device is not ready (and may have been reset > due to corruption), and zero when the device is ready. Good idea. > >> +static int dps310_check_reset_meas_cfg(struct dps310_data *data, int ready_bit) >> +{ >> + int en = DPS310_PRS_EN | DPS310_TEMP_EN | DPS310_BACKGROUND; >> + int meas_cfg; >> + int rc = regmap_read(data->regmap, DPS310_MEAS_CFG, &meas_cfg); >> + >> + if (rc < 0) >> + return rc; >> + >> + if (meas_cfg & ready_bit) >> + return 0; >> + >> + if ((meas_cfg & en) != en) { >> + /* DPS310 register state corrupt, better start from scratch */ >> + rc = regmap_write(data->regmap, DPS310_RESET, >> + DPS310_RESET_MAGIC); >> + if (rc < 0) >> + return rc; >> + >> + /* Wait for device chip access: 2.5ms in specification */ >> + usleep_range(2500, 12000); >> + rc = dps310_startup(data); >> + if (rc) >> + return rc; >> + >> + dev_info(&data->client->dev, >> + "recovered from corrupted MEAS_CFG=%02x\n", meas_cfg); >> + } >> + >> + return 1; > I'm confused about this case. We get there when the device doesn't > have ready_bit set in meas_cfg and we've done a reset, but we also get > here when the bit isn't set and we haven't done anything to resolve it > (after re-reading the code I understand now, but perhaps reworking it > as follows will make it clear): > > Could we write it like this: > > if (meas_cfg & ready_bit) { > /* Device ready, must be okay */ > return 0; > } > > if (meas_cfg & en) { > /* Device okay (but not ready), no action required */ > return 1; > } > > /* DPS310 register state corrupt, better start from scratch */ > ... > return 1; Yea it could be clearer, I can update that. > > >> +} >> + >> static int dps310_read_pres_raw(struct dps310_data *data) >> { >> int rc; >> @@ -409,15 +442,25 @@ static int dps310_read_pres_raw(struct dps310_data *data) >> if (mutex_lock_interruptible(&data->lock)) >> return -EINTR; >> >> - rate = dps310_get_pres_samp_freq(data); >> - timeout = DPS310_POLL_TIMEOUT_US(rate); >> - >> - /* Poll for sensor readiness; base the timeout upon the sample rate. */ >> - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, >> - ready & DPS310_PRS_RDY, >> - DPS310_POLL_SLEEP_US(timeout), timeout); >> - if (rc) >> - goto done; >> + rc = dps310_check_reset_meas_cfg(data, DPS310_PRS_RDY); > can we do this: > > if (rc < 0) > goto done; > > if (rc > 0) { > > } > > The rework I suggest makes it clearer that we've considered the '0' > case, when the device is ready before this code runs. Sure. Thanks for the review, I'll get a v3 up. Thanks, Eddie > >> + if (rc) { >> + if (rc < 0) >> + goto done; >> + >> + rate = dps310_get_pres_samp_freq(data); >> + timeout = DPS310_POLL_TIMEOUT_US(rate); >> + >> + /* >> + * Poll for sensor readiness; base the timeout upon the sample >> + * rate. >> + */ >> + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, >> + ready, ready & DPS310_PRS_RDY, >> + DPS310_POLL_SLEEP_US(timeout), >> + timeout); >> + if (rc) >> + goto done; >> + } >> >> rc = regmap_bulk_read(data->regmap, DPS310_PRS_BASE, val, sizeof(val)); >> if (rc < 0) >> @@ -458,15 +501,25 @@ static int dps310_read_temp_raw(struct dps310_data *data) >> if (mutex_lock_interruptible(&data->lock)) >> return -EINTR; >> >> - rate = dps310_get_temp_samp_freq(data); >> - timeout = DPS310_POLL_TIMEOUT_US(rate); >> - >> - /* Poll for sensor readiness; base the timeout upon the sample rate. */ >> - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, >> - ready & DPS310_TMP_RDY, >> - DPS310_POLL_SLEEP_US(timeout), timeout); >> - if (rc < 0) >> - goto done; >> + rc = dps310_check_reset_meas_cfg(data, DPS310_TMP_RDY); >> + if (rc) { >> + if (rc < 0) >> + goto done; >> + >> + rate = dps310_get_temp_samp_freq(data); >> + timeout = DPS310_POLL_TIMEOUT_US(rate); >> + >> + /* >> + * Poll for sensor readiness; base the timeout upon the sample >> + * rate. >> + */ >> + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, >> + ready, ready & DPS310_TMP_RDY, >> + DPS310_POLL_SLEEP_US(timeout), >> + timeout); >> + if (rc < 0) >> + goto done; >> + } >> >> rc = dps310_read_temp_ready(data); >> >> -- >> 2.27.0 >> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt 2022-05-18 14:48 [PATCH v2 0/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James 2022-05-18 14:48 ` [PATCH v2 1/2] iio: pressure: dps310: Refactor startup procedure Eddie James 2022-05-18 14:48 ` [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James @ 2022-05-22 11:41 ` Jonathan Cameron 2 siblings, 0 replies; 6+ messages in thread From: Jonathan Cameron @ 2022-05-22 11:41 UTC (permalink / raw) To: Eddie James; +Cc: linux-iio, linux-kernel, lars, joel On Wed, 18 May 2022 09:48:16 -0500 Eddie James <eajames@linux.ibm.com> wrote: > Corruption of the MEAS_CFG register has been observed soon after > system boot. In order to recover this scenario, check MEAS_CFG if > measurement isn't ready, and if it's incorrect, reset the DPS310 > and execute the startup procedure. Include a patch to move the > startup procedure into a function. > > Changes since v1: > - Separate into two patches > - Rename 'dps310_verify_meas_cfg' to 'dps310_check_reset_meas_cfg' Looks good to me. I'll leave this a little longer on list to give Joel and others the opportunity to take a look. If I seem to have lost it in a few weeks time, feel free to ping me (it's been known to happen though I think my tracking is much less error prone now I have moved to patchwork + my local system). Jonathan > > Eddie James (2): > iio: pressure: dps310: Refactor startup procedure > iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt > > drivers/iio/pressure/dps310.c | 281 +++++++++++++++++++++------------- > 1 file changed, 174 insertions(+), 107 deletions(-) > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-05-24 14:18 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-05-18 14:48 [PATCH v2 0/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James 2022-05-18 14:48 ` [PATCH v2 1/2] iio: pressure: dps310: Refactor startup procedure Eddie James 2022-05-18 14:48 ` [PATCH v2 2/2] iio: pressure: dps310: Reset chip if MEAS_CFG is corrupt Eddie James 2022-05-24 2:12 ` Joel Stanley 2022-05-24 14:18 ` Eddie James 2022-05-22 11:41 ` [PATCH v2 0/2] " Jonathan Cameron
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox