[PATCH v7 3/3] staging: iio: adc: ad7816: Fix DMA safety issues in SPI transfers

From: Abdelnasser Hussein

Date: Tue Sep 15 2026 - 04:13:25 EST


The SPI operations in this driver are not DMA safe:
1. spi_read() uses a stack-allocated buffer.
2. spi_write() in ad7816_spi_read() uses a struct member that shares a
cacheline with other variables.
3. spi_write() in ad7816_spi_write() passes a stack parameter by
reference.

Fix these violations by replacing all spi_read() and spi_write() calls
with spi_write_then_read(). This safely handles DMA by internally
allocating a bounce buffer for the transfers, avoiding cacheline
sharing issues without needing dedicated aligned buffers.
This implicitly corrects the size argument in read to sizeof(buf).

Fixes: 7024425db64a ("staging: iio: adc: new driver for AD7816 devices")
Signed-off-by: Abdelnasser Hussein <abdelnasserhussein11@xxxxxxxxx>
---
drivers/staging/iio/adc/ad7816.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index c18093ca8a82..f76f0215119a 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -74,7 +74,7 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)

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));
+ ret = spi_write_then_read(spi_dev, &chip->channel_id, sizeof(chip->channel_id), NULL, 0);
if (ret < 0) {
dev_err(&spi_dev->dev, "SPI channel setting error\n");
return ret;
@@ -96,7 +96,7 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)

gpiod_set_value(chip->rdwr_pin, 0);
gpiod_set_value(chip->rdwr_pin, 1);
- ret = spi_read(spi_dev, &buf, sizeof(*data));
+ ret = spi_write_then_read(spi_dev, NULL, 0, &buf, sizeof(buf));
if (ret < 0) {
dev_err(&spi_dev->dev, "SPI data read error\n");
return ret;
@@ -116,7 +116,7 @@ static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data)

gpiod_set_value(chip->rdwr_pin, 1);
gpiod_set_value(chip->rdwr_pin, 0);
- ret = spi_write(spi_dev, &data, sizeof(data));
+ ret = spi_write_then_read(spi_dev, &data, sizeof(data), NULL, 0);
if (ret < 0)
dev_err(&spi_dev->dev, "SPI oti data write error\n");

--
2.54.0