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

📄 irq.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}static struct irq_chip s3c_irq_uart1 = {	.name		= "s3c-uart1",	.mask		= s3c_irq_uart1_mask,	.unmask		= s3c_irq_uart1_unmask,	.ack		= s3c_irq_uart1_ack,};/* UART2 */static voids3c_irq_uart2_mask(unsigned int irqno){	s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);}static voids3c_irq_uart2_unmask(unsigned int irqno){	s3c_irqsub_unmask(irqno, INTMSK_UART2);}static voids3c_irq_uart2_ack(unsigned int irqno){	s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);}static struct irq_chip s3c_irq_uart2 = {	.name		= "s3c-uart2",	.mask		= s3c_irq_uart2_mask,	.unmask		= s3c_irq_uart2_unmask,	.ack		= s3c_irq_uart2_ack,};/* ADC and Touchscreen */static voids3c_irq_adc_mask(unsigned int irqno){	s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);}static voids3c_irq_adc_unmask(unsigned int irqno){	s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);}static voids3c_irq_adc_ack(unsigned int irqno){	s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);}static struct irq_chip s3c_irq_adc = {	.name		= "s3c-adc",	.mask		= s3c_irq_adc_mask,	.unmask		= s3c_irq_adc_unmask,	.ack		= s3c_irq_adc_ack,};/* irq demux for adc */static void s3c_irq_demux_adc(unsigned int irq,			      struct irq_desc *desc){	unsigned int subsrc, submsk;	unsigned int offset = 9;	struct irq_desc *mydesc;	/* read the current pending interrupts, and the mask	 * for what it is available */	subsrc = __raw_readl(S3C2410_SUBSRCPND);	submsk = __raw_readl(S3C2410_INTSUBMSK);	subsrc &= ~submsk;	subsrc >>= offset;	subsrc &= 3;	if (subsrc != 0) {		if (subsrc & 1) {			mydesc = irq_desc + IRQ_TC;			desc_handle_irq(IRQ_TC, mydesc);		}		if (subsrc & 2) {			mydesc = irq_desc + IRQ_ADC;			desc_handle_irq(IRQ_ADC, mydesc);		}	}}static void s3c_irq_demux_uart(unsigned int start){	unsigned int subsrc, submsk;	unsigned int offset = start - IRQ_S3CUART_RX0;	struct irq_desc *desc;	/* read the current pending interrupts, and the mask	 * for what it is available */	subsrc = __raw_readl(S3C2410_SUBSRCPND);	submsk = __raw_readl(S3C2410_INTSUBMSK);	irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",		start, offset, subsrc, submsk);	subsrc &= ~submsk;	subsrc >>= offset;	subsrc &= 7;	if (subsrc != 0) {		desc = irq_desc + start;		if (subsrc & 1)			desc_handle_irq(start, desc);		desc++;		if (subsrc & 2)			desc_handle_irq(start+1, desc);		desc++;		if (subsrc & 4)			desc_handle_irq(start+2, desc);	}}/* uart demux entry points */static voids3c_irq_demux_uart0(unsigned int irq,		    struct irq_desc *desc){	irq = irq;	s3c_irq_demux_uart(IRQ_S3CUART_RX0);}static voids3c_irq_demux_uart1(unsigned int irq,		    struct irq_desc *desc){	irq = irq;	s3c_irq_demux_uart(IRQ_S3CUART_RX1);}static voids3c_irq_demux_uart2(unsigned int irq,		    struct irq_desc *desc){	irq = irq;	s3c_irq_demux_uart(IRQ_S3CUART_RX2);}static voids3c_irq_demux_extint8(unsigned int irq,		      struct irq_desc *desc){	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);	eintpnd &= ~eintmsk;	eintpnd &= ~0xff;	/* ignore lower irqs */	/* we may as well handle all the pending IRQs here */	while (eintpnd) {		irq = __ffs(eintpnd);		eintpnd &= ~(1<<irq);		irq += (IRQ_EINT4 - 4);		desc_handle_irq(irq, irq_desc + irq);	}}static voids3c_irq_demux_extint4t7(unsigned int irq,			struct irq_desc *desc){	unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);	unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);	eintpnd &= ~eintmsk;	eintpnd &= 0xff;	/* only lower irqs */	/* we may as well handle all the pending IRQs here */	while (eintpnd) {		irq = __ffs(eintpnd);		eintpnd &= ~(1<<irq);		irq += (IRQ_EINT4 - 4);		desc_handle_irq(irq, irq_desc + irq);	}}#ifdef CONFIG_PMstatic struct sleep_save irq_save[] = {	SAVE_ITEM(S3C2410_INTMSK),	SAVE_ITEM(S3C2410_INTSUBMSK),};/* the extint values move between the s3c2410/s3c2440 and the s3c2412 * so we use an array to hold them, and to calculate the address of * the register at run-time*/static unsigned long save_extint[3];static unsigned long save_eintflt[4];static unsigned long save_eintmask;int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state){	unsigned int i;	for (i = 0; i < ARRAY_SIZE(save_extint); i++)		save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)		save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));	s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));	save_eintmask = __raw_readl(S3C24XX_EINTMASK);	return 0;}int s3c24xx_irq_resume(struct sys_device *dev){	unsigned int i;	for (i = 0; i < ARRAY_SIZE(save_extint); i++)		__raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));	for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)		__raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));	s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));	__raw_writel(save_eintmask, S3C24XX_EINTMASK);	return 0;}#else#define s3c24xx_irq_suspend NULL#define s3c24xx_irq_resume  NULL#endif/* s3c24xx_init_irq * * Initialise S3C2410 IRQ system*/void __init s3c24xx_init_irq(void){	unsigned long pend;	unsigned long last;	int irqno;	int i;	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");	/* first, clear all interrupts pending... */	last = 0;	for (i = 0; i < 4; i++) {		pend = __raw_readl(S3C24XX_EINTPEND);		if (pend == 0 || pend == last)			break;		__raw_writel(pend, S3C24XX_EINTPEND);		printk("irq: clearing pending ext status %08x\n", (int)pend);		last = pend;	}	last = 0;	for (i = 0; i < 4; i++) {		pend = __raw_readl(S3C2410_INTPND);		if (pend == 0 || pend == last)			break;		__raw_writel(pend, S3C2410_SRCPND);		__raw_writel(pend, S3C2410_INTPND);		printk("irq: clearing pending status %08x\n", (int)pend);		last = pend;	}	last = 0;	for (i = 0; i < 4; i++) {		pend = __raw_readl(S3C2410_SUBSRCPND);		if (pend == 0 || pend == last)			break;		printk("irq: clearing subpending status %08x\n", (int)pend);		__raw_writel(pend, S3C2410_SUBSRCPND);		last = pend;	}	/* register the main interrupts */	irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");	for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {		/* set all the s3c2410 internal irqs */		switch (irqno) {			/* deal with the special IRQs (cascaded) */		case IRQ_EINT4t7:		case IRQ_EINT8t23:		case IRQ_UART0:		case IRQ_UART1:		case IRQ_UART2:		case IRQ_ADCPARENT:			set_irq_chip(irqno, &s3c_irq_level_chip);			set_irq_handler(irqno, handle_level_irq);			break;		case IRQ_RESERVED6:		case IRQ_RESERVED24:			/* no IRQ here */			break;		default:			//irqdbf("registering irq %d (s3c irq)\n", irqno);			set_irq_chip(irqno, &s3c_irq_chip);			set_irq_handler(irqno, handle_edge_irq);			set_irq_flags(irqno, IRQF_VALID);		}	}	/* setup the cascade irq handlers */	set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);	set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);	set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);	set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);	set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);	set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);	/* external interrupts */	for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {		irqdbf("registering irq %d (ext int)\n", irqno);		set_irq_chip(irqno, &s3c_irq_eint0t4);		set_irq_handler(irqno, handle_edge_irq);		set_irq_flags(irqno, IRQF_VALID);	}	for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {		irqdbf("registering irq %d (extended s3c irq)\n", irqno);		set_irq_chip(irqno, &s3c_irqext_chip);		set_irq_handler(irqno, handle_edge_irq);		set_irq_flags(irqno, IRQF_VALID);	}	/* register the uart interrupts */	irqdbf("s3c2410: registering external interrupts\n");	for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {		irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);		set_irq_chip(irqno, &s3c_irq_uart0);		set_irq_handler(irqno, handle_level_irq);		set_irq_flags(irqno, IRQF_VALID);	}	for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {		irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);		set_irq_chip(irqno, &s3c_irq_uart1);		set_irq_handler(irqno, handle_level_irq);		set_irq_flags(irqno, IRQF_VALID);	}	for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {		irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);		set_irq_chip(irqno, &s3c_irq_uart2);		set_irq_handler(irqno, handle_level_irq);		set_irq_flags(irqno, IRQF_VALID);	}	for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {		irqdbf("registering irq %d (s3c adc irq)\n", irqno);		set_irq_chip(irqno, &s3c_irq_adc);		set_irq_handler(irqno, handle_edge_irq);		set_irq_flags(irqno, IRQF_VALID);	}	irqdbf("s3c2410: registered interrupt handlers\n");}

⌨️ 快捷键说明

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