From 3a2a5ea5ee5cb3e8c2766adbd59ee0660a57303c Mon Sep 17 00:00:00 2001 From: Jishnu Prakash Date: Mon, 23 Aug 2021 22:50:02 +0530 Subject: [PATCH] iio: qcom-spmi-adc5-gen3 : add support to clear conversion fault When an ADC conversion results in a conversion fault, the conversion fault bit in the status register is set, but never cleared, by PBS, causing an error print for conversion fault to appear for all future conversions. Update interrupt handler to clear conversion fault bit if it is found set. Change-Id: I83b36ce585ab5d20639dbf5050f91e8850cc2b75 Signed-off-by: Jishnu Prakash --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index 1833f2630e8d..6a3ca36eec0b 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -50,6 +50,9 @@ static LIST_HEAD(adc_tm_device_list); #define ADC5_GEN3_TM_LOW_STS_CLR 0x4d +#define ADC5_GEN3_CONV_ERR_CLR 0x4e +#define ADC5_GEN3_CONV_ERR_CLR_REQ BIT(0) + #define ADC5_GEN3_SID 0x4f #define ADC5_GEN3_SID_MASK 0xf @@ -532,7 +535,7 @@ static void adc5_gen3_dump_regs_debug(struct adc5_chip *adc) static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) { struct adc5_chip *adc = dev_id; - u8 status, tm_status[2], eoc_status; + u8 status, tm_status[2], eoc_status, val; int ret; ret = adc5_read(adc, ADC5_GEN3_EOC_STS, &eoc_status, 1); @@ -566,6 +569,22 @@ static irqreturn_t adc5_gen3_isr(int irq, void *dev_id) if (status & ADC5_GEN3_STATUS1_CONV_FAULT) { pr_err("Unexpected conversion fault\n"); adc5_gen3_dump_regs_debug(adc); + + val = ADC5_GEN3_CONV_ERR_CLR_REQ; + ret = adc5_write(adc, ADC5_GEN3_CONV_ERR_CLR, &val, 1); + if (ret < 0) + goto handler_end; + + /* To indicate conversion request is only to clear a status */ + val = 0; + ret = adc5_write(adc, ADC5_GEN3_PERPH_CH, &val, 1); + if (ret < 0) + goto handler_end; + + val = ADC5_GEN3_CONV_REQ_REQ; + ret = adc5_write(adc, ADC5_GEN3_CONV_REQ, &val, 1); + if (ret < 0) + goto handler_end; } handler_end: @@ -597,6 +616,10 @@ static void tm_handler_work(struct work_struct *work) /* To indicate conversion request is only to clear a status */ val = 0; ret = adc5_write(adc, ADC5_GEN3_PERPH_CH, &val, 1); + if (ret < 0) { + pr_err("adc write status clear conv_req failed with %d\n", ret); + goto work_unlock; + } val = ADC5_GEN3_CONV_REQ_REQ; ret = adc5_write(adc, ADC5_GEN3_CONV_REQ, &val, 1);