From: Ingo Molnar Clean up the fastack concept by turning it into fasteoi and introducing the ->eoi() method for chips. This also allows the cleanup of an i386 EOI quirk - now the quirk is cleanly separated from the pure ACK implementation. Signed-off-by: Ingo Molnar Cc: Benjamin Herrenschmidt Cc: Roland Dreier Signed-off-by: Andrew Morton --- include/linux/irq.h | 6 ++++-- kernel/irq/chip.c | 25 ++++++++++++------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff -puN include/linux/irq.h~genirq-add-chip-eoi-fastack-fasteoi-core include/linux/irq.h --- a/include/linux/irq.h~genirq-add-chip-eoi-fastack-fasteoi-core +++ a/include/linux/irq.h @@ -74,7 +74,8 @@ struct proc_dir_entry; * @mask: mask an interrupt source * @mask_ack: ack and mask an interrupt source * @unmask: unmask an interrupt source - * @end: end of interrupt + * @eoi: end of interrupt - chip level + * @end: end of interrupt - flow level * @set_affinity: set the CPU affinity on SMP machines * @retrigger: resend an IRQ to the CPU * @set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ @@ -94,6 +95,7 @@ struct irq_chip { void (*mask)(unsigned int irq); void (*mask_ack)(unsigned int irq); void (*unmask)(unsigned int irq); + void (*eoi)(unsigned int irq); void (*end)(unsigned int irq); void (*set_affinity)(unsigned int irq, cpumask_t dest); @@ -288,7 +290,7 @@ extern int handle_IRQ_event(unsigned int extern void fastcall handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); extern void fastcall -handle_fastack_irq(unsigned int irq, struct irq_desc *desc, +handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); extern void fastcall handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs); diff -puN kernel/irq/chip.c~genirq-add-chip-eoi-fastack-fasteoi-core kernel/irq/chip.c --- a/kernel/irq/chip.c~genirq-add-chip-eoi-fastack-fasteoi-core +++ a/kernel/irq/chip.c @@ -280,18 +280,18 @@ out: } /** - * handle_fastack_irq - irq handler for transparent controllers + * handle_fasteoi_irq - irq handler for transparent controllers * @irq: the interrupt number * @desc: the interrupt description structure for this irq * @regs: pointer to a register structure * - * Only a single callback will be issued to the chip: an ->ack() + * Only a single callback will be issued to the chip: an ->eoi() * call when the interrupt has been serviced. This enables support * for modern forms of interrupt handlers, which handle the flow * details in hardware, transparently. */ void fastcall -handle_fastack_irq(unsigned int irq, struct irq_desc *desc, +handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); @@ -327,10 +327,9 @@ handle_fastack_irq(unsigned int irq, str spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; out: - if (!(desc->status & IRQ_DISABLED)) - desc->chip->ack(irq); - else + if (unlikely(desc->status & IRQ_DISABLED)) desc->chip->mask(irq); + desc->chip->eoi(irq); spin_unlock(&desc->lock); } @@ -510,19 +509,19 @@ handle_irq_name(void fastcall (*handle)( struct pt_regs *)) { if (handle == handle_level_irq) - return "level "; - if (handle == handle_fastack_irq) - return "level "; + return "level "; + if (handle == handle_fasteoi_irq) + return "fasteoi"; if (handle == handle_edge_irq) - return "edge "; + return "edge "; if (handle == handle_simple_irq) - return "simple"; + return "simple "; #ifdef CONFIG_SMP if (handle == handle_percpu_irq) - return "percpu"; + return "percpu "; #endif if (handle == handle_bad_irq) - return "bad "; + return "bad "; return NULL; } _