summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelo Compagnucci <angelo.compagnucci@gmail.com>2020-08-19 10:55:25 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-09-23 09:46:10 +0300
commit91e8f0d6b347efe495aa9a0bdcb7b0cee1fb567e (patch)
treef7c54fb8ccf1ac3b03bcba0e6c844161f4010646
parent250f4087fc60a64c0f7954020da35cafa0a5af24 (diff)
downloadlinux-91e8f0d6b347efe495aa9a0bdcb7b0cee1fb567e.tar.xz
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>
-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 254135e07792..39c3a7e972c1 100644
--- a/drivers/iio/adc/mcp3422.c
+++ b/drivers/iio/adc/mcp3422.c
@@ -99,16 +99,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;
}
@@ -141,6 +137,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;
@@ -153,7 +151,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,