/* * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology * Author: Fuxin Zhang, zhangfx@lemote.com * * 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 #include //#include #include //FIXME: Only provide functionality for gsc3280, should be move to a new place lately. #include //struct soc_soc_intc_regs volatile *soc_soc_hw0_icregs // = (struct soc_soc_intc_regs volatile *)(KSEG1ADDR(SOC_SOC_INTC_BASE)); static struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", }; static irqreturn_t blx_buserror_action(int irq, void *dev_id) { // struct pt_regs *regs = get_irq_regs(); volatile unsigned long int *buserror_status = (unsigned long int *)0xbc04a0c4; *buserror_status = 0x1; //BusError not accurately, so printk is useless. #if 0 printk(KERN_ERR "%s BusError, EPC: %lx RA: %lx\n", (regs->cp0_cause & 4) ? "Data" : "Instruction", regs->cp0_epc, regs->regs[31]); #endif return IRQ_HANDLED; } static struct irqaction buserror_irqaction = { .handler = blx_buserror_action, .name = "BusError", }; void gsc3280_soc_irq_init(int irq_base); void __init mach_init_irq(void) { /* init all controller * 16-23 ------> mips cpu interrupts * 24-46 ------> gsc3280 soc interrupts */ clear_c0_status(ST0_IM | ST0_BEV); local_irq_disable(); mips_cpu_irq_init(); gsc3280_soc_irq_init(MIPS_CPU_IRQ_BASE + 8); setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); /* 8259 irq at IP7 */ setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); /* response buserror from DWC interrupt, IRQ number in dwc-irq.c */ setup_irq(MIPS_CPU_IRQ_BASE + 8 + 30, &buserror_irqaction); } void soc_soc_hw0_irqdispatch(void); asmlinkage void mach_irq_dispatch(unsigned int pending) { if (pending & CAUSEF_IP7) { do_IRQ(MIPS_CPU_IRQ_BASE + 7); /* add end */ } else if (pending & CAUSEF_IP2) { soc_soc_hw0_irqdispatch(); } else { // printk("spurious: cause = 0x%x, status = 0x%x\n", cause, status); spurious_interrupt(); } }