staging:iio:adc:ad7152: Add proper locking
authorMichael Hennerich <michael.hennerich@analog.com>
Fri, 2 Sep 2011 16:25:29 +0000 (17:25 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 6 Sep 2011 23:03:30 +0000 (16:03 -0700)
Add proper locking.
Consistently use indio_dev.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/iio/adc/ad7152.c

index 92a9c90b4816ee4f565da4943f35ebb0691f3e8d..f2e1df1b05c4b9318d2c7f4663f0f8af230da1af 100644 (file)
@@ -19,7 +19,7 @@
 #include "../sysfs.h"
 
 /*
- * TODO: Check compliance of calibscale and calibbias with abi (units)
+ * TODO: Check compliance of calibbias with abi (units)
  */
 /*
  * AD7152 registers definition
@@ -94,8 +94,8 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
                                         size_t len,
                                         u8 regval)
 {
-       struct iio_dev *dev_info = dev_get_drvdata(dev);
-       struct ad7152_chip_info *chip = iio_priv(dev_info);
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct ad7152_chip_info *chip = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        bool doit;
        int ret, timeout = 10;
@@ -112,17 +112,23 @@ static inline ssize_t ad7152_start_calib(struct device *dev,
        else
                regval |= AD7152_CONF_CH2EN;
 
+       mutex_lock(&indio_dev->mlock);
        ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval);
-       if (ret < 0)
+       if (ret < 0) {
+               mutex_unlock(&indio_dev->mlock);
                return ret;
+       }
 
        do {
                mdelay(20);
                ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG);
-               if (ret < 0)
+               if (ret < 0) {
+                       mutex_unlock(&indio_dev->mlock);
                        return ret;
+               }
        } while ((ret == regval) && timeout--);
 
+       mutex_unlock(&indio_dev->mlock);
        return len;
 }
 static ssize_t ad7152_start_offset_calib(struct device *dev,
@@ -158,8 +164,8 @@ static ssize_t ad7152_show_filter_rate_setup(struct device *dev,
                struct device_attribute *attr,
                char *buf)
 {
-       struct iio_dev *dev_info = dev_get_drvdata(dev);
-       struct ad7152_chip_info *chip = iio_priv(dev_info);
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct ad7152_chip_info *chip = iio_priv(indio_dev);
 
        return sprintf(buf, "0x%02x\n", chip->filter_rate_setup);
 }
@@ -169,8 +175,8 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
                const char *buf,
                size_t len)
 {
-       struct iio_dev *dev_info = dev_get_drvdata(dev);
-       struct ad7152_chip_info *chip = iio_priv(dev_info);
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct ad7152_chip_info *chip = iio_priv(indio_dev);
        u8 data;
        int ret;
 
@@ -178,11 +184,13 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev,
        if (ret < 0)
                return ret;
 
+       mutex_lock(&indio_dev->mlock);
        ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG2, data);
        if (ret < 0)
                return ret;
 
        chip->filter_rate_setup = data;
+       mutex_unlock(&indio_dev->mlock);
 
        return len;
 }
@@ -220,19 +228,23 @@ static const int ad7152_scale_table[] = {
        30525, 7631, 15263, 61050
 };
 
-static int ad7152_write_raw(struct iio_dev *dev_info,
+static int ad7152_write_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *chan,
                            int val,
                            int val2,
                            long mask)
 {
-       struct ad7152_chip_info *chip = iio_priv(dev_info);
+       struct ad7152_chip_info *chip = iio_priv(indio_dev);
        int ret, i;
 
+       mutex_lock(&indio_dev->mlock);
+
        switch (mask) {
        case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
-               if (val != 1)
-                       return -EINVAL;
+               if (val != 1) {
+                       ret = -EINVAL;
+                       goto out;
+               }
 
                val = (val2 * 1024) / 15625;
 
@@ -240,23 +252,29 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
                                ad7152_addresses[chan->channel][AD7152_GAIN],
                                swab16(val));
                if (ret < 0)
-                       return ret;
+                       goto out;
 
-               return 0;
+               ret = 0;
+               break;
 
        case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
-               if ((val < 0) | (val > 0xFFFF))
-                       return -EINVAL;
+               if ((val < 0) | (val > 0xFFFF)) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = i2c_smbus_write_word_data(chip->client,
                                ad7152_addresses[chan->channel][AD7152_OFFS],
                                swab16(val));
                if (ret < 0)
-                       return ret;
+                       goto out;
 
-               return 0;
+               ret = 0;
+               break;
        case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
-               if (val != 0)
-                       return -EINVAL;
+               if (val != 0) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                for (i = 0; i < ARRAY_SIZE(ad7152_scale_table); i++)
                        if (val2 == ad7152_scale_table[i])
                                break;
@@ -268,21 +286,29 @@ static int ad7152_write_raw(struct iio_dev *dev_info,
                                ad7152_addresses[chan->channel][AD7152_SETUP],
                                chip->setup[chan->channel]);
                if (ret < 0)
-                       return ret;
-               else
-                       return 0;
+                       goto out;
+
+               ret = 0;
+               break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
+
+out:
+       mutex_unlock(&indio_dev->mlock);
+       return ret;
 }
-static int ad7152_read_raw(struct iio_dev *dev_info,
+static int ad7152_read_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan,
                           int *val, int *val2,
                           long mask)
 {
-       struct ad7152_chip_info *chip = iio_priv(dev_info);
+       struct ad7152_chip_info *chip = iio_priv(indio_dev);
        int ret;
        u8 regval = 0;
+
+       mutex_lock(&indio_dev->mlock);
+
        switch (mask) {
        case 0:
                /* First set whether in differential mode */
@@ -299,7 +325,7 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
                                ad7152_addresses[chan->channel][AD7152_SETUP],
                                chip->setup[chan->channel]);
                        if (ret < 0)
-                               return ret;
+                               goto out;
                }
                /* Make sure the channel is enabled */
                if (chan->channel == 0)
@@ -312,48 +338,55 @@ static int ad7152_read_raw(struct iio_dev *dev_info,
                ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG,
                                regval);
                if (ret < 0)
-                       return ret;
+                       goto out;
 
                msleep(60); /* Slowest conversion time */
                /* Now read the actual register */
                ret = i2c_smbus_read_word_data(chip->client,
                                ad7152_addresses[chan->channel][AD7152_DATA]);
                if (ret < 0)
-                       return ret;
+                       goto out;
                *val = swab16(ret);
 
-               return IIO_VAL_INT;
+               ret = IIO_VAL_INT;
+               break;
        case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
 
                ret = i2c_smbus_read_word_data(chip->client,
                                ad7152_addresses[chan->channel][AD7152_GAIN]);
                if (ret < 0)
-                       return ret;
+                       goto out;
                /* 1 + gain_val / 2^16 */
                *val = 1;
                *val2 = (15625 * swab16(ret)) / 1024;
 
-               return IIO_VAL_INT_PLUS_MICRO;
+               ret = IIO_VAL_INT_PLUS_MICRO;
+               break;
        case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
                ret = i2c_smbus_read_word_data(chip->client,
                                ad7152_addresses[chan->channel][AD7152_OFFS]);
                if (ret < 0)
-                       return ret;
+                       goto out;
                *val = swab16(ret);
 
-               return IIO_VAL_INT;
+               ret = IIO_VAL_INT;
+               break;
        case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
                ret = i2c_smbus_read_byte_data(chip->client,
                                ad7152_addresses[chan->channel][AD7152_SETUP]);
                if (ret < 0)
-                       return ret;
+                       goto out;
                *val = 0;
                *val2 = ad7152_scale_table[ret >> 6];
 
-               return IIO_VAL_INT_PLUS_NANO;
+               ret = IIO_VAL_INT_PLUS_NANO;
+               break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        };
+out:
+       mutex_unlock(&indio_dev->mlock);
+       return ret;
 }
 
 static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,