From: Rupesh Majhi <zoone.rupert@gmail.com>
To: "Andy Shevchenko" <andy@kernel.org>,
"Bill Wendling" <morbo@google.com>,
"David Lechner" <dlechner@baylibre.com>,
"Eddie James" <eajames@linux.ibm.com>,
"Joel Stanley" <joel@jms.id.au>,
"Jonathan Cameron" <jic23@kernel.org>,
"Justin Stitt" <justinstitt@google.com>,
"Nathan Chancellor" <nathan@kernel.org>,
"Nick Desaulniers" <ndesaulniers@google.com>,
"Nuno Sá" <nuno.sa@analog.com>
Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
llvm@lists.linux.dev, Rupesh Majhi <zoone.rupert@gmail.com>
Subject: [PATCH v7 04/10] iio: pressure: dps310: take the lock once per raw read
Date: Fri, 18 Sep 2026 15:25:11 +0300 [thread overview]
Message-ID: <20260918122517.377565-5-zoone.rupert@gmail.com> (raw)
In-Reply-To: <20260918122517.377565-1-zoone.rupert@gmail.com>
A processed pressure read takes the lock twice: once in the raw read,
then again when dps310_calculate_pressure() trylocks to refresh the
temperature. The refresh is skipped whenever the lock is busy.
Split the raw reads into variants that expect the lock held and give each
channel a helper that takes it once for the whole sequence, so the
temperature refresh is unconditional. Buffered capture later in this
series needs the same shape.
Mark the functions that need the lock with __must_hold() rather than a
comment, and include cleanup.h, which ACQUIRE() needs and was coming in
transitively.
Assisted-by: LLM
Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com>
---
drivers/iio/pressure/dps310.c | 143 ++++++++++++++++++----------------
1 file changed, 77 insertions(+), 66 deletions(-)
diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
index e7f173e08e01..8cefca928077 100644
--- a/drivers/iio/pressure/dps310.c
+++ b/drivers/iio/pressure/dps310.c
@@ -14,6 +14,7 @@
* - Optionally support the FIFO
*/
+#include <linux/cleanup.h>
#include <linux/i2c.h>
#include <linux/limits.h>
#include <linux/math64.h>
@@ -287,8 +288,8 @@ static int dps310_get_temp_precision(struct dps310_data *data, int *val)
return 0;
}
-/* Called with lock held */
static int dps310_set_pres_precision(struct dps310_data *data, int val)
+ __must_hold(&data->lock)
{
int rc;
u8 shift_en;
@@ -306,8 +307,8 @@ static int dps310_set_pres_precision(struct dps310_data *data, int val)
DPS310_PRS_PRC_BITS, ilog2(val));
}
-/* Called with lock held */
static int dps310_set_temp_precision(struct dps310_data *data, int val)
+ __must_hold(&data->lock)
{
int rc;
u8 shift_en;
@@ -325,8 +326,8 @@ static int dps310_set_temp_precision(struct dps310_data *data, int val)
DPS310_TMP_PRC_BITS, ilog2(val));
}
-/* Called with lock held */
static int dps310_set_pres_samp_freq(struct dps310_data *data, int freq)
+ __must_hold(&data->lock)
{
u8 val;
@@ -339,8 +340,8 @@ static int dps310_set_pres_samp_freq(struct dps310_data *data, int freq)
DPS310_PRS_RATE_BITS, val);
}
-/* Called with lock held */
static int dps310_set_temp_samp_freq(struct dps310_data *data, int freq)
+ __must_hold(&data->lock)
{
u8 val;
@@ -439,6 +440,7 @@ static int dps310_ready_status(struct dps310_data *data, int ready_bit, int time
}
static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout)
+ __must_hold(&data->lock)
{
int rc;
@@ -464,40 +466,36 @@ static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout)
return 0;
}
-static int dps310_read_pres_raw(struct dps310_data *data)
+static int dps310_read_pres_raw_locked(struct dps310_data *data)
+ __must_hold(&data->lock)
{
int rc;
int rate;
int timeout;
u8 val[3];
- if (mutex_lock_interruptible(&data->lock))
- return -EINTR;
-
rc = dps310_get_pres_samp_freq(data, &rate);
if (rc)
- goto done;
+ return rc;
timeout = DPS310_POLL_TIMEOUT_US(rate);
/* Poll for sensor readiness; base the timeout upon the sample rate. */
rc = dps310_ready(data, DPS310_PRS_RDY, timeout);
if (rc)
- goto done;
+ return rc;
rc = regmap_bulk_read(data->regmap, DPS310_PRS_BASE, val, sizeof(val));
if (rc < 0)
- goto done;
+ return rc;
data->pressure_raw = sign_extend32(get_unaligned_be24(val), 23);
-done:
- mutex_unlock(&data->lock);
- return rc;
+ return 0;
}
-/* Called with lock held */
static int dps310_read_temp_ready(struct dps310_data *data)
+ __must_hold(&data->lock)
{
int rc;
u8 val[3];
@@ -511,31 +509,40 @@ static int dps310_read_temp_ready(struct dps310_data *data)
return 0;
}
-static int dps310_read_temp_raw(struct dps310_data *data)
+static int dps310_read_temp_raw_locked(struct dps310_data *data)
+ __must_hold(&data->lock)
{
int rc;
int rate;
int timeout;
- if (mutex_lock_interruptible(&data->lock))
- return -EINTR;
-
rc = dps310_get_temp_samp_freq(data, &rate);
if (rc)
- goto done;
+ return rc;
timeout = DPS310_POLL_TIMEOUT_US(rate);
/* Poll for sensor readiness; base the timeout upon the sample rate. */
rc = dps310_ready(data, DPS310_TMP_RDY, timeout);
if (rc)
- goto done;
+ return rc;
+
+ return dps310_read_temp_ready(data);
+}
+
+/* Best effort: on error the previous temperature stands */
+static void dps310_refresh_temp_locked(struct dps310_data *data)
+ __must_hold(&data->lock)
+{
+ int rc;
+ int t_ready;
- rc = dps310_read_temp_ready(data);
+ rc = regmap_read(data->regmap, DPS310_MEAS_CFG, &t_ready);
+ if (rc)
+ return;
-done:
- mutex_unlock(&data->lock);
- return rc;
+ if (t_ready & DPS310_TMP_RDY)
+ dps310_read_temp_ready(data);
}
static bool dps310_is_writeable_reg(struct device *dev, unsigned int reg)
@@ -577,59 +584,47 @@ static int dps310_write_raw(struct iio_dev *iio,
struct iio_chan_spec const *chan, int val,
int val2, long mask)
{
- int rc;
struct dps310_data *data = iio_priv(iio);
- if (mutex_lock_interruptible(&data->lock))
+ ACQUIRE(mutex_intr, lock)(&data->lock);
+ if (ACQUIRE_ERR(mutex_intr, &lock))
return -EINTR;
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
switch (chan->type) {
case IIO_PRESSURE:
- rc = dps310_set_pres_samp_freq(data, val);
- break;
+ return dps310_set_pres_samp_freq(data, val);
case IIO_TEMP:
- rc = dps310_set_temp_samp_freq(data, val);
- break;
+ return dps310_set_temp_samp_freq(data, val);
default:
- rc = -EINVAL;
- break;
+ return -EINVAL;
}
- break;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
switch (chan->type) {
case IIO_PRESSURE:
- rc = dps310_set_pres_precision(data, val);
- break;
+ return dps310_set_pres_precision(data, val);
case IIO_TEMP:
- rc = dps310_set_temp_precision(data, val);
- break;
+ return dps310_set_temp_precision(data, val);
default:
- rc = -EINVAL;
- break;
+ return -EINVAL;
}
- break;
default:
- rc = -EINVAL;
- break;
+ return -EINVAL;
}
-
- mutex_unlock(&data->lock);
- return rc;
}
static int dps310_calculate_pressure(struct dps310_data *data, int *val)
+ __must_hold(&data->lock)
{
int i;
int rc;
- int t_ready;
int kpi;
int kti;
s64 rem = 0ULL;
@@ -653,15 +648,6 @@ static int dps310_calculate_pressure(struct dps310_data *data, int *val)
kp = (s64)kpi;
kt = (s64)kti;
- /* Refresh temp if it's ready, otherwise just use the latest value */
- if (mutex_trylock(&data->lock)) {
- rc = regmap_read(data->regmap, DPS310_MEAS_CFG, &t_ready);
- if (rc >= 0 && t_ready & DPS310_TMP_RDY)
- dps310_read_temp_ready(data);
-
- mutex_unlock(&data->lock);
- }
-
p = (s64)data->pressure_raw;
t = (s64)data->temp_raw;
@@ -707,6 +693,23 @@ static int dps310_calculate_pressure(struct dps310_data *data, int *val)
return 0;
}
+static int dps310_read_pressure_value(struct dps310_data *data, int *val)
+{
+ int rc;
+
+ ACQUIRE(mutex_intr, lock)(&data->lock);
+ if (ACQUIRE_ERR(mutex_intr, &lock))
+ return -EINTR;
+
+ rc = dps310_read_pres_raw_locked(data);
+ if (rc)
+ return rc;
+
+ dps310_refresh_temp_locked(data);
+
+ return dps310_calculate_pressure(data, val);
+}
+
static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2,
long mask)
{
@@ -721,11 +724,7 @@ static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2,
return IIO_VAL_INT;
case IIO_CHAN_INFO_PROCESSED:
- rc = dps310_read_pres_raw(data);
- if (rc)
- return rc;
-
- rc = dps310_calculate_pressure(data, val);
+ rc = dps310_read_pressure_value(data, val);
if (rc)
return rc;
@@ -744,6 +743,7 @@ static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2,
}
static int dps310_calculate_temp(struct dps310_data *data, int *val)
+ __must_hold(&data->lock)
{
s64 c0;
s64 t;
@@ -765,6 +765,21 @@ static int dps310_calculate_temp(struct dps310_data *data, int *val)
return 0;
}
+static int dps310_read_temp_value(struct dps310_data *data, int *val)
+{
+ int rc;
+
+ ACQUIRE(mutex_intr, lock)(&data->lock);
+ if (ACQUIRE_ERR(mutex_intr, &lock))
+ return -EINTR;
+
+ rc = dps310_read_temp_raw_locked(data);
+ if (rc)
+ return rc;
+
+ return dps310_calculate_temp(data, val);
+}
+
static int dps310_read_temp(struct dps310_data *data, int *val, int *val2,
long mask)
{
@@ -779,11 +794,7 @@ static int dps310_read_temp(struct dps310_data *data, int *val, int *val2,
return IIO_VAL_INT;
case IIO_CHAN_INFO_PROCESSED:
- rc = dps310_read_temp_raw(data);
- if (rc)
- return rc;
-
- rc = dps310_calculate_temp(data, val);
+ rc = dps310_read_temp_value(data, val);
if (rc)
return rc;
--
2.43.0
next prev parent reply other threads:[~2026-09-18 12:25 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 12:25 [PATCH v7 00/10] iio: pressure: dps310: FIFO and triggered buffer support Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 01/10] iio: pressure: dps310: fix CFG_REG bit definitions Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 02/10] iio: pressure: dps310: use a local device pointer in probe Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 03/10] iio: pressure: dps310: use get_unaligned_be24() for the 24-bit results Rupesh Majhi
2026-09-18 12:25 ` Rupesh Majhi [this message]
2026-09-18 12:25 ` [PATCH v7 05/10] iio: pressure: dps310: add triggered buffer support Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 06/10] iio: core: add an accessor for scan_timestamp Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 07/10] iio: pressure: dps310: read buffered samples from the hardware FIFO Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 08/10] iio: pressure: dps310: derive the drain interval from the watermark Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 09/10] iio: pressure: dps310: implement .hwfifo_flush_to_buffer() Rupesh Majhi
2026-09-18 12:25 ` [PATCH v7 10/10] iio: pressure: dps310: check the lock markings with context analysis Rupesh Majhi
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=20260918122517.377565-5-zoone.rupert@gmail.com \
--to=zoone.rupert@gmail.com \
--cc=andy@kernel.org \
--cc=dlechner@baylibre.com \
--cc=eajames@linux.ibm.com \
--cc=jic23@kernel.org \
--cc=joel@jms.id.au \
--cc=justinstitt@google.com \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=nuno.sa@analog.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
all inboxes | Powered by JetHome®