diff options
Diffstat (limited to 'nuttx/arch/arm/src/imx/imx_decodeirq.c')
-rw-r--r-- | nuttx/arch/arm/src/imx/imx_decodeirq.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/nuttx/arch/arm/src/imx/imx_decodeirq.c b/nuttx/arch/arm/src/imx/imx_decodeirq.c index f6a38b934..7d2ba81dd 100644 --- a/nuttx/arch/arm/src/imx/imx_decodeirq.c +++ b/nuttx/arch/arm/src/imx/imx_decodeirq.c @@ -79,45 +79,51 @@ void up_decodeirq(uint32* regs) uint32 regval; int irq; - /* Decode the interrupt. First, fetch the NIVECSR register. */ - - regval = getreg32(IMX_AITC_NIVECSR); - - /* The MS 16 bits of the NIVECSR register contains vector index for the - * highest pending normal interrupt. + /* Current regs non-zero indicates that we are processing an interrupt; + * current_regs is also used to manage interrupt level context switches. */ - irq = regval >> AITC_NIVECSR_NIVECTOR_SHIFT; + current_regs = regs; - /* If irq < 64, then this is the IRQ. If there is no pending interrupt, - * then irq will be >= 64 (it will be 0xffff for illegal source). - */ + /* Loop while there are pending interrupts to be processed */ - if (irq < NR_IRQS) + do { - /* Mask and acknowledge the interrupt */ + /* Decode the interrupt. First, fetch the NIVECSR register. */ - up_maskack_irq(irq); + regval = getreg32(IMX_AITC_NIVECSR); - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. + /* The MS 16 bits of the NIVECSR register contains vector index for the + * highest pending normal interrupt. */ - current_regs = regs; + irq = regval >> AITC_NIVECSR_NIVECTOR_SHIFT; - /* Deliver the IRQ */ + /* If irq < 64, then this is the IRQ. If there is no pending interrupt, + * then irq will be >= 64 (it will be 0xffff for illegal source). + */ - irq_dispatch(irq, regs); + if (irq < NR_IRQS) + { + /* Mask and acknowledge the interrupt */ - /* Indicate that we are no long in an interrupt handler */ + up_maskack_irq(irq); - current_regs = NULL; + /* Deliver the IRQ */ - /* Unmask the last interrupt (global interrupts are still - * disabled. - */ + irq_dispatch(irq, regs); + + /* Unmask the last interrupt (global interrupts are still + * disabled). + */ - up_enable_irq(irq); + up_enable_irq(irq); + } } + while (irq < NR_IRQS); + + /* Indicate that we are no longer in an interrupt handler */ + + current_regs = NULL; #endif } |