OSDN Git Service

iio: dac: ad7303: replace mlock with own lock
authorAlexandru Ardelean <alexandru.ardelean@analog.com>
Mon, 7 Oct 2019 08:26:42 +0000 (11:26 +0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Tue, 15 Oct 2019 20:11:07 +0000 (21:11 +0100)
This change replaces indio_dev's mlock with the driver's own lock. The lock
is mostly needed to protect state when changing the `dac_cache` info.
The lock has been extended to `ad7303_read_raw()`, to make sure that the
cache is updated if an SPI-write is already in progress.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/dac/ad7303.c

index 8de9f40..14bbac6 100644 (file)
@@ -41,6 +41,7 @@ struct ad7303_state {
        struct regulator *vdd_reg;
        struct regulator *vref_reg;
 
+       struct mutex lock;
        /*
         * DMA (thus cache coherency maintenance) requires the
         * transfer buffers to live in their own cache lines.
@@ -79,7 +80,7 @@ static ssize_t ad7303_write_dac_powerdown(struct iio_dev *indio_dev,
        if (ret)
                return ret;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&st->lock);
 
        if (pwr_down)
                st->config |= AD7303_CFG_POWER_DOWN(chan->channel);
@@ -90,7 +91,7 @@ static ssize_t ad7303_write_dac_powerdown(struct iio_dev *indio_dev,
         * mode, so just write one of the DAC channels again */
        ad7303_write(st, chan->channel, st->dac_cache[chan->channel]);
 
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&st->lock);
        return len;
 }
 
@@ -116,7 +117,9 @@ static int ad7303_read_raw(struct iio_dev *indio_dev,
 
        switch (info) {
        case IIO_CHAN_INFO_RAW:
+               mutex_lock(&st->lock);
                *val = st->dac_cache[chan->channel];
+               mutex_unlock(&st->lock);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
                vref_uv = ad7303_get_vref(st, chan);
@@ -144,11 +147,11 @@ static int ad7303_write_raw(struct iio_dev *indio_dev,
                if (val >= (1 << chan->scan_type.realbits) || val < 0)
                        return -EINVAL;
 
-               mutex_lock(&indio_dev->mlock);
+               mutex_lock(&st->lock);
                ret = ad7303_write(st, chan->address, val);
                if (ret == 0)
                        st->dac_cache[chan->channel] = val;
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(&st->lock);
                break;
        default:
                ret = -EINVAL;
@@ -211,6 +214,8 @@ static int ad7303_probe(struct spi_device *spi)
 
        st->spi = spi;
 
+       mutex_init(&st->lock);
+
        st->vdd_reg = devm_regulator_get(&spi->dev, "Vdd");
        if (IS_ERR(st->vdd_reg))
                return PTR_ERR(st->vdd_reg);