Commit 99623239 authored by Max Filippov's avatar Max Filippov Committed by Chris Zankel

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: default avatarMax Filippov <jcmvbkbc@gmail.com>
Signed-off-by: default avatarChris Zankel <chris@zankel.net>
parent cbd1de2e
...@@ -30,7 +30,6 @@ atomic_t irq_err_count; ...@@ -30,7 +30,6 @@ atomic_t irq_err_count;
asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) 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); int irq = irq_find_mapping(NULL, hwirq);
if (hwirq >= NR_IRQS) { if (hwirq >= NR_IRQS) {
...@@ -38,8 +37,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) ...@@ -38,8 +37,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
__func__, hwirq); __func__, hwirq);
} }
irq_enter();
#ifdef CONFIG_DEBUG_STACKOVERFLOW #ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */ /* 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) ...@@ -54,9 +51,6 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
} }
#endif #endif
generic_handle_irq(irq); generic_handle_irq(irq);
irq_exit();
set_irq_regs(old_regs);
} }
int arch_show_interrupts(struct seq_file *p, int prec) int arch_show_interrupts(struct seq_file *p, int prec)
......
...@@ -212,6 +212,9 @@ void do_interrupt(struct pt_regs *regs) ...@@ -212,6 +212,9 @@ void do_interrupt(struct pt_regs *regs)
XCHAL_INTLEVEL6_MASK, XCHAL_INTLEVEL6_MASK,
XCHAL_INTLEVEL7_MASK, XCHAL_INTLEVEL7_MASK,
}; };
struct pt_regs *old_regs = set_irq_regs(regs);
irq_enter();
for (;;) { for (;;) {
unsigned intread = get_sr(interrupt); unsigned intread = get_sr(interrupt);
...@@ -227,21 +230,13 @@ void do_interrupt(struct pt_regs *regs) ...@@ -227,21 +230,13 @@ void do_interrupt(struct pt_regs *regs)
} }
if (level == 0) 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; do_IRQ(__ffs(int_at_level), regs);
set_sr(mask, intclear);
do_IRQ(i, regs);
}
} }
irq_exit();
set_irq_regs(old_regs);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment