[media] media: rc: nuvoton-cir: fix interrupt handling

Only handle an interrupt if at least one combination of event bit
and related interrupt bit is set.
Previously it was just checked that at least one event bit and
at least one interrupt bit are set.

This fixes issues like the following which was caused by
interrupt sharing:
An interrupt intended for nvt_cir_isr was handled by nvt_cir_wake_isr
first and because status bit CIR_WAKE_IRSTS_IR_PENDING was set
the wake fifo was accidently cleared.

This patch also fixes the bug that nvt_cir_wake_isr returned IRQ_HANDLED
even if it detected that the (shared) interrupt was meant for another
handler.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
Heiner Kallweit 2015-12-30 14:45:51 -02:00 committed by Mauro Carvalho Chehab
parent 88205f01fe
commit d42fd29769
1 changed files with 12 additions and 17 deletions

View File

@ -825,9 +825,13 @@ static irqreturn_t nvt_cir_isr(int irq, void *data)
* 0: CIR_IRSTS_GH - Min Length Detected
*/
status = nvt_cir_reg_read(nvt, CIR_IRSTS);
if (!status) {
iren = nvt_cir_reg_read(nvt, CIR_IREN);
/* IRQ may be shared with CIR WAKE, therefore check for each
* status bit whether the related interrupt source is enabled
*/
if (!(status & iren)) {
nvt_dbg_verbose("%s exiting, IRSTS 0x0", __func__);
nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
return IRQ_NONE;
}
@ -835,13 +839,6 @@ static irqreturn_t nvt_cir_isr(int irq, void *data)
nvt_cir_reg_write(nvt, status, CIR_IRSTS);
nvt_cir_reg_write(nvt, 0, CIR_IRSTS);
/* Interrupt may be shared with CIR Wake, bail if CIR not enabled */
iren = nvt_cir_reg_read(nvt, CIR_IREN);
if (!iren) {
nvt_dbg_verbose("%s exiting, CIR not enabled", __func__);
return IRQ_NONE;
}
nvt_cir_log_irqs(status, iren);
if (status & CIR_IRSTS_RTR) {
@ -914,7 +911,12 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data)
nvt_dbg_wake("%s firing", __func__);
status = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS);
if (!status)
iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN);
/* IRQ may be shared with CIR, therefore check for each
* status bit whether the related interrupt source is enabled
*/
if (!(status & iren))
return IRQ_NONE;
if (status & CIR_WAKE_IRSTS_IR_PENDING)
@ -923,13 +925,6 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data)
nvt_cir_wake_reg_write(nvt, status, CIR_WAKE_IRSTS);
nvt_cir_wake_reg_write(nvt, 0, CIR_WAKE_IRSTS);
/* Interrupt may be shared with CIR, bail if Wake not enabled */
iren = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN);
if (!iren) {
nvt_dbg_wake("%s exiting, wake not enabled", __func__);
return IRQ_HANDLED;
}
if ((status & CIR_WAKE_IRSTS_PE) &&
(nvt->wake_state == ST_WAKE_START)) {
while (nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX)) {