URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [ddb5xxx/] [ddb5476/] [vrc5476_irq.c] - Rev 1765
Compare with Previous | Blame | View Log
/* * The irq controller for vrc5476. * * Copyright (C) 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net * * 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 the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/types.h> #include <linux/ptrace.h> #include <asm/system.h> #include <asm/ddb5xxx/ddb5xxx.h> static int irq_base; static void vrc5476_irq_enable(uint irq) { nile4_enable_irq(irq - irq_base); } static void vrc5476_irq_disable(uint irq) { nile4_disable_irq(irq - irq_base); } static unsigned int vrc5476_irq_startup(uint irq) { nile4_enable_irq(irq - irq_base); return 0; } #define vrc5476_irq_shutdown vrc5476_irq_disable static void vrc5476_irq_ack(uint irq) { nile4_clear_irq(irq - irq_base); nile4_disable_irq(irq - irq_base); } static void vrc5476_irq_end(uint irq) { if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) vrc5476_irq_enable(irq); } static hw_irq_controller vrc5476_irq_controller = { "vrc5476", vrc5476_irq_startup, vrc5476_irq_shutdown, vrc5476_irq_enable, vrc5476_irq_disable, vrc5476_irq_ack, vrc5476_irq_end, NULL /* no affinity stuff for UP */ }; void __init vrc5476_irq_init(u32 base) { extern irq_desc_t irq_desc[]; u32 i; irq_base = base; for (i= base; i< base + NUM_VRC5476_IRQ; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; irq_desc[i].handler = &vrc5476_irq_controller; } } asmlinkage void vrc5476_irq_dispatch(struct pt_regs *regs) { extern void spurious_interrupt(void); u32 mask; int nile4_irq; mask = nile4_get_irq_stat(0); /* quick check for possible time interrupt */ if (mask & (1 << VRC5476_IRQ_GPT)) { do_IRQ(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT, regs); return; } /* check for i8259 interrupts */ if (mask & (1 << VRC5476_I8259_CASCADE)) { int i8259_irq = nile4_i8259_iack(); do_IRQ(I8259_IRQ_BASE + i8259_irq, regs); return; } /* regular nile4 interrupts (we should not really have any */ for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) { if (mask & 1) { do_IRQ(VRC5476_IRQ_BASE + nile4_irq, regs); return; } } spurious_interrupt(); }