X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Frb1xx-2.6%2Ffiles%2Farch%2Fmips%2Fadm5120%2Firq.c;fp=target%2Flinux%2Frb1xx-2.6%2Ffiles%2Farch%2Fmips%2Fadm5120%2Firq.c;h=46f3bb05ee4a344bd5a2071e5eb41f05debb8c47;hb=027fd7a0180b42880ecab87f92a10981f490ddeb;hp=0000000000000000000000000000000000000000;hpb=9af06a109175d4f226b23c8b698120d7d6e8d9e9;p=openwrt%2Fsvn-archive%2Farchive.git diff --git a/target/linux/rb1xx-2.6/files/arch/mips/adm5120/irq.c b/target/linux/rb1xx-2.6/files/arch/mips/adm5120/irq.c new file mode 100644 index 0000000000..46f3bb05ee --- /dev/null +++ b/target/linux/rb1xx-2.6/files/arch/mips/adm5120/irq.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) ADMtek Incorporated. + * Creator : daniell@admtek.com.tw + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 2001 MIPS Technologies, Inc. + * Copyright (C) 2001 Ralf Baechle + * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MIPS_CPU_TIMER_IRQ 7 + +extern int setup_irq(unsigned int irq, struct irqaction *irqaction); +extern irq_desc_t irq_desc[]; +extern asmlinkage void mipsIRQ(void); + +int mips_int_lock(void); +void mips_int_unlock(int); + +unsigned int mips_counter_frequency; + +#define ADM5120_INTC_REG(reg) (*(volatile u32 *)(KSEG1ADDR(0x12200000+(reg)))) +#define ADM5120_INTC_STATUS ADM5120_INTC_REG(0x00) +#define ADM5120_INTC_ENABLE ADM5120_INTC_REG(0x08) +#define ADM5120_INTC_DISABLE ADM5120_INTC_REG(0x0c) +#define ADM5120_IRQ_MAX 9 +#define ADM5120_IRQ_MASK 0x3ff + +void adm5120_hw0_irqdispatch(struct pt_regs *regs) +{ + unsigned long intsrc; + int i; + + intsrc = ADM5120_INTC_STATUS & ADM5120_IRQ_MASK; + + for (i = 0; intsrc; intsrc >>= 1, i++) + if (intsrc & 0x1) + do_IRQ(i); + else + spurious_interrupt(); +} + +void mips_timer_interrupt(struct pt_regs *regs) +{ + write_c0_compare(read_c0_count()+ mips_counter_frequency/HZ); + ll_timer_interrupt(MIPS_CPU_TIMER_IRQ); +} + +/* Main interrupt dispatcher */ +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int cp0_cause = read_c0_cause() & read_c0_status(); + + if (cp0_cause & CAUSEF_IP7) { + mips_timer_interrupt( regs); + } else if (cp0_cause & CAUSEF_IP2) { + adm5120_hw0_irqdispatch( regs); + } +} + +void enable_adm5120_irq(unsigned int irq) +{ + int s; + + /* Disable all interrupts (FIQ/IRQ) */ + s = mips_int_lock(); + + if ((irq < 0) || (irq > ADM5120_IRQ_MAX)) + goto err_exit; + + ADM5120_INTC_ENABLE = (1< ADM5120_IRQ_MAX)) + goto err_exit; + + ADM5120_INTC_DISABLE = (1<