summaryrefslogtreecommitdiff
path: root/drivers/iio/adc
diff options
context:
space:
mode:
authorNicholas Troast <ntroast@codeaurora.org>2017-03-08 15:38:51 -0800
committerAbhijeet Dharmapurikar <adharmap@codeaurora.org>2017-03-20 11:56:08 -0700
commite414b3629184b01c72fbfb72a5efbc343a1372ab (patch)
tree13559fd5de765e53a4e8d1cb19016a601d69f213 /drivers/iio/adc
parent687a4eb82be5905f5400678dcaff4e98dad72e3c (diff)
iio: qcom-tadc: serialize conversion requests
Two or more conversion requests could be scheduled at the same time which causes timeout errors. Fix this by serializing the software conversion requests. Change-Id: Ie5de4923cfb67f8e75248ebe1a6d577dab1686a4 Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r--drivers/iio/adc/qcom-tadc.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/iio/adc/qcom-tadc.c b/drivers/iio/adc/qcom-tadc.c
index 9241288c1d43..82d2e762ef36 100644
--- a/drivers/iio/adc/qcom-tadc.c
+++ b/drivers/iio/adc/qcom-tadc.c
@@ -217,6 +217,7 @@ struct tadc_chip {
struct tadc_chan_data chans[TADC_NUM_CH];
struct completion eoc_complete;
struct mutex write_lock;
+ struct mutex conv_lock;
};
struct tadc_pt {
@@ -482,10 +483,11 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
u8 val[TADC_NUM_CH * 2];
int rc, i;
+ mutex_lock(&chip->conv_lock);
rc = tadc_read(chip, TADC_MBG_ERR_REG(chip), val, 1);
if (rc < 0) {
pr_err("Couldn't read mbg error status rc=%d\n", rc);
- return rc;
+ goto unlock;
}
if (val[0] != 0) {
@@ -496,7 +498,7 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
rc = tadc_write(chip, TADC_CONV_REQ_REG(chip), channels);
if (rc < 0) {
pr_err("Couldn't write conversion request rc=%d\n", rc);
- return rc;
+ goto unlock;
}
timeout = msecs_to_jiffies(CONVERSION_TIMEOUT_MS);
@@ -506,25 +508,29 @@ static int tadc_do_conversion(struct tadc_chip *chip, u8 channels, s16 *adc)
rc = tadc_read(chip, TADC_SW_CH_CONV_REG(chip), val, 1);
if (rc < 0) {
pr_err("Couldn't read conversion status rc=%d\n", rc);
- return rc;
+ goto unlock;
}
if (val[0] != channels) {
- pr_err("Conversion timed out\n");
- return -ETIMEDOUT;
+ rc = -ETIMEDOUT;
+ goto unlock;
}
}
rc = tadc_read(chip, TADC_CH1_ADC_LO_REG(chip), val, ARRAY_SIZE(val));
if (rc < 0) {
pr_err("Couldn't read adc channels rc=%d\n", rc);
- return rc;
+ goto unlock;
}
for (i = 0; i < TADC_NUM_CH; i++)
adc[i] = (s16)(val[i * 2] | (u16)val[i * 2 + 1] << 8);
- return jiffies_to_msecs(timeout - timeleft);
+ rc = jiffies_to_msecs(timeout - timeleft);
+
+unlock:
+ mutex_unlock(&chip->conv_lock);
+ return rc;
}
static int tadc_read_raw(struct iio_dev *indio_dev,
@@ -1017,6 +1023,7 @@ static int tadc_probe(struct platform_device *pdev)
chip->tadc_cmp_base = chip->tadc_base + 0x100;
mutex_init(&chip->write_lock);
+ mutex_init(&chip->conv_lock);
chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
if (!chip->regmap) {
pr_err("Couldn't get regmap\n");