| From 3f1093d83d7164e4705e4232ccf76da54adfda85 Mon Sep 17 00:00:00 2001 |
| From: Angelo Compagnucci <angelo.compagnucci@gmail.com> |
| Date: Wed, 19 Aug 2020 09:55:25 +0200 |
| Subject: iio: adc: mcp3422: fix locking scope |
| |
| From: Angelo Compagnucci <angelo.compagnucci@gmail.com> |
| |
| 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> |
| |
| --- |
| drivers/iio/adc/mcp3422.c | 12 +++++++----- |
| 1 file changed, 7 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/iio/adc/mcp3422.c |
| +++ b/drivers/iio/adc/mcp3422.c |
| @@ -95,16 +95,12 @@ static int mcp3422_update_config(struct |
| { |
| 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 m |
| 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 m |
| 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, |