]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: addac: stx104: Fix race condition for stx104_write_raw()
authorWilliam Breathitt Gray <william.gray@linaro.org>
Thu, 6 Apr 2023 14:40:10 +0000 (10:40 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 May 2023 14:10:51 +0000 (23:10 +0900)
commit 9740827468cea80c42db29e7171a50e99acf7328 upstream.

The priv->chan_out_states array and actual DAC value can become
mismatched if stx104_write_raw() is called concurrently. Prevent such a
race condition by utilizing a mutex.

Fixes: 97a445dad37a ("iio: Add IIO support for the DAC on the Apex Embedded Systems STX104")
Signed-off-by: William Breathitt Gray <william.gray@linaro.org>
Link: https://lore.kernel.org/r/c95c9a77fcef36b2a052282146950f23bbc1ebdc.1680790580.git.william.gray@linaro.org
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iio/addac/stx104.c

index 46b46b7a3c8ded0080acc8a12002f619d0d4553e..b658a75d4e3a86d3466e7ea4561d98153f6a4b24 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
@@ -69,10 +70,12 @@ struct stx104_reg {
 
 /**
  * struct stx104_iio - IIO device private data structure
+ * @lock: synchronization lock to prevent I/O race conditions
  * @chan_out_states:   channels' output states
  * @reg:               I/O address offset for the device registers
  */
 struct stx104_iio {
+       struct mutex lock;
        unsigned int chan_out_states[STX104_NUM_OUT_CHAN];
        struct stx104_reg __iomem *reg;
 };
@@ -182,9 +185,12 @@ static int stx104_write_raw(struct iio_dev *indio_dev,
                        if ((unsigned int)val > 65535)
                                return -EINVAL;
 
+                       mutex_lock(&priv->lock);
+
                        priv->chan_out_states[chan->channel] = val;
                        iowrite16(val, &priv->reg->dac[chan->channel]);
 
+                       mutex_unlock(&priv->lock);
                        return 0;
                }
                return -EINVAL;
@@ -355,6 +361,8 @@ static int stx104_probe(struct device *dev, unsigned int id)
 
        indio_dev->name = dev_name(dev);
 
+       mutex_init(&priv->lock);
+
        /* configure device for software trigger operation */
        iowrite8(0, &priv->reg->acr);