spmi: qpnp-int: use edge flow handler for edge interrupts

The driver uses level flow handler for both edge and level trigger types.
This creates a window where an edge triggered interrupt can be missed.

The following explanation applies for kernel prior to commit
d4dc0f90d2 ("genirq: Allow
check_wakeup_irqs to notice level-triggered interrupts").

The edge flow handler sets the IRQS_PENDING flag if that interrupt was
disabled (IRQD_DISABLED flag set) and the genirq framework uses this
flag to:
1. Resend edge triggered interrupts
2. Abort suspend if it were a wakeup interrupt

The level flow handler does not set this flag as it is expected that a
level triggered interrupt will be active unless handled.

If the level flow handler is used for edge triggered interrupts, then we
miss the opportunity to set IRQS_PENDING flag and so we could miss
resending the interrupt or aborting suspend if the edge triggered
interrupt fires while it is disabled.

Change in commit d4dc0f90d2 ("genirq:
Allow check_wakeup_irqs to notice level-triggered interrupts")
makes level flow handler set the IRQS_PENDING flag and solves this issue.
However, the qpnp-int driver is intended to be run on kernels without this
change.

Hence update the code to use edge flow handler for edge triggered
interrupts.

Change-Id: I9a99ecd1366a614fc372743f150e5a6d508db786
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2013-11-25 11:34:10 -08:00 committed by David Collins
parent 519ced757b
commit d079346dec

View File

@ -318,6 +318,11 @@ static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
return rc;
}
if (flow_type & IRQ_TYPE_EDGE_BOTH)
__irq_set_handler_locked(d->irq, handle_edge_irq);
else
__irq_set_handler_locked(d->irq, handle_level_irq);
return 0;
}