From: Ingo Molnar This patch converts all the i386 PIC controllers (except VisWS and Voyager, which I could not test - but which should still work as old-style IRQ layers) to the new and simpler irq-chip interrupt handling layer. [akpm@osdl.org: build fix] [mingo@elte.hu: enable fasteoi handler for i386 level-triggered IO-APIC irqs] Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner Cc: Benjamin Herrenschmidt Cc: Roland Dreier Signed-off-by: Andrew Morton --- arch/i386/kernel/i8259.c | 45 +++------ arch/i386/kernel/io_apic.c | 160 ++++++++++++----------------------- arch/i386/kernel/irq.c | 19 ++-- include/asm-i386/hw_irq.h | 2 4 files changed, 81 insertions(+), 145 deletions(-) diff -puN arch/i386/kernel/i8259.c~genirq-convert-the-i386-architecture-to-irq-chips arch/i386/kernel/i8259.c --- a/arch/i386/kernel/i8259.c~genirq-convert-the-i386-architecture-to-irq-chips +++ a/arch/i386/kernel/i8259.c @@ -34,39 +34,21 @@ * moves to arch independent land */ -DEFINE_SPINLOCK(i8259A_lock); - -static void end_8259A_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && - irq_desc[irq].action) - enable_8259A_irq(irq); -} - -#define shutdown_8259A_irq disable_8259A_irq - static void mask_and_ack_8259A(unsigned int); -unsigned int startup_8259A_irq(unsigned int irq) -{ - enable_8259A_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type i8259A_irq_type = { - .typename = "XT-PIC", - .startup = startup_8259A_irq, - .shutdown = shutdown_8259A_irq, - .enable = enable_8259A_irq, - .disable = disable_8259A_irq, - .ack = mask_and_ack_8259A, - .end = end_8259A_irq, +static struct irq_chip i8259A_chip = { + .name = "XT-PIC", + .mask = disable_8259A_irq, + .unmask = enable_8259A_irq, + .mask_ack = mask_and_ack_8259A, }; /* * 8259A PIC functions to handle ISA devices: */ +DEFINE_SPINLOCK(i8259A_lock); + /* * This contains the irq mask for both 8259A irq controllers, */ @@ -131,7 +113,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<orig_eax; + struct irq_desc *desc = irq_desc + irq; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; u32 *isp; @@ -98,7 +99,7 @@ fastcall unsigned int do_IRQ(struct pt_r * current stack (which is the irq stack already after all) */ if (curctx != irqctx) { - int arg1, arg2, ebx; + int arg1, arg2, arg3, ebx; /* build the stack frame on the IRQ stack */ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); @@ -114,16 +115,17 @@ fastcall unsigned int do_IRQ(struct pt_r (curctx->tinfo.preempt_count & SOFTIRQ_MASK); asm volatile( - " xchgl %%ebx,%%esp \n" - " call __do_IRQ \n" + " xchgl %%ebx,%%esp \n" + " call *%%edi \n" " movl %%ebx,%%esp \n" - : "=a" (arg1), "=d" (arg2), "=b" (ebx) - : "0" (irq), "1" (regs), "2" (isp) - : "memory", "cc", "ecx" + : "=a" (arg1), "=d" (arg2), "=c" (arg3), "=b" (ebx) + : "0" (irq), "1" (desc), "2" (regs), "3" (isp), + "D" (desc->handle_irq) + : "memory", "cc" ); } else #endif - __do_IRQ(irq, regs); + desc->handle_irq(irq, desc, regs); out_exit: irq_exit(); @@ -258,7 +260,8 @@ int show_interrupts(struct seq_file *p, for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %8s", irq_desc[i].chip->name); + seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff -puN include/asm-i386/hw_irq.h~genirq-convert-the-i386-architecture-to-irq-chips include/asm-i386/hw_irq.h --- a/include/asm-i386/hw_irq.h~genirq-convert-the-i386-architecture-to-irq-chips +++ a/include/asm-i386/hw_irq.h @@ -17,8 +17,6 @@ #include #include -struct hw_interrupt_type; - #define NMI_VECTOR 0x02 /* _