Re: [PATCH v3 1/2] staging: iio: ad7816: serialize ad7816_spi_read() with a mutex
Jonathan Cameron <[email protected]>
| Newsgroups | org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260805005909.3137c74f@jic23-huawei> |
On Mon, 3 Aug 2026 16:43:44 +0300 Abdelnasser Hussein <[email protected]> wrote: > The ad7816_spi_read() path performs a sequence of SPI transfers and GPIO > state changes that must not be interleaved with another read operation. > > Without serialization, concurrent callers can interfere with each other, > leading to inconsistent device state and incorrect data being returned. > > Add a mutex to struct ad7816_chip_info and hold it across the entire read > sequence to ensure exclusive access to the device. > > Signed-off-by: Abdelnasser Hussein <[email protected]> Split the two ad7816 out as a series on their own. > --- > drivers/staging/iio/adc/ad7816.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c > index 0e32a2295990..b5a0c2871e00 100644 > --- a/drivers/staging/iio/adc/ad7816.c > +++ b/drivers/staging/iio/adc/ad7816.c > @@ -50,6 +50,7 @@ struct ad7816_chip_info { > u8 oti_data[AD7816_CS_MAX + 1]; > u8 channel_id; /* 0 always be temperature */ > u8 mode; > + struct mutex lock; /* protect device state during SPI transfers */ > }; > > enum ad7816_type { > @@ -67,11 +68,14 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) > int ret; > __be16 buf; > > + mutex_lock(&chip->lock); Use guard(mutex)(&chip->lock); and adjust the rest as appropriate, including adding cleanup.h if it isn't already there. > + > gpiod_set_value(chip->rdwr_pin, 1); > gpiod_set_value(chip->rdwr_pin, 0); > ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id)); > if (ret < 0) { > dev_err(&spi_dev->dev, "SPI channel setting error\n"); > + mutex_unlock(&chip->lock); > return ret; > } > gpiod_set_value(chip->rdwr_pin, 1); > @@ -94,11 +98,13 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) > ret = spi_read(spi_dev, &buf, sizeof(*data)); > if (ret < 0) { > dev_err(&spi_dev->dev, "SPI data read error\n"); > + mutex_unlock(&chip->lock); > + > return ret; > } > > *data = be16_to_cpu(buf); > - > + mutex_unlock(&chip->lock); > return ret; > } > > @@ -359,7 +365,7 @@ static int ad7816_probe(struct spi_device *spi_dev) > if (!indio_dev) > return -ENOMEM; > chip = iio_priv(indio_dev); > - > + mutex_init(&chip->lock); ret = devm_mutex_init(&chip->lock); if (ret) return ret; > chip->spi_dev = spi_dev; > for (i = 0; i <= AD7816_CS_MAX; i++) > chip->oti_data[i] = 203;