From e6b18c3b3f63df3ed184403b1afb662974508906 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 1 Apr 2010 00:01:54 +0200 Subject: [PATCH] new irq handling code --- arch/lm32/kernel/entry.S | 38 ++++++++++++++++++++++++++++++-------- arch/lm32/kernel/irq.c | 27 ++++++--------------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/arch/lm32/kernel/entry.S b/arch/lm32/kernel/entry.S index 15d8d39..232d253 100644 --- a/arch/lm32/kernel/entry.S +++ b/arch/lm32/kernel/entry.S @@ -79,14 +79,13 @@ ENTRY(divide_by_zero_handler) KERNEL_EXCEPTION_VECTOR(160) ENTRY(interrupt_handler) - addi sp, sp, -128 - sw (sp+120), ra - calli _save_irq_frame - rcsr r1, IP - - addi r2, sp, 4 - calli asm_do_IRQ - bi _restore_irq_frame_and_return + bi _long_interrupt_handler + nop + nop + nop + nop + nop + nop nop ENTRY(system_call) @@ -358,6 +357,29 @@ ENTRY(sys_clone_wrapper) /* in IRQ we call a function between save and restore */ /* we therefore only save and restore the caller saved registers */ /* (r1-r10, ra, ea because an interrupt could interrupt another one) */ +_long_interrupt_handler: + addi sp, sp, -128 + sw (sp+120), ra + calli _save_irq_frame + + rcsr r2, IP + rcsr r3, IM + mvi r1, 0 + and r2, r2, r3 + mvi r3, 1 + be r2, r0, 3f +1: + and r4, r2, r3 + bne r4, r0, 2f + sli r3, r3, 1 + addi r1, r1, 1 + bi 1b +2: + addi r2, sp, 4 + calli asm_do_IRQ +3: + bi _restore_irq_frame_and_return + _save_irq_frame: sw (sp+8), r1 sw (sp+12), r2 diff --git a/arch/lm32/kernel/irq.c b/arch/lm32/kernel/irq.c index 2dd57f4..32e7256 100644 --- a/arch/lm32/kernel/irq.c +++ b/arch/lm32/kernel/irq.c @@ -188,31 +188,16 @@ asmlinkage void manage_signals_irq(struct pt_regs* regs); * come via this function. Instead, they should provide their * own 'handler' */ -asmlinkage void asm_do_IRQ(unsigned long vec, struct pt_regs *regs) +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *old_regs; - unsigned int irq; - - old_regs = set_irq_regs(regs); + struct pt_regs *old_regs = set_irq_regs(regs); irq_enter(); - /* Only process unmasked interrupts. - * This avoids a race condition if several interrupts - * arrive at the same time! - */ - vec &= lm32_current_irq_mask; - /* mask ALL interrupts we are going to process */ - lm32_irq_multimask(vec); - - /* decode irq */ - for (irq=0 ; irq<32; ++irq ) { - if ( vec & (1 << irq) ) { - generic_handle_irq(irq); /* < this (re)enables interrupts globally */ - lm32_irq_ack(irq); - lm32_irq_unmask(irq); - } - } + lm32_irq_mask(irq); + generic_handle_irq(irq); /* < this (re)enables interrupts globally */ + lm32_irq_ack(irq); + lm32_irq_unmask(irq); irq_exit(); -- 1.5.6.5