]> git.karo-electronics.de Git - linux-beck.git/commitdiff
iio: light: vcnl4000: Add missing locking
authorPeter Meerwald-Stadler <pmeerw@pmeerw.net>
Tue, 5 Jul 2016 10:23:21 +0000 (12:23 +0200)
committerJonathan Cameron <jic23@kernel.org>
Sun, 10 Jul 2016 13:44:06 +0000 (14:44 +0100)
Signed-off-by: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/light/vcnl4000.c

index 9f94b6ba39841dc8036adc6cf822622e0f882891..360b6e98137acbfbd604e6492687f0b34f424de5 100644 (file)
@@ -48,6 +48,7 @@
 
 struct vcnl4000_data {
        struct i2c_client *client;
+       struct mutex lock;
 };
 
 static const struct i2c_device_id vcnl4000_id[] = {
@@ -63,16 +64,18 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
        __be16 buf;
        int ret;
 
+       mutex_lock(&data->lock);
+
        ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND,
                                        req_mask);
        if (ret < 0)
-               return ret;
+               goto fail;
 
        /* wait for data to become ready */
        while (tries--) {
                ret = i2c_smbus_read_byte_data(data->client, VCNL4000_COMMAND);
                if (ret < 0)
-                       return ret;
+                       goto fail;
                if (ret & rdy_mask)
                        break;
                msleep(20); /* measurement takes up to 100 ms */
@@ -81,17 +84,23 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask,
        if (tries < 0) {
                dev_err(&data->client->dev,
                        "vcnl4000_measure() failed, data not ready\n");
-               return -EIO;
+               ret = -EIO;
+               goto fail;
        }
 
        ret = i2c_smbus_read_i2c_block_data(data->client,
                data_reg, sizeof(buf), (u8 *) &buf);
        if (ret < 0)
-               return ret;
+               goto fail;
 
+       mutex_unlock(&data->lock);
        *val = be16_to_cpu(buf);
 
        return 0;
+
+fail:
+       mutex_unlock(&data->lock);
+       return ret;
 }
 
 static const struct iio_chan_spec vcnl4000_channels[] = {
@@ -163,6 +172,7 @@ static int vcnl4000_probe(struct i2c_client *client,
        data = iio_priv(indio_dev);
        i2c_set_clientdata(client, indio_dev);
        data->client = client;
+       mutex_init(&data->lock);
 
        ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
        if (ret < 0)