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

📄 irq.c

📁 linux-2.6.15.6
💻 C
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * arch/sh64/kernel/irq_cayman.c * * SH-5 Cayman Interrupt Support * * This file handles the board specific parts of the Cayman interrupt system * * Copyright (C) 2002 Stuart Menefy */#include <linux/config.h>#include <asm/irq.h>#include <asm/page.h>#include <asm/io.h>#include <linux/irq.h>#include <linux/interrupt.h>#include <linux/signal.h>#include <asm/cayman.h>unsigned long epld_virt;#define EPLD_BASE        0x04002000#define EPLD_STATUS_BASE (epld_virt + 0x10)#define EPLD_MASK_BASE   (epld_virt + 0x20)/* Note the SMSC SuperIO chip and SMSC LAN chip interrupts are all muxed onto   the same SH-5 interrupt */static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id, struct pt_regs *regs){        printk(KERN_INFO "CAYMAN: spurious SMSC interrupt\n");	return IRQ_NONE;}static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id, struct pt_regs *regs){        printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq);	return IRQ_NONE;}static struct irqaction cayman_action_smsc = {	.name		= "Cayman SMSC Mux",	.handler	= cayman_interrupt_smsc,	.flags		= SA_INTERRUPT,};static struct irqaction cayman_action_pci2 = {	.name		= "Cayman PCI2 Mux",	.handler	= cayman_interrupt_pci2,	.flags		= SA_INTERRUPT,};static void enable_cayman_irq(unsigned int irq){	unsigned long flags;	unsigned long mask;	unsigned int reg;	unsigned char bit;	irq -= START_EXT_IRQS;	reg = EPLD_MASK_BASE + ((irq / 8) << 2);	bit = 1<<(irq % 8);	local_irq_save(flags);	mask = ctrl_inl(reg);	mask |= bit;	ctrl_outl(mask, reg);	local_irq_restore(flags);}void disable_cayman_irq(unsigned int irq){	unsigned long flags;	unsigned long mask;	unsigned int reg;	unsigned char bit;	irq -= START_EXT_IRQS;	reg = EPLD_MASK_BASE + ((irq / 8) << 2);	bit = 1<<(irq % 8);	local_irq_save(flags);	mask = ctrl_inl(reg);	mask &= ~bit;	ctrl_outl(mask, reg);	local_irq_restore(flags);}static void ack_cayman_irq(unsigned int irq){	disable_cayman_irq(irq);}static void end_cayman_irq(unsigned int irq){	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))		enable_cayman_irq(irq);}static unsigned int startup_cayman_irq(unsigned int irq){	enable_cayman_irq(irq);	return 0; /* never anything pending */}static void shutdown_cayman_irq(unsigned int irq){	disable_cayman_irq(irq);}struct hw_interrupt_type cayman_irq_type = {	.typename	= "Cayman-IRQ",	.startup	= startup_cayman_irq,	.shutdown	= shutdown_cayman_irq,	.enable		= enable_cayman_irq,	.disable	= disable_cayman_irq,	.ack		= ack_cayman_irq,	.end		= end_cayman_irq,};int cayman_irq_demux(int evt){	int irq = intc_evt_to_irq[evt];	if (irq == SMSC_IRQ) {		unsigned long status;		int i;		status = ctrl_inl(EPLD_STATUS_BASE) &			 ctrl_inl(EPLD_MASK_BASE) & 0xff;		if (status == 0) {			irq = -1;		} else {			for (i=0; i<8; i++) {				if (status & (1<<i))					break;			}			irq = START_EXT_IRQS + i;		}	}	if (irq == PCI2_IRQ) {		unsigned long status;		int i;		status = ctrl_inl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &			 ctrl_inl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;		if (status == 0) {			irq = -1;		} else {			for (i=0; i<8; i++) {				if (status & (1<<i))					break;			}			irq = START_EXT_IRQS + (3 * 8) + i;		}	}	return irq;}#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)int cayman_irq_describe(char* p, int irq){	if (irq < NR_INTC_IRQS) {		return intc_irq_describe(p, irq);	} else if (irq < NR_INTC_IRQS + 8) {		return sprintf(p, "(SMSC %d)", irq - NR_INTC_IRQS);	} else if ((irq >= NR_INTC_IRQS + 24) && (irq < NR_INTC_IRQS + 32)) {		return sprintf(p, "(PCI2 %d)", irq - (NR_INTC_IRQS + 24));	}	return 0;}#endifvoid init_cayman_irq(void){	int i;	epld_virt = onchip_remap(EPLD_BASE, 1024, "EPLD");	if (!epld_virt) {		printk(KERN_ERR "Cayman IRQ: Unable to remap EPLD\n");		return;	}	for (i=0; i<NR_EXT_IRQS; i++) {		irq_desc[START_EXT_IRQS + i].handler = &cayman_irq_type;	}	/* Setup the SMSC interrupt */	setup_irq(SMSC_IRQ, &cayman_action_smsc);	setup_irq(PCI2_IRQ, &cayman_action_pci2);}

⌨️ 快捷键说明

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