[U-Boot-Users] Bogus External Interrupt

Hello,
I am trying to write simple program similar to examples/timer.c, which uses interrupts from general purpose timers.
My board is based on mpc8260 and I am using U-boot 1.1.4.
When interrupt is generated from timer, there also appears message: Bogus External Interrupt IRQ 0.
I don't know why bogus interrupt appears and how it is related to my timer interrupt.This is also strange that the number of IRQ is 0. This bogus interrupt appears only when timer is started. When I have registered my timer interrupt handler with irq_install_handler, but not started timer, everything was ok, and I was able to check with irqinfo that my handler is registered.
I would be grateful for some suggestions what can be wrong.
Best regards!

do wrote:
Hello,
I am trying to write simple program similar to examples/timer.c, which uses interrupts from general purpose timers.
My board is based on mpc8260 and I am using U-boot 1.1.4.
When interrupt is generated from timer, there also appears message: Bogus External Interrupt IRQ 0.
I don't know why bogus interrupt appears and how it is related to my timer interrupt.This is also strange that the number of IRQ is 0. This bogus interrupt appears only when timer is started. When I have registered my timer interrupt handler with irq_install_handler, but not started timer, everything was ok, and I was able to check with irqinfo that my handler is registered.
I would be grateful for some suggestions what can be wrong.
Best regards!
Typically "IRQ 0" is an indication that there was no interrupt found when the ISR went to read the interrupt reason. I can think of two reasons for this: 1) (Typical reason): an interrupt happened and was withdrawn (level sensitive interrupt: it went inactive) before the processor got to the ISR.
2) (Likely your problem): The ISR cleared the interrupt improperly so that the processor (re)latched the interrupt that was cleared. When you exit the ISR, the processor has a pending interrupt so it re-enters the ISR, but doesn't find anything to do. Typically this is caused by clearing the processor side of the interrupt and _then_ clearing the source. You should clear the source _first_ and then the processor (or, for a multi-level interrupt, clear from the furthest out inward).
This should be a non-fatal error, but should be understood and fixed.
gvb

Jerry Van Baren napisaĆ(a):
- (Likely your problem): The ISR cleared the interrupt improperly so
that the processor (re)latched the interrupt that was cleared. When you exit the ISR, the processor has a pending interrupt so it re-enters the ISR, but doesn't find anything to do. Typically this is caused by clearing the processor side of the interrupt and _then_ clearing the source. You should clear the source _first_ and then the processor (or, for a multi-level interrupt, clear from the furthest out inward).
This should be a non-fatal error, but should be understood and fixed.
I think that the procesor relatched the interrupt that was cleared by the m8260_mask_and_ack(irq) procedure in external_interrupt servicing function. Thank you for your suggestions. One of the solutions can be splitting this procedure in two, for example: m8260_mask_irq(irq) and m8260_ack_irq(irq). The first can be used for masking interrupt before ISR (mask register usage), and second for ack after ISR (pending interrupt register usage), when the reason of interrupt is cleared. There can be also enabled other interrupts for multi-level.
Best regards!
PS. I hope that the following patch (although not perfect) can be helpful for others:
diff -uNr u-boot-org/cpu/mpc8260/interrupts.c u-boot/cpu/mpc8260/interrupts.c --- u-boot-org/cpu/mpc8260/interrupts.c 2006-01-25 23:13:34.000000000 +0100 +++ u-boot/cpu/mpc8260/interrupts.c 2006-03-06 11:35:53.000000000 +0100 @@ -92,6 +92,20 @@ simr[word] = ppc_cached_irq_mask[word]; }
+static void m8260_ack_irq (unsigned int irq_nr) +{ + volatile immap_t *immr = (immap_t *) CFG_IMMR; + int bit, word; + volatile uint *sipnr; + + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; + + sipnr = &(immr->im_intctl.ic_sipnrh); + sipnr[word] = 1 << (31 - bit); +} + + static void m8260_unmask_irq (unsigned int irq_nr) { volatile immap_t *immr = (immap_t *) CFG_IMMR; @@ -180,10 +194,8 @@
irq = m8260_get_irq (regs);
- m8260_mask_and_ack (irq); - - enable_interrupts (); - + m8260_mask_irq(irq); /* enable_interrupts(); */ /* for multi-level*/ + if (irq_handlers[irq].handler != NULL) (*irq_handlers[irq].handler) (irq_handlers[irq].arg); else { @@ -194,7 +206,11 @@ */ unmask = 0; } - + + m8260_ack_irq(irq); + + if (unmask) m8260_unmask_irq (irq); }
participants (2)
-
do
-
Jerry Van Baren