diff options
Diffstat (limited to 'arch/mips/vr41xx/common/irq.c')
| -rw-r--r-- | arch/mips/vr41xx/common/irq.c | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 4733c534446..ae0e4ee6c61 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c @@ -1,7 +1,7 @@ /* * Interrupt handing routines for NEC VR4100 series. * - * Copyright (C) 2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * Copyright (C) 2005-2007 Yoichi Yuasa <yuasa@linux-mips.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,24 +19,24 @@ */ #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/irq.h> #include <asm/irq_cpu.h> -#include <asm/system.h> #include <asm/vr41xx/irq.h> typedef struct irq_cascade { - int (*get_irq)(unsigned int, struct pt_regs *); + int (*get_irq)(unsigned int); } irq_cascade_t; static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned; static struct irqaction cascade_irqaction = { .handler = no_action, - .mask = CPU_MASK_NONE, .name = "cascade", + .flags = IRQF_NO_THREAD, }; -int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)) +int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int)) { int retval = 0; @@ -59,10 +59,9 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *) EXPORT_SYMBOL_GPL(cascade_irq); -static void irq_dispatch(unsigned int irq, struct pt_regs *regs) +static void irq_dispatch(unsigned int irq) { irq_cascade_t *cascade; - struct irq_desc *desc; if (irq >= NR_IRQS) { atomic_inc(&irq_err_count); @@ -71,45 +70,55 @@ static void irq_dispatch(unsigned int irq, struct pt_regs *regs) cascade = irq_cascade + irq; if (cascade->get_irq != NULL) { - unsigned int source_irq = irq; - desc = irq_desc + source_irq; - desc->chip->ack(source_irq); - irq = cascade->get_irq(irq, regs); - if (irq < 0) + struct irq_desc *desc = irq_to_desc(irq); + struct irq_data *idata = irq_desc_get_irq_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + int ret; + + if (chip->irq_mask_ack) + chip->irq_mask_ack(idata); + else { + chip->irq_mask(idata); + chip->irq_ack(idata); + } + ret = cascade->get_irq(irq); + irq = ret; + if (ret < 0) atomic_inc(&irq_err_count); else - irq_dispatch(irq, regs); - desc->chip->end(source_irq); + irq_dispatch(irq); + if (!irqd_irq_disabled(idata) && chip->irq_unmask) + chip->irq_unmask(idata); } else - do_IRQ(irq, regs); + do_IRQ(irq); } -asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; if (pending & CAUSEF_IP7) - do_IRQ(7, regs); + do_IRQ(TIMER_IRQ); else if (pending & 0x7800) { if (pending & CAUSEF_IP3) - irq_dispatch(3, regs); + irq_dispatch(INT1_IRQ); else if (pending & CAUSEF_IP4) - irq_dispatch(4, regs); + irq_dispatch(INT2_IRQ); else if (pending & CAUSEF_IP5) - irq_dispatch(5, regs); + irq_dispatch(INT3_IRQ); else if (pending & CAUSEF_IP6) - irq_dispatch(6, regs); + irq_dispatch(INT4_IRQ); } else if (pending & CAUSEF_IP2) - irq_dispatch(2, regs); + irq_dispatch(INT0_IRQ); else if (pending & CAUSEF_IP0) - do_IRQ(0, regs); + do_IRQ(MIPS_SOFTINT0_IRQ); else if (pending & CAUSEF_IP1) - do_IRQ(1, regs); + do_IRQ(MIPS_SOFTINT1_IRQ); else - spurious_interrupt(regs); + spurious_interrupt(); } void __init arch_init_irq(void) { - mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); + mips_cpu_irq_init(); } |
