* [U-Boot-Users] Bogus External Interrupt
@ 2006-03-02 22:07 do
2006-03-03 15:13 ` Jerry Van Baren
0 siblings, 1 reply; 3+ messages in thread
From: do @ 2006-03-02 22:07 UTC (permalink / raw)
To: u-boot
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!
^ permalink raw reply [flat|nested] 3+ messages in thread
* [U-Boot-Users] Bogus External Interrupt
2006-03-02 22:07 [U-Boot-Users] Bogus External Interrupt do
@ 2006-03-03 15:13 ` Jerry Van Baren
2006-03-07 20:26 ` [U-Boot-Users] " do
0 siblings, 1 reply; 3+ messages in thread
From: Jerry Van Baren @ 2006-03-03 15:13 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* [U-Boot-Users] Re: Bogus External Interrupt
2006-03-03 15:13 ` Jerry Van Baren
@ 2006-03-07 20:26 ` do
0 siblings, 0 replies; 3+ messages in thread
From: do @ 2006-03-07 20:26 UTC (permalink / raw)
To: u-boot
Jerry Van Baren napisa?(a):
> 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.
>
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);
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2006-03-07 20:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-02 22:07 [U-Boot-Users] Bogus External Interrupt do
2006-03-03 15:13 ` Jerry Van Baren
2006-03-07 20:26 ` [U-Boot-Users] " do
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox