mfd: pmic8058: Ack interrupts before handling them
There could be a case where
- ADC interrupt is handled and a next request is queued up
- The interrupt thread gets scheduled out just before acking the interrupt
- ADC hardware completes the queued request and raises the next interrupt
- The interrupt thread now gets a chance to run and acks the adc interrupt.
Note this acks the next interrupt.
The above sequence of events leads to lost interrupts. Ack the interrupt
before calling the handle_nested_irq. If next interrupt is raised while the
current one's handler is still running, it will cause another invocation of
the interrupt handler to run.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index dfda920..ff22339 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -1069,12 +1069,16 @@
mutex_unlock(&chip->pm_lock);
for (i = 0; i < handled; i++) {
- handle_nested_irq(irqs_to_handle[i]);
- irqs_to_handle[i] -= chip->pdata.irq_base;
- block = irqs_to_handle[i] / 8 ;
- config = PM8058_IRQF_WRITE | chip->config[irqs_to_handle[i]]
+ int pmic_irq = irqs_to_handle[i] - chip->pdata.irq_base;
+
+ /* ack the interrupt first */
+ block = pmic_irq / 8 ;
+ config = PM8058_IRQF_WRITE | chip->config[pmic_irq]
| PM8058_IRQF_CLR;
pm8058_config_irq(chip, &block, &config);
+
+ /* calle the action handler */
+ handle_nested_irq(irqs_to_handle[i]);
}
if (spurious) {