iio: adc: ad9467: add mutex to struct ad9467_state
authorNuno Sa <nuno.sa@analog.com>
Thu, 7 Dec 2023 12:39:26 +0000 (13:39 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jan 2024 23:35:52 +0000 (15:35 -0800)
[ Upstream commit 737720197be445bb9eec2986101e4a386e019337 ]

When calling ad9467_set_scale(), multiple calls to ad9467_spi_write()
are done which means we need to properly protect the whole operation so
we are sure we will be in a sane state if two concurrent calls occur.

Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
Signed-off-by: Nuno Sa <nuno.sa@analog.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-3-a4a33bc4d70e@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/iio/adc/ad9467.c

index d3c98c4..104c6d3 100644 (file)
@@ -4,8 +4,9 @@
  *
  * Copyright 2012-2020 Analog Devices Inc.
  */
-
+#include <linux/cleanup.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -121,6 +122,8 @@ struct ad9467_state {
        unsigned int                    output_mode;
 
        struct gpio_desc                *pwrdown_gpio;
+       /* ensure consistent state obtained on multiple related accesses */
+       struct mutex                    lock;
 };
 
 static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
@@ -161,6 +164,7 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg,
        int ret;
 
        if (readval == NULL) {
+               guard(mutex)(&st->lock);
                ret = ad9467_spi_write(spi, reg, writeval);
                if (ret)
                        return ret;
@@ -310,6 +314,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
                if (scale_val[0] != val || scale_val[1] != val2)
                        continue;
 
+               guard(mutex)(&st->lock);
                ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
                                       info->scale_table[i][1]);
                if (ret < 0)