X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Ftx4927%2Fcommon%2Ftx4927_irq.c;h=cd176f6a06c8c297c2e5bb7282b612ad552ee0f2;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=14591d16e41a64b51e5d4133c1253cf5d8ac608f;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 14591d16e..cd176f6a0 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -23,7 +23,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include @@ -37,7 +36,7 @@ #include #include #include -#include +#include #include #include #include @@ -48,8 +47,6 @@ /* * DEBUG */ -#define TX4927_IRQ_CHECK_CP0 -#define TX4927_IRQ_CHECK_PIC #undef TX4927_IRQ_DEBUG @@ -145,11 +142,11 @@ static void tx4927_irq_pic_end(unsigned int irq); * Kernel structs for all pic's */ -static spinlock_t tx4927_cp0_lock = SPIN_LOCK_UNLOCKED; -static spinlock_t tx4927_pic_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(tx4927_cp0_lock); +static DEFINE_SPINLOCK(tx4927_pic_lock); #define TX4927_CP0_NAME "TX4927-CP0" -static struct hw_interrupt_type tx4927_irq_cp0_type = { +static struct irq_chip tx4927_irq_cp0_type = { .typename = TX4927_CP0_NAME, .startup = tx4927_irq_cp0_startup, .shutdown = tx4927_irq_cp0_shutdown, @@ -161,7 +158,7 @@ static struct hw_interrupt_type tx4927_irq_cp0_type = { }; #define TX4927_PIC_NAME "TX4927-PIC" -static struct hw_interrupt_type tx4927_irq_pic_type = { +static struct irq_chip tx4927_irq_pic_type = { .typename = TX4927_PIC_NAME, .startup = tx4927_irq_pic_startup, .shutdown = tx4927_irq_pic_shutdown, @@ -172,7 +169,7 @@ static struct hw_interrupt_type tx4927_irq_pic_type = { .set_affinity = NULL }; -#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } static struct irqaction tx4927_irq_pic_action = TX4927_PIC_ACTION(TX4927_PIC_NAME); @@ -229,7 +226,7 @@ static void __init tx4927_irq_cp0_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &tx4927_irq_cp0_type; + irq_desc[i].chip = &tx4927_irq_cp0_type; } return; @@ -239,16 +236,6 @@ static unsigned int tx4927_irq_cp0_startup(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); -#ifdef TX4927_IRQ_CHECK_CP0 - { - if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - tx4927_irq_cp0_enable(irq); return (0); @@ -258,16 +245,6 @@ static void tx4927_irq_cp0_shutdown(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); -#ifdef TX4927_IRQ_CHECK_CP0 - { - if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - tx4927_irq_cp0_disable(irq); return; @@ -279,16 +256,6 @@ static void tx4927_irq_cp0_enable(unsigned int irq) TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); -#ifdef TX4927_IRQ_CHECK_CP0 - { - if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - spin_lock_irqsave(&tx4927_cp0_lock, flags); tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); @@ -304,16 +271,6 @@ static void tx4927_irq_cp0_disable(unsigned int irq) TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); -#ifdef TX4927_IRQ_CHECK_CP0 - { - if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - spin_lock_irqsave(&tx4927_cp0_lock, flags); tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); @@ -327,16 +284,6 @@ static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); -#ifdef TX4927_IRQ_CHECK_CP0 - { - if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - tx4927_irq_cp0_disable(irq); return; @@ -346,16 +293,6 @@ static void tx4927_irq_cp0_end(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); -#ifdef TX4927_IRQ_CHECK_CP0 - { - if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4927_irq_cp0_enable(irq); } @@ -497,7 +434,7 @@ static void __init tx4927_irq_pic_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &tx4927_irq_pic_type; + irq_desc[i].chip = &tx4927_irq_pic_type; } setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); @@ -516,16 +453,6 @@ static unsigned int tx4927_irq_pic_startup(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); -#ifdef TX4927_IRQ_CHECK_PIC - { - if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - tx4927_irq_pic_enable(irq); return (0); @@ -535,16 +462,6 @@ static void tx4927_irq_pic_shutdown(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); -#ifdef TX4927_IRQ_CHECK_PIC - { - if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - tx4927_irq_pic_disable(irq); return; @@ -556,16 +473,6 @@ static void tx4927_irq_pic_enable(unsigned int irq) TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); -#ifdef TX4927_IRQ_CHECK_PIC - { - if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - spin_lock_irqsave(&tx4927_pic_lock, flags); tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, @@ -582,16 +489,6 @@ static void tx4927_irq_pic_disable(unsigned int irq) TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); -#ifdef TX4927_IRQ_CHECK_PIC - { - if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - spin_lock_irqsave(&tx4927_pic_lock, flags); tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), @@ -606,16 +503,6 @@ static void tx4927_irq_pic_mask_and_ack(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); -#ifdef TX4927_IRQ_CHECK_PIC - { - if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - tx4927_irq_pic_disable(irq); return; @@ -625,16 +512,6 @@ static void tx4927_irq_pic_end(unsigned int irq) { TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); -#ifdef TX4927_IRQ_CHECK_PIC - { - if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { - TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, - "bad irq=%d \n", irq); - panic("\n"); - } - } -#endif - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4927_irq_pic_enable(irq); } @@ -647,8 +524,6 @@ static void tx4927_irq_pic_end(unsigned int irq) */ void __init tx4927_irq_init(void) { - extern asmlinkage void tx4927_irq_handler(void); - TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); @@ -657,16 +532,12 @@ void __init tx4927_irq_init(void) TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); tx4927_irq_pic_init(); - TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, - "=Calling set_except_vector(tx4927_irq_handler)\n"); - set_except_vector(0, tx4927_irq_handler); - TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); return; } -int tx4927_irq_nested(void) +static int tx4927_irq_nested(void) { int sw_irq = 0; u32 level2; @@ -704,3 +575,25 @@ int tx4927_irq_nested(void) return (sw_irq); } + +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_status() & read_c0_cause(); + + if (pending & STATUSF_IP7) /* cpu timer */ + do_IRQ(TX4927_IRQ_CPU_TIMER, regs); + else if (pending & STATUSF_IP2) { /* tx4927 pic */ + unsigned int irq = tx4927_irq_nested(); + + if (unlikely(irq == 0)) { + spurious_interrupt(regs); + return; + } + do_IRQ(irq, regs); + } else if (pending & STATUSF_IP0) /* user line 0 */ + do_IRQ(TX4927_IRQ_USER0, regs); + else if (pending & STATUSF_IP1) /* user line 1 */ + do_IRQ(TX4927_IRQ_USER1, regs); + else + spurious_interrupt(regs); +}