xtensa: clean up do_interrupt/do_IRQ
- set up irq registers and call irq_enter/irq_exit once for each kernel entry due to interrupt; - don't attempt to clear current IRQ in the do_interrupt, IRQ handler will take care of it; - find pending interrupt with highest priority before every ISR invocation. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Chris Zankel <chris@zankel.net>
This commit is contained in:

committed by
Chris Zankel

parent
cbd1de2e8e
commit
996232393b
@@ -212,6 +212,9 @@ void do_interrupt(struct pt_regs *regs)
|
||||
XCHAL_INTLEVEL6_MASK,
|
||||
XCHAL_INTLEVEL7_MASK,
|
||||
};
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
|
||||
irq_enter();
|
||||
|
||||
for (;;) {
|
||||
unsigned intread = get_sr(interrupt);
|
||||
@@ -227,21 +230,13 @@ void do_interrupt(struct pt_regs *regs)
|
||||
}
|
||||
|
||||
if (level == 0)
|
||||
return;
|
||||
break;
|
||||
|
||||
/*
|
||||
* Clear the interrupt before processing, in case it's
|
||||
* edge-triggered or software-generated
|
||||
*/
|
||||
while (int_at_level) {
|
||||
unsigned i = __ffs(int_at_level);
|
||||
unsigned mask = 1 << i;
|
||||
|
||||
int_at_level ^= mask;
|
||||
set_sr(mask, intclear);
|
||||
do_IRQ(i, regs);
|
||||
}
|
||||
do_IRQ(__ffs(int_at_level), regs);
|
||||
}
|
||||
|
||||
irq_exit();
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user