[PATCH v2 05/15] iio: adc: ad4134: Serialize single-read operations

From: Marcelo Schmitt

Date: Tue Sep 15 2026 - 15:14:16 EST


Protect single-sample read operations from going wrong if two or more of
them run concurrently. Serialize the data read operation so to avoid
single-sample read requests disrupting each other.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxx>
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@xxxxxxxxxx>
---
Change log v1 -> v2:
- Added {} to delimit scoped mutex usage context in single-sample read.
- Used pahole to reduce memory holes in ad4134_state struct.

drivers/iio/adc/ad4134.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ad4134.c b/drivers/iio/adc/ad4134.c
index 7400bd145d8a..7773b7af349b 100644
--- a/drivers/iio/adc/ad4134.c
+++ b/drivers/iio/adc/ad4134.c
@@ -7,6 +7,7 @@
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/crc8.h>
#include <linux/delay.h>
@@ -15,6 +16,7 @@
#include <linux/export.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
@@ -98,6 +100,11 @@ struct ad4134_state {
struct regmap *regmap;
unsigned long sys_clk_hz;
struct gpio_desc *odr_gpio;
+ /*
+ * Synchronize access to members the of driver state, and ensure
+ * atomicity of consecutive register access operations.
+ */
+ struct mutex lock;
int refin_mv;
/*
* DMA (thus cache coherency maintenance) requires the transfer buffers
@@ -257,7 +264,9 @@ static int ad4134_read_raw(struct iio_dev *indio_dev,
int ret;

switch (info) {
- case IIO_CHAN_INFO_RAW:
+ case IIO_CHAN_INFO_RAW: {
+ guard(mutex)(&st->lock);
+
gpiod_set_value_cansleep(st->odr_gpio, 1);
/*
* For slave mode gated DCLK (data sheet page 11), the minimum
@@ -276,6 +285,7 @@ static int ad4134_read_raw(struct iio_dev *indio_dev,
return ret;

return IIO_VAL_INT;
+ }
case IIO_CHAN_INFO_SCALE:
*val = st->refin_mv;
*val2 = AD4134_CHAN_PRECISION_BITS - 1;
@@ -444,6 +454,10 @@ static int ad4134_probe(struct spi_device *spi)

crc8_populate_msb(ad4134_spi_crc_table, AD4134_SPI_CRC_POLYNOM);

+ ret = devm_mutex_init(dev, &st->lock);
+ if (ret)
+ return ret;
+
st->regmap = devm_regmap_init(dev, NULL, st, &ad4134_regmap_config);
if (IS_ERR(st->regmap))
return dev_err_probe(dev, PTR_ERR(st->regmap),
--
2.53.0