diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c index 95aeb65f244b..2a809a70803b 100644 --- a/drivers/iio/adc/qcom-spmi-adc5.c +++ b/drivers/iio/adc/qcom-spmi-adc5.c @@ -87,7 +87,7 @@ /* For PMIC7 */ #define ADC_APP_SID 0x40 #define ADC_APP_SID_MASK 0xf -#define ADC7_CONV_TIMEOUT msecs_to_jiffies(10) +#define ADC7_CONV_TIMEOUT_MS 501 enum adc5_cal_method { ADC5_NO_CAL = 0, @@ -433,6 +433,8 @@ static int adc7_do_conversion(struct adc5_chip *adc, u16 *data_volt, u16 *data_cur) { int ret; + unsigned long rc; + unsigned int time_pending_ms; u8 status = 0; mutex_lock(&adc->lock); @@ -444,15 +446,43 @@ 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) { + pr_err("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) + pr_warn("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 < 0) goto unlock; if (status & ADC5_USR_STATUS1_CONV_FAULT) { - pr_err("Unexpected conversion fault\n"); + pr_err("ADC channel %s unexpected conversion fault\n", + prop->datasheet_name); + ret = -EIO; + goto unlock; + } + + if (!(status & ADC5_USR_STATUS1_EOC)) { + pr_err("ADC channel %s EOC bit not set, status=%#x\n", + prop->datasheet_name, status); ret = -EIO; goto unlock; }