From 3260740c920ea811e18bc1743c863fce74ac89b7 Mon Sep 17 00:00:00 2001 From: florian Date: Mon, 2 Apr 2007 16:59:59 +0000 Subject: Add preliminary RouterBoard RB1xx support git-svn-id: svn://svn.openwrt.org/openwrt/trunk@6839 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../linux/rb1xx-2.6/files/arch/mips/adm5120/irq.c | 156 +++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 target/linux/rb1xx-2.6/files/arch/mips/adm5120/irq.c (limited to 'target/linux/rb1xx-2.6/files/arch/mips/adm5120/irq.c') 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 000000000..46f3bb05e --- /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<