summaryrefslogtreecommitdiffstats
path: root/drivers/iio/adc
diff options
context:
space:
mode:
authorAngelo Compagnucci <angelo.compagnucci@gmail.com>2020-08-19 09:55:25 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-09-17 13:47:42 +0200
commit5571056a58051d85f22265e6ac62da8e7ac727a7 (patch)
tree018c2ba39a6c7c1b0681bc5fdd9ec5f9ae483af7 /drivers/iio/adc
parentf7db02316a003c67ecf8c02037d21c765b992647 (diff)
downloadlinux-stable-5571056a58051d85f22265e6ac62da8e7ac727a7.tar.gz
linux-stable-5571056a58051d85f22265e6ac62da8e7ac727a7.tar.bz2
linux-stable-5571056a58051d85f22265e6ac62da8e7ac727a7.zip
iio: adc: mcp3422: fix locking scope
commit 3f1093d83d7164e4705e4232ccf76da54adfda85 upstream. Locking should be held for the entire reading sequence involving setting the channel, waiting for the channel switch and reading from the channel. If not, reading from a channel can result mixing with the reading from another channel. Fixes: 07914c84ba30 ("iio: adc: Add driver for Microchip MCP3422/3/4 high resolution ADC") Signed-off-by: Angelo Compagnucci <angelo.compagnucci@gmail.com> Link: https://lore.kernel.org/r/20200819075525.1395248-1-angelo.compagnucci@gmail.com Cc: <Stable@vger.kernel.org> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r--drivers/iio/adc/mcp3422.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c
index 4d03b1f265d9..8ae4cf135157 100644
--- a/drivers/iio/adc/mcp3422.c
+++ b/drivers/iio/adc/mcp3422.c
@@ -95,16 +95,12 @@ static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
{
int ret;
- mutex_lock(&adc->lock);
-
ret = i2c_master_send(adc->i2c, &newconfig, 1);
if (ret > 0) {
adc->config = newconfig;
ret = 0;
}
- mutex_unlock(&adc->lock);
-
return ret;
}
@@ -137,6 +133,8 @@ static int mcp3422_read_channel(struct mcp3422 *adc,
u8 config;
u8 req_channel = channel->channel;
+ mutex_lock(&adc->lock);
+
if (req_channel != MCP3422_CHANNEL(adc->config)) {
config = adc->config;
config &= ~MCP3422_CHANNEL_MASK;
@@ -151,7 +149,11 @@ static int mcp3422_read_channel(struct mcp3422 *adc,
msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
}
- return mcp3422_read(adc, value, &config);
+ ret = mcp3422_read(adc, value, &config);
+
+ mutex_unlock(&adc->lock);
+
+ return ret;
}
static int mcp3422_read_raw(struct iio_dev *iio,