fix: interrupt handler for multiple sources

This commit is contained in:
Michal Simek 2007-05-07 17:22:25 +02:00
parent 48fbd3a4cd
commit 42efed6130
3 changed files with 15 additions and 10 deletions

View file

@ -27,6 +27,7 @@
#include <common.h> #include <common.h>
#include <command.h> #include <command.h>
#include <asm/microblaze_intc.h> #include <asm/microblaze_intc.h>
#include <asm/asm.h>
#undef DEBUG_INT #undef DEBUG_INT
@ -106,7 +107,6 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg)
act->count = 0; act->count = 0;
enable_one_interrupt (irq); enable_one_interrupt (irq);
} else { /* disable */ } else { /* disable */
act->handler = (interrupt_handler_t *) def_hdlr; act->handler = (interrupt_handler_t *) def_hdlr;
act->arg = (void *)irq; act->arg = (void *)irq;
disable_one_interrupt (irq); disable_one_interrupt (irq);
@ -147,12 +147,13 @@ int interrupts_init (void)
void interrupt_handler (void) void interrupt_handler (void)
{ {
int irqs; int irqs = (intc->isr & intc->ier); /* find active interrupt */
irqs = (intc->isr & intc->ier); /* find active interrupt */ int i = 1;
#ifdef DEBUG_INT #ifdef DEBUG_INT
int value;
printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
intc->iar, intc->mer); intc->iar, intc->mer);
R14(value);
printf ("Interrupt handler on %x line, r14 %x\n", irqs, value); printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
#endif #endif
struct irq_action *act = vecs; struct irq_action *act = vecs;
@ -165,15 +166,19 @@ void interrupt_handler (void)
#endif #endif
act->handler (act->arg); act->handler (act->arg);
act->count++; act->count++;
intc->iar = i;
return;
} }
irqs >>= 1; irqs >>= 1;
act++; act++;
i <<= 1;
} }
intc->iar = 0xFFFFFFFF; /* erase all events */
#ifdef DEBUG #ifdef DEBUG_INT
printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr, printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
intc->ier, intc->iar, intc->mer); intc->ier, intc->iar, intc->mer);
printf ("Interrupt handler on %x line, r14\n", irqs); R14(value);
printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
#endif #endif
} }
#endif #endif

View file

@ -24,6 +24,7 @@
#include <common.h> #include <common.h>
#include <asm/microblaze_timer.h> #include <asm/microblaze_timer.h>
#include <asm/microblaze_intc.h>
volatile int timestamp = 0; volatile int timestamp = 0;
@ -44,9 +45,6 @@ void set_timer (ulong t)
#ifdef CFG_INTC_0 #ifdef CFG_INTC_0
#ifdef CFG_TIMER_0 #ifdef CFG_TIMER_0
extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
void *arg);
microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR); microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR);
void timer_isr (void *arg) void timer_isr (void *arg)

View file

@ -39,3 +39,5 @@ struct irq_action {
int count; /* number of interrupt */ int count; /* number of interrupt */
}; };
void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
void *arg);