iio: adc: ti-ads1015: use iio_device_claim_direct_mode()
authorAkinobu Mita <akinobu.mita@gmail.com>
Thu, 20 Jul 2017 15:24:26 +0000 (00:24 +0900)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sun, 20 Aug 2017 14:41:17 +0000 (15:41 +0100)
While the iio buffer for the ti-ads1015 driver is enabled, reading the
raw ADC channel data is restricted.  We usually use the
iio_device_claim_direct_mode()/iio_device_release_direct_mode() pair for
that.

This change consequently reverses the locking order for the driver's
private lock and indio_dev->mlock which acquired by
iio_device_claim_direct_mode() internally. But it's safe because there is
no other dependency between these locks.

Cc: Daniel Baluta <daniel.baluta@gmail.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ti-ads1015.c

index 8602b642a42fc1269eb13b3a2a198d94d7ea7c67..14c573175f8e62891c49415d705d337396f25081 100644 (file)
@@ -347,34 +347,34 @@ static int ads1015_read_raw(struct iio_dev *indio_dev,
        int ret, idx;
        struct ads1015_data *data = iio_priv(indio_dev);
 
-       mutex_lock(&indio_dev->mlock);
        mutex_lock(&data->lock);
        switch (mask) {
        case IIO_CHAN_INFO_RAW: {
                int shift = chan->scan_type.shift;
 
-               if (iio_buffer_enabled(indio_dev)) {
-                       ret = -EBUSY;
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
                        break;
-               }
 
                ret = ads1015_set_power_state(data, true);
                if (ret < 0)
-                       break;
+                       goto release_direct;
 
                ret = ads1015_get_adc_result(data, chan->address, val);
                if (ret < 0) {
                        ads1015_set_power_state(data, false);
-                       break;
+                       goto release_direct;
                }
 
                *val = sign_extend32(*val >> shift, 15 - shift);
 
                ret = ads1015_set_power_state(data, false);
                if (ret < 0)
-                       break;
+                       goto release_direct;
 
                ret = IIO_VAL_INT;
+release_direct:
+               iio_device_release_direct_mode(indio_dev);
                break;
        }
        case IIO_CHAN_INFO_SCALE:
@@ -393,7 +393,6 @@ static int ads1015_read_raw(struct iio_dev *indio_dev,
                break;
        }
        mutex_unlock(&data->lock);
-       mutex_unlock(&indio_dev->mlock);
 
        return ret;
 }