⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq.c

📁 该文件是rt_linux
💻 C
字号:
/* *  arch/mips/philips/nino/irq.c * *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  Interrupt service routines for Philips Nino */#include <linux/init.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/mipsregs.h>#include <asm/tx3912.h>#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);static void enable_irq6(unsigned int irq){	if(irq == 0) {		outl(inl(TX3912_INT6_ENABLE) |			TX3912_INT6_ENABLE_PRIORITYMASK_PERINT,			TX3912_INT6_ENABLE);		outl(inl(TX3912_INT5_ENABLE) | TX3912_INT5_PERINT,			TX3912_INT5_ENABLE);	}	if(irq == 3) {		outl(inl(TX3912_INT6_ENABLE) |			TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT,			TX3912_INT6_ENABLE);		outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_RX_BITS,			TX3912_INT2_ENABLE);	}}static unsigned int startup_irq6(unsigned int irq){	enable_irq6(irq);	return 0;		/* Never anything pending  */}static void disable_irq6(unsigned int irq){	if(irq == 0) {		outl(inl(TX3912_INT6_ENABLE) &			~TX3912_INT6_ENABLE_PRIORITYMASK_PERINT,			TX3912_INT6_ENABLE);		outl(inl(TX3912_INT5_ENABLE) & ~TX3912_INT5_PERINT,			TX3912_INT5_ENABLE);		outl(inl(TX3912_INT5_CLEAR) | TX3912_INT5_PERINT,			TX3912_INT5_CLEAR);	}	if(irq == 3) {		outl(inl(TX3912_INT6_ENABLE) &			~TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT,			TX3912_INT6_ENABLE);		outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_RX_BITS,			TX3912_INT2_ENABLE);	}}#define shutdown_irq6		disable_irq6#define mask_and_ack_irq6	disable_irq6static void end_irq6(unsigned int irq){	if(!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))		enable_irq6(irq);}static struct hw_interrupt_type irq6_type = {	"MIPS",	startup_irq6,	shutdown_irq6,	enable_irq6,	disable_irq6,	mask_and_ack_irq6,	end_irq6,	NULL};void irq6_dispatch(struct pt_regs *regs){	int irq = -1;	if((inl(TX3912_INT6_STATUS) & TX3912_INT6_STATUS_INTVEC_UARTARXINT) ==		TX3912_INT6_STATUS_INTVEC_UARTARXINT) {		irq = 3;		goto done;	}	if ((inl(TX3912_INT6_STATUS) & TX3912_INT6_STATUS_INTVEC_PERINT) ==		TX3912_INT6_STATUS_INTVEC_PERINT) {		irq = 0;		goto done;	}	/* if irq == -1, then interrupt was cleared or is invalid */	if (irq == -1) {		panic("Unhandled High Priority PR31700 Interrupt = 0x%08x",			inl(TX3912_INT6_STATUS));	}done:	do_IRQ(irq, regs);}static void enable_irq4(unsigned int irq){	set_cp0_status(STATUSF_IP4);	if (irq == 2) {		outl(inl(TX3912_INT2_CLEAR) | TX3912_INT2_UARTA_TX_BITS,			TX3912_INT2_CLEAR);		outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_TX_BITS,			TX3912_INT2_ENABLE);	}}static unsigned int startup_irq4(unsigned int irq){	enable_irq4(irq);	return 0;		/* Never anything pending  */}static void disable_irq4(unsigned int irq){	clear_cp0_status(STATUSF_IP4);}#define shutdown_irq4		disable_irq4#define mask_and_ack_irq4	disable_irq4static void end_irq4(unsigned int irq){	if(!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))		enable_irq4(irq);}static struct hw_interrupt_type irq4_type = {	"MIPS",	startup_irq4,	shutdown_irq4,	enable_irq4,	disable_irq4,	mask_and_ack_irq4,	end_irq4,	NULL};void irq4_dispatch(struct pt_regs *regs){	int irq = -1;	if(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTA_TX_BITS) {		irq = 2;		goto done;	}	/* if irq == -1, then interrupt was cleared or is invalid */	if (irq == -1) {		printk("PR31700 Interrupt Status Register 1 = 0x%08x\n",			inl(TX3912_INT1_STATUS));		printk("PR31700 Interrupt Status Register 2 = 0x%08x\n",			inl(TX3912_INT2_STATUS));		printk("PR31700 Interrupt Status Register 3 = 0x%08x\n",			inl(TX3912_INT3_STATUS));		printk("PR31700 Interrupt Status Register 4 = 0x%08x\n",			inl(TX3912_INT4_STATUS));		printk("PR31700 Interrupt Status Register 5 = 0x%08x\n",			inl(TX3912_INT5_STATUS));		panic("Unhandled Low Priority PR31700 Interrupt");	}done:	do_IRQ(irq, regs);	return;}void irq_bad(struct pt_regs *regs){	/* This should never happen */	printk(" CAUSE register = 0x%08lx\n", regs->cp0_cause);	printk("STATUS register = 0x%08lx\n", regs->cp0_status);	printk("   EPC register = 0x%08lx\n", regs->cp0_epc);	panic("Stray interrupt, spinning...");}void __init nino_irq_setup(void){	extern asmlinkage void ninoIRQ(void);	unsigned int i;	/* Disable all hardware interrupts */	change_cp0_status(ST0_IM, 0x00);	/* Clear interrupts */	outl(0xffffffff, TX3912_INT1_CLEAR);	outl(0xffffffff, TX3912_INT2_CLEAR);	outl(0xffffffff, TX3912_INT3_CLEAR);	outl(0xffffffff, TX3912_INT4_CLEAR);	outl(0xffffffff, TX3912_INT5_CLEAR);	/*	 * Disable all PR31700 interrupts. We let the various	 * device drivers in the system register themselves	 * and set the proper hardware bits.	 */	outl(0x00000000, TX3912_INT1_ENABLE);	outl(0x00000000, TX3912_INT2_ENABLE);	outl(0x00000000, TX3912_INT3_ENABLE);	outl(0x00000000, TX3912_INT4_ENABLE);	outl(0x00000000, TX3912_INT5_ENABLE);	/* Initialize IRQ vector table */	init_generic_irq();	/* Initialize IRQ action handlers */	for (i = 0; i < 16; i++) {		hw_irq_controller *handler = NULL;		if (i == 0 || i == 3)			handler		= &irq6_type;		else			handler		= &irq4_type;		irq_desc[i].status	= IRQ_DISABLED;		irq_desc[i].action	= 0;		irq_desc[i].depth	= 1;		irq_desc[i].handler	= handler;	}	/* Set up the external interrupt exception vector */	set_except_vector(0, ninoIRQ);	/* Enable high priority interrupts */	outl(TX3912_INT6_ENABLE_GLOBALEN | TX3912_INT6_ENABLE_HIGH_PRIORITY,		TX3912_INT6_ENABLE);	/* Enable all interrupts */	change_cp0_status(ST0_IM, ALLINTS);}void (*irq_setup)(void);void __init init_IRQ(void){#ifdef CONFIG_REMOTE_DEBUG	extern void breakpoint(void);	extern void set_debug_traps(void);	printk("Wait for gdb client connection ...\n");	set_debug_traps();	breakpoint();#endif	/* Invoke board-specific irq setup */	irq_setup();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -