]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.9.49/iio-adc-ti-ads1015-avoid-getting-stale-result-after-runtime-resume.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.9.49 / iio-adc-ti-ads1015-avoid-getting-stale-result-after-runtime-resume.patch
CommitLineData
a1e97e95
GKH
1From 73e3e3fc50de50cfd68e945d85679c983ed31bd9 Mon Sep 17 00:00:00 2001
2From: Akinobu Mita <akinobu.mita@gmail.com>
3Date: Fri, 21 Jul 2017 00:24:20 +0900
4Subject: iio: adc: ti-ads1015: avoid getting stale result after runtime resume
5
6From: Akinobu Mita <akinobu.mita@gmail.com>
7
8commit 73e3e3fc50de50cfd68e945d85679c983ed31bd9 upstream.
9
10This driver assumes that the device is operating in the continuous
11conversion mode which performs the conversion continuously. So this driver
12doesn't insert a wait time before reading the conversion register if the
13configuration is not changed from a previous request.
14
15This assumption is broken if the device is runtime suspended and entered
16a power-down state. The forthcoming request causes reading a stale result
17from the conversion register as the device is runtime resumed just before.
18
19Fix it by adding a flag to detect that condition and insert a necessary
20wait time.
21
22Cc: Daniel Baluta <daniel.baluta@gmail.com>
23Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
24Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
25Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26
27---
28 drivers/iio/adc/ti-ads1015.c | 18 ++++++++++++++++--
29 1 file changed, 16 insertions(+), 2 deletions(-)
30
31--- a/drivers/iio/adc/ti-ads1015.c
32+++ b/drivers/iio/adc/ti-ads1015.c
33@@ -176,6 +176,12 @@ struct ads1015_data {
34 struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
35
36 unsigned int *data_rate;
37+ /*
38+ * Set to true when the ADC is switched to the continuous-conversion
39+ * mode and exits from a power-down state. This flag is used to avoid
40+ * getting the stale result from the conversion register.
41+ */
42+ bool conv_invalid;
43 };
44
45 static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg)
46@@ -254,9 +260,10 @@ int ads1015_get_adc_result(struct ads101
47 if (ret < 0)
48 return ret;
49
50- if (change) {
51+ if (change || data->conv_invalid) {
52 conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
53 usleep_range(conv_time, conv_time + 1);
54+ data->conv_invalid = false;
55 }
56
57 return regmap_read(data->regmap, ADS1015_CONV_REG, val);
58@@ -624,6 +631,8 @@ static int ads1015_probe(struct i2c_clie
59 if (ret)
60 return ret;
61
62+ data->conv_invalid = true;
63+
64 ret = pm_runtime_set_active(&client->dev);
65 if (ret)
66 goto err_buffer_cleanup;
67@@ -679,10 +688,15 @@ static int ads1015_runtime_resume(struct
68 {
69 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
70 struct ads1015_data *data = iio_priv(indio_dev);
71+ int ret;
72
73- return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
74+ ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
75 ADS1015_CFG_MOD_MASK,
76 ADS1015_CONTINUOUS << ADS1015_CFG_MOD_SHIFT);
77+ if (!ret)
78+ data->conv_invalid = true;
79+
80+ return ret;
81 }
82 #endif
83