📄 irq.c
字号:
return mask;}void restore_local_and_enable(int controller, unsigned long mask){ int i; unsigned long flags, new_mask; save_and_cli(flags); for (i=0; i<32; i++) { if (mask & (1<<i)) { if (controller) local_enable_irq(i+32); else local_enable_irq(i); } } if (controller) new_mask = au_readl(IC1_MASKSET); else new_mask = au_readl(IC0_MASKSET); restore_flags(flags);}static struct hw_interrupt_type rise_edge_irq_type = { "Au1000 Rise Edge", startup_irq, shutdown_irq, local_enable_irq, local_disable_irq, mask_and_ack_rise_edge_irq, end_irq, NULL};static struct hw_interrupt_type fall_edge_irq_type = { "Au1000 Fall Edge", startup_irq, shutdown_irq, local_enable_irq, local_disable_irq, mask_and_ack_fall_edge_irq, end_irq, NULL};static struct hw_interrupt_type level_irq_type = { "Au1000 Level", startup_irq, shutdown_irq, local_enable_irq, local_disable_irq, mask_and_ack_level_irq, end_irq, NULL};#ifdef CONFIG_PMvoid startup_match20_interrupt(void){ local_enable_irq(AU1000_TOY_MATCH2_INT);}#endifvoid __init init_IRQ(void){ int i; unsigned long cp0_status; extern char except_vec0_au1000; cp0_status = read_32bit_cp0_register(CP0_STATUS); memset(irq_desc, 0, sizeof(irq_desc)); set_except_vector(0, au1000_IRQ); init_generic_irq(); for (i = 0; i <= AU1000_MAX_INTR; i++) { switch (i) { case AU1000_UART0_INT: case AU1000_UART3_INT:#ifdef CONFIG_MIPS_PB1000 case AU1000_UART1_INT: case AU1000_UART2_INT: case AU1000_SSI0_INT: case AU1000_SSI1_INT:#endif#ifdef CONFIG_MIPS_PB1100 case AU1000_UART1_INT: case AU1000_SSI0_INT: case AU1000_SSI1_INT:#endif case AU1000_DMA_INT_BASE: case AU1000_DMA_INT_BASE+1: case AU1000_DMA_INT_BASE+2: case AU1000_DMA_INT_BASE+3: case AU1000_DMA_INT_BASE+4: case AU1000_DMA_INT_BASE+5: case AU1000_DMA_INT_BASE+6: case AU1000_DMA_INT_BASE+7: case AU1000_IRDA_TX_INT: case AU1000_IRDA_RX_INT: case AU1000_MAC0_DMA_INT:#ifdef CONFIG_MIPS_PB1000 case AU1000_MAC1_DMA_INT:#endif#ifdef CONFIG_MIPS_PB1500 case AU1000_MAC1_DMA_INT:#endif case AU1500_GPIO_204: setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); irq_desc[i].handler = &level_irq_type; break;#ifdef CONFIG_MIPS_PB1000 case AU1000_GPIO_15:#endif case AU1000_USB_HOST_INT:#ifdef CONFIG_MIPS_PB1500 case AU1000_PCI_INTA: case AU1000_PCI_INTB: case AU1000_PCI_INTC: case AU1000_PCI_INTD: case AU1500_GPIO_201: case AU1500_GPIO_202: case AU1500_GPIO_203: case AU1500_GPIO_205: case AU1500_GPIO_207:#endif#ifdef CONFIG_MIPS_PB1100 case AU1000_GPIO_9: // PCMCIA Card Fully_Interted# case AU1000_GPIO_10: // PCMCIA_STSCHG# case AU1000_GPIO_11: // PCMCIA_IRQ# case AU1000_GPIO_13: // DC_IRQ# case AU1000_GPIO_23: // 2-wire SCL#endif setup_local_irq(i, INTC_INT_LOW_LEVEL, 0); irq_desc[i].handler = &level_irq_type; break; case AU1000_ACSYNC_INT: case AU1000_AC97C_INT: case AU1000_TOY_INT: case AU1000_TOY_MATCH0_INT: case AU1000_TOY_MATCH1_INT: case AU1000_USB_DEV_SUS_INT: case AU1000_USB_DEV_REQ_INT: case AU1000_RTC_INT: case AU1000_RTC_MATCH0_INT: case AU1000_RTC_MATCH1_INT: case AU1000_RTC_MATCH2_INT: setup_local_irq(i, INTC_INT_RISE_EDGE, 0); irq_desc[i].handler = &rise_edge_irq_type; break; // Careful if you change match 2 request! // The interrupt handler is called directly // from the low level dispatch code. case AU1000_TOY_MATCH2_INT: setup_local_irq(i, INTC_INT_RISE_EDGE, 1); irq_desc[i].handler = &rise_edge_irq_type; break; default: /* active high, level interrupt */ setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); irq_desc[i].handler = &level_irq_type; break; } } set_cp0_status(ALLINTS);#ifdef CONFIG_REMOTE_DEBUG /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); breakpoint();#endif}/* * Interrupts are nested. Even if an interrupt handler is registered * as "fast", we might get another interrupt before we return from * intcX_reqX_irqdispatch(). */void intc0_req0_irqdispatch(struct pt_regs *regs){ int irq = 0, i; static unsigned long intc0_req0 = 0; intc0_req0 |= au_readl(IC0_REQ0INT); if (!intc0_req0) return; /* * Because of the tight timing of SETUP token to reply * transactions, the USB devices-side packet complete * interrupt needs the highest priority. */ if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) { intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT); do_IRQ(AU1000_USB_DEV_REQ_INT, regs); return; } for (i=0; i<32; i++) { if ((intc0_req0 & (1<<i))) { intc0_req0 &= ~(1<<i); do_IRQ(irq, regs); break; } irq++; }}void intc0_req1_irqdispatch(struct pt_regs *regs){ int irq = 0, i; static unsigned long intc0_req1 = 0; intc0_req1 = au_readl(IC0_REQ1INT); if (!intc0_req1) return; for (i=0; i<32; i++) { if ((intc0_req1 & (1<<i))) { intc0_req1 &= ~(1<<i);#ifdef CONFIG_PM if (i == AU1000_TOY_MATCH2_INT) { mask_and_ack_rise_edge_irq(irq); counter0_irq(irq, NULL, regs); local_enable_irq(irq); } else#endif { do_IRQ(irq, regs); } break; } irq++; }}/* * Interrupt Controller 1: * interrupts 32 - 63 */void intc1_req0_irqdispatch(struct pt_regs *regs){ int irq = 0, i; static unsigned long intc1_req0 = 0; volatile unsigned short levels, mdr; unsigned char ide_status; intc1_req0 |= au_readl(IC1_REQ0INT); if (!intc1_req0) return;#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ) au_writel(1, CPLD_AUX0); /* debug led 0 */#endif for (i=0; i<32; i++) { if ((intc1_req0 & (1<<i))) { intc1_req0 &= ~(1<<i);#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ) au_writel(2, CPLD_AUX0); /* turn on debug led 1 */ do_IRQ(irq+32, regs); au_writel(0, CPLD_AUX0); /* turn off debug led 1 */#else do_IRQ(irq+32, regs);#endif break; } irq++; }#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ) au_writel(0, CPLD_AUX0);#endif}void intc1_req1_irqdispatch(struct pt_regs *regs){ int irq = 0, i; static unsigned long intc1_req1 = 0; intc1_req1 |= au_readl(IC1_REQ1INT); if (!intc1_req1) return; for (i=0; i<32; i++) { if ((intc1_req1 & (1<<i))) { intc1_req1 &= ~(1<<i); do_IRQ(irq+32, regs); break; } irq++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -