mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 19:47:08 +02:00
iio: qcom-spmi-adc5: Handle EOC properly
Currently, when an ADC7 channel is read, there is a wait time of 10 ms where an EOC (end of conversion) interrupt should happen thereby completing the wait for ADC conversion. However, if this wait times out, it is not handled and stale data can be read. Add error logs to print when this wait times out as well as if EOC bit is not set and return an error. Also, this 10 ms wait time for EOC after requesting for a channel conversion is not sufficient. As per the hardware recommendation when multiple subsystems requests PMIC HW arbiter to read same or different channels on different PMICs simultaneously, it could take 15 ms for a good case i.e. where all the conversion requests went through successfully. However, for a worst case where this conversion request times out, it could take up to 500 ms before an EOC interrupt is sent by PBS to SW. Hence, increase conversion wait time to 501 ms so that no other channel reads can be made in the worst case. Also print a warning when the wait time for EOC is more than 15 ms. Change-Id: I69eeade3e85f740af10cd7a3d668e67f67f6617d Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
parent
81fe95c85f
commit
5104aa0d97
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
/* For PMIC7 */
|
||||
#define ADC_APP_SID 0x40
|
||||
#define ADC_APP_SID_MASK GENMASK(3, 0)
|
||||
#define ADC7_CONV_TIMEOUT msecs_to_jiffies(10)
|
||||
#define ADC7_CONV_TIMEOUT_MS 501
|
||||
|
||||
enum adc5_cal_method {
|
||||
ADC5_NO_CAL = 0,
|
||||
|
|
@ -365,6 +365,8 @@ static int adc7_do_conversion(struct adc5_chip *adc,
|
|||
{
|
||||
int ret;
|
||||
u8 status;
|
||||
unsigned long rc;
|
||||
unsigned int time_pending_ms;
|
||||
|
||||
mutex_lock(&adc->lock);
|
||||
|
||||
|
|
@ -375,14 +377,44 @@ static int adc7_do_conversion(struct adc5_chip *adc,
|
|||
}
|
||||
|
||||
/* No support for polling mode at present */
|
||||
wait_for_completion_timeout(&adc->complete, ADC7_CONV_TIMEOUT);
|
||||
rc = wait_for_completion_timeout(&adc->complete,
|
||||
msecs_to_jiffies(ADC7_CONV_TIMEOUT_MS));
|
||||
if (!rc) {
|
||||
dev_err(adc->dev, "Reading ADC channel %s timed out\n",
|
||||
prop->datasheet_name);
|
||||
ret = -ETIMEDOUT;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* As per the hardware documentation, EOC should happen within 15 ms
|
||||
* in a good case where there could be multiple conversion requests
|
||||
* going through PMIC HW arbiter for reading ADC channels. However, if
|
||||
* for some reason, one of the conversion request fails and times out,
|
||||
* worst possible delay can be 500 ms. Hence print a warning when we
|
||||
* see EOC completion happened more than 15 ms.
|
||||
*/
|
||||
time_pending_ms = jiffies_to_msecs(rc);
|
||||
if (time_pending_ms < ADC7_CONV_TIMEOUT_MS &&
|
||||
(ADC7_CONV_TIMEOUT_MS - time_pending_ms) > 15)
|
||||
dev_warn(adc->dev, "ADC channel %s EOC took %u ms\n",
|
||||
prop->datasheet_name,
|
||||
ADC7_CONV_TIMEOUT_MS - time_pending_ms);
|
||||
|
||||
ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
if (status & ADC5_USR_STATUS1_CONV_FAULT) {
|
||||
dev_err(adc->dev, "Unexpected conversion fault\n");
|
||||
dev_err(adc->dev, "ADC channel %s unexpected conversion fault\n",
|
||||
prop->datasheet_name);
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (!(status & ADC5_USR_STATUS1_EOC)) {
|
||||
dev_err(adc->dev, "ADC channel %s EOC bit not set, status=%#x\n",
|
||||
prop->datasheet_name, status);
|
||||
ret = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user