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:
parent
cbd1de2e8e
commit
996232393b
|
@ -30,7 +30,6 @@ atomic_t irq_err_count;
|
|||
|
||||
asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
int irq = irq_find_mapping(NULL, hwirq);
|
||||
|
||||
if (hwirq >= NR_IRQS) {
|
||||
|
@ -38,8 +37,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
|
|||
__func__, hwirq);
|
||||
}
|
||||
|
||||
irq_enter();
|
||||
|
||||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||
/* Debugging check for stack overflow: is there less than 1KB free? */
|
||||
{
|
||||
|
@ -54,9 +51,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
|
|||
}
|
||||
#endif
|
||||
generic_handle_irq(irq);
|
||||
|
||||
irq_exit();
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
int arch_show_interrupts(struct seq_file *p, int prec)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue