Skip to content

Commit

Permalink
xtensa: clean up do_interrupt/do_IRQ
Browse files Browse the repository at this point in the history
- 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>
  • Loading branch information
Max Filippov authored and Chris Zankel committed Jan 14, 2014
1 parent cbd1de2 commit 9962323
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 20 deletions.
6 changes: 0 additions & 6 deletions arch/xtensa/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,13 @@ 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) {
printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
__func__, hwirq);
}

irq_enter();

#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
{
Expand All @@ -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)
Expand Down
23 changes: 9 additions & 14 deletions arch/xtensa/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -227,21 +230,13 @@ void do_interrupt(struct pt_regs *regs)
}

if (level == 0)
return;

/*
* 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);
}
break;

do_IRQ(__ffs(int_at_level), regs);
}

irq_exit();
set_irq_regs(old_regs);
}

/*
Expand Down

0 comments on commit 9962323

Please sign in to comment.