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);