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

📄 icu.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
{	irq_desc_t *desc = irq_desc + BCU_IRQ;	unsigned long flags;	spin_lock_irqsave(&desc->lock, flags);	write_icu2(BCUINTR, MBCUINTREG);	spin_unlock_irqrestore(&desc->lock, flags);}void vr41xx_disable_bcuint(void){	irq_desc_t *desc = irq_desc + BCU_IRQ;	unsigned long flags;	spin_lock_irqsave(&desc->lock, flags);	write_icu2(0, MBCUINTREG);	spin_unlock_irqrestore(&desc->lock, flags);}/*=======================================================================*/static unsigned int startup_sysint1_irq(unsigned int irq){	set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));	return 0; /* never anything pending */}static void shutdown_sysint1_irq(unsigned int irq){	clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));}static void enable_sysint1_irq(unsigned int irq){	set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));}#define disable_sysint1_irq	shutdown_sysint1_irq#define ack_sysint1_irq		shutdown_sysint1_irqstatic void end_sysint1_irq(unsigned int irq){	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))		set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));}static struct hw_interrupt_type sysint1_irq_type = {	.typename	= "SYSINT1",	.startup	= startup_sysint1_irq,	.shutdown	= shutdown_sysint1_irq,	.enable		= enable_sysint1_irq,	.disable	= disable_sysint1_irq,	.ack		= ack_sysint1_irq,	.end		= end_sysint1_irq,};/*=======================================================================*/static unsigned int startup_sysint2_irq(unsigned int irq){	set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));	return 0; /* never anything pending */}static void shutdown_sysint2_irq(unsigned int irq){	clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));}static void enable_sysint2_irq(unsigned int irq){	set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));}#define disable_sysint2_irq	shutdown_sysint2_irq#define ack_sysint2_irq		shutdown_sysint2_irqstatic void end_sysint2_irq(unsigned int irq){	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))		set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));}static struct hw_interrupt_type sysint2_irq_type = {	.typename	= "SYSINT2",	.startup	= startup_sysint2_irq,	.shutdown	= shutdown_sysint2_irq,	.enable		= enable_sysint2_irq,	.disable	= disable_sysint2_irq,	.ack		= ack_sysint2_irq,	.end		= end_sysint2_irq,};/*=======================================================================*/static inline int set_sysint1_assign(unsigned int irq, unsigned char assign){	irq_desc_t *desc = irq_desc + irq;	uint16_t intassign0, intassign1;	unsigned int pin;	pin = SYSINT1_IRQ_TO_PIN(irq);	spin_lock_irq(&desc->lock);	intassign0 = read_icu1(INTASSIGN0);	intassign1 = read_icu1(INTASSIGN1);	switch (pin) {	case 0:		intassign0 &= ~INTASSIGN_MASK;		intassign0 |= (uint16_t)assign;		break;	case 1:		intassign0 &= ~(INTASSIGN_MASK << 3);		intassign0 |= (uint16_t)assign << 3;		break;	case 2:		intassign0 &= ~(INTASSIGN_MASK << 6);		intassign0 |= (uint16_t)assign << 6;		break;	case 3:		intassign0 &= ~(INTASSIGN_MASK << 9);		intassign0 |= (uint16_t)assign << 9;		break;	case 8:		intassign0 &= ~(INTASSIGN_MASK << 12);		intassign0 |= (uint16_t)assign << 12;		break;	case 9:		intassign1 &= ~INTASSIGN_MASK;		intassign1 |= (uint16_t)assign;		break;	case 11:		intassign1 &= ~(INTASSIGN_MASK << 6);		intassign1 |= (uint16_t)assign << 6;		break;	case 12:		intassign1 &= ~(INTASSIGN_MASK << 9);		intassign1 |= (uint16_t)assign << 9;		break;	default:		return -EINVAL;	}	sysint1_assign[pin] = assign;	write_icu1(intassign0, INTASSIGN0);	write_icu1(intassign1, INTASSIGN1);	spin_unlock_irq(&desc->lock);	return 0;}static inline int set_sysint2_assign(unsigned int irq, unsigned char assign){	irq_desc_t *desc = irq_desc + irq;	uint16_t intassign2, intassign3;	unsigned int pin;	pin = SYSINT2_IRQ_TO_PIN(irq);	spin_lock_irq(&desc->lock);	intassign2 = read_icu1(INTASSIGN2);	intassign3 = read_icu1(INTASSIGN3);	switch (pin) {	case 0:		intassign2 &= ~INTASSIGN_MASK;		intassign2 |= (uint16_t)assign;		break;	case 1:		intassign2 &= ~(INTASSIGN_MASK << 3);		intassign2 |= (uint16_t)assign << 3;		break;	case 3:		intassign2 &= ~(INTASSIGN_MASK << 6);		intassign2 |= (uint16_t)assign << 6;		break;	case 4:		intassign2 &= ~(INTASSIGN_MASK << 9);		intassign2 |= (uint16_t)assign << 9;		break;	case 5:		intassign2 &= ~(INTASSIGN_MASK << 12);		intassign2 |= (uint16_t)assign << 12;		break;	case 6:		intassign3 &= ~INTASSIGN_MASK;		intassign3 |= (uint16_t)assign;		break;	case 7:		intassign3 &= ~(INTASSIGN_MASK << 3);		intassign3 |= (uint16_t)assign << 3;		break;	case 8:		intassign3 &= ~(INTASSIGN_MASK << 6);		intassign3 |= (uint16_t)assign << 6;		break;	case 9:		intassign3 &= ~(INTASSIGN_MASK << 9);		intassign3 |= (uint16_t)assign << 9;		break;	case 10:		intassign3 &= ~(INTASSIGN_MASK << 12);		intassign3 |= (uint16_t)assign << 12;		break;	default:		return -EINVAL;	}	sysint2_assign[pin] = assign;	write_icu1(intassign2, INTASSIGN2);	write_icu1(intassign3, INTASSIGN3);	spin_unlock_irq(&desc->lock);	return 0;}int vr41xx_set_intassign(unsigned int irq, unsigned char intassign){	int retval = -EINVAL;	if (current_cpu_data.cputype != CPU_VR4133)		return -EINVAL;	if (intassign > INTASSIGN_MAX)		return -EINVAL;	if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST)		retval = set_sysint1_assign(irq, intassign);	else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST)		retval = set_sysint2_assign(irq, intassign);	return retval;}EXPORT_SYMBOL(vr41xx_set_intassign);/*=======================================================================*/asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs){	uint16_t pend1, pend2;	uint16_t mask1, mask2;	int i;	pend1 = read_icu1(SYSINT1REG);	mask1 = read_icu1(MSYSINT1REG);	pend2 = read_icu2(SYSINT2REG);	mask2 = read_icu2(MSYSINT2REG);	mask1 &= pend1;	mask2 &= pend2;	if (mask1) {		for (i = 0; i < 16; i++) {			if (intnum == sysint1_assign[i] &&			    (mask1 & ((uint16_t)1 << i))) {				if (i == 8)					giuint_irq_dispatch(regs);				else					do_IRQ(SYSINT1_IRQ(i), regs);				return;			}		}	}	if (mask2) {		for (i = 0; i < 16; i++) {			if (intnum == sysint2_assign[i] &&			    (mask2 & ((uint16_t)1 << i))) {				do_IRQ(SYSINT2_IRQ(i), regs);				return;			}		}	}	printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2);	atomic_inc(&irq_err_count);}/*=======================================================================*/static int __init vr41xx_icu_init(void){	switch (current_cpu_data.cputype) {	case CPU_VR4111:	case CPU_VR4121:		icu1_base = SYSINT1REG_TYPE1;		icu2_base = SYSINT2REG_TYPE1;		break;	case CPU_VR4122:	case CPU_VR4131:	case CPU_VR4133:		icu1_base = SYSINT1REG_TYPE2;		icu2_base = SYSINT2REG_TYPE2;		break;	default:		printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n");		return -EINVAL;	}	write_icu1(0, MSYSINT1REG);	write_icu1(0xffff, MGIUINTLREG);	write_icu2(0, MSYSINT2REG);	write_icu2(0xffff, MGIUINTHREG);	return 0;}early_initcall(vr41xx_icu_init);/*=======================================================================*/static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL};static inline void init_vr41xx_icu_irq(void){	int i;	for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++)		irq_desc[i].handler = &sysint1_irq_type;	for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++)		irq_desc[i].handler = &sysint2_irq_type;	setup_irq(INT0_CASCADE_IRQ, &icu_cascade);	setup_irq(INT1_CASCADE_IRQ, &icu_cascade);	setup_irq(INT2_CASCADE_IRQ, &icu_cascade);	setup_irq(INT3_CASCADE_IRQ, &icu_cascade);	setup_irq(INT4_CASCADE_IRQ, &icu_cascade);}void __init init_IRQ(void){	memset(irq_desc, 0, sizeof(irq_desc));	init_generic_irq();	mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);	init_vr41xx_icu_irq();	init_vr41xx_giuint_irq();	set_except_vector(0, vr41xx_handle_interrupt);}

⌨️ 快捷键说明

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