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

📄 irq.c

📁 microwindows移植到S3C44B0的源码
💻 C
字号:
/* * arch/armnommu/mach-netarm/irq.c: * * NET+ARM  IRQ mask, unmask & init routines. * * (C) 2001 IMMS gGmbH (http://www.imms.de) * author(s): Rolf Peukert (rolf.peukert@imms.de) * * partially based on work by Gordon McNutt and Joe deBlaquiere * * This program is free software; you can redistribute  it and/or modify it * under  the terms of  the GNU General  Public License as published by the * Free Software Foundation;  either version 2 of the  License, or (at your * option) any later version. * * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the  GNU General Public License along * with this program; if not, write  to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <linux/config.h>#include <asm/arch/irq.h>#include <asm/arch/netarm_registers.h>#ifdef CONFIG_SERIAL_NETARM/* Mask & Acknowledge function for serial channel 1, RX and TX interrupts */extern void nas_mask_ack_serial1_irq( unsigned int irq );/* dto. for serial channel 2, both defined in drivers/char/serial_netarm.c */extern void nas_mask_ack_serial2_irq( unsigned int irq );#else/* minimal Mask & Acknowledge functions */void nas_mask_ack_serial1_irq( unsigned int irq ){	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR);	volatile unsigned long int *stat_a =		(volatile unsigned long *)(NETARM_SER_MODULE_BASE +		NETARM_SER_CH1_STATUS_A);		if ((irq == IRQ_SER1_TX) || (irq == IRQ_SER1_RX))	{		*mask  	= (1 << irq);	/* set mask bit */		*stat_a	= 0xFFFF;	/* clear all IRQ pending bits */	}}void nas_mask_ack_serial2_irq( unsigned int irq ){	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR);	volatile unsigned long int *stat_a =		(volatile unsigned long *)(NETARM_SER_MODULE_BASE +		NETARM_SER_CH2_STATUS_A);	if ((irq == IRQ_SER2_TX) || (irq == IRQ_SER2_RX))	{		*mask  	= (1 << irq);	/* set mask bit */		*stat_a	= 0xFFFF;	/* clear all IRQ pending bits */	}}#endif /* if CONFIG_SERIAL_NETARM... *//* Generic Mask IRQ function */void netarm_mask_irq(unsigned int irq){	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;		if (32 > irq) *mask = ( 1 << irq );}/* Generic Unmask IRQ function */void netarm_unmask_irq(unsigned int irq){	volatile unsigned long int *set = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_SET) ;		if (32 > irq) *set = ( 1 << irq );}/* Dummy Mask&Ack function */void netarm_mask_ack_irq(unsigned int irq){	netarm_mask_irq(irq);        /* The NET+ARM doesn't implement a general IRQ status register	   like the DSC21 -> we need individual mask_ack_routines */}/* Mask & Acknowledge function for Timer 1 IRQ */void netarm_mask_ack_t1_irq(unsigned int irq){	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;	volatile unsigned long int *stat = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_TIMER1_STATUS) ;	if (irq == IRQ_TIMER1)	{		*mask = (1 << IRQ_TIMER1);	/* constant, should be calculated at compile time */		*stat = NETARM_GEN_TSTAT_INTPEN;/* this clears the IRQ pending bit */	}}/* Mask & Acknowledge function for Timer 2 IRQ */void netarm_mask_ack_t2_irq(unsigned int irq){	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;	volatile unsigned long int *stat = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_TIMER2_STATUS) ;	if (irq == IRQ_TIMER2)	{		*mask = (1 << IRQ_TIMER2);	/* = 0x00000100, bit 4 set */		*stat = NETARM_GEN_TSTAT_INTPEN;/* clear IRQ pending bit */	}}/* Mask & Acknowledge function for Port C Bit 0..3 IRQs */void netarm_mask_ack_portc_irq(unsigned int irq){	int 	irq_bit;	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;	volatile unsigned long int *portc = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_PORTC) ;	if (irq <= IRQ_PORTC3) /* Interrupts 0..3 correspond to Port C bits 0..3 */	{		irq_bit = 1 << irq;		*mask   = irq_bit;		/* set mask bit */		*portc  = *portc | irq_bit;	/* acknowledge IRQ */	}}/* Mask & Acknowledge function for DMA channel 1 IRQ */void netarm_mask_ack_dma1_irq(unsigned int irq){	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;	volatile unsigned long int *dmastata = 		(volatile unsigned long *)(NETARM_DMA_MODULE_BASE + 		NETARM_DMA1A_STATUS) ;	volatile unsigned long int *dmastatb = 		(volatile unsigned long *)(NETARM_DMA_MODULE_BASE + 		NETARM_DMA1B_STATUS) ;	volatile unsigned long int *dmastatc = 		(volatile unsigned long *)(NETARM_DMA_MODULE_BASE + 		NETARM_DMA1C_STATUS) ;	volatile unsigned long int *dmastatd = 		(volatile unsigned long *)(NETARM_DMA_MODULE_BASE + 		NETARM_DMA1D_STATUS) ;	if (IRQ_DMA01 == irq)	{		*mask   = (1 << IRQ_DMA01);	/* set mask bit */		/* A better irq routine should differentiate between the 16 possible		   IRQ sources. But for now we just acknowledge all IRQ sources */		*dmastata = NETARM_DMA_STAT_INTPEN_MASK;		*dmastatb = NETARM_DMA_STAT_INTPEN_MASK;		*dmastatc = NETARM_DMA_STAT_INTPEN_MASK;		*dmastatd = NETARM_DMA_STAT_INTPEN_MASK;	}}/* Mask & Acknowledge function for DMA channels 2..10 IRQs */void netarm_mask_ack_dmax_irq(unsigned int irq){	int	channel;	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;	volatile unsigned long int *dmastat;	/* Interrupts 30..22 correspond to DMA channels 2..10	   Note the "reverse" numbering scheme (HW Reference 4.4) */	if ((IRQ_DMA02 >= irq) && (irq >= IRQ_DMA10))	{		*mask   = (1 << irq);		/* set mask bit */		channel = 32 - irq;		/* DMA channel, 1..10 */		dmastat = (volatile unsigned long *)(NETARM_DMA_MODULE_BASE + 		           NETARM_DMA2_STATUS + ((channel - 2)* 0x20));		/* A better irq routine should differentiate between the four possible		   IRQ sources. But as a quick workaround, we acknowledge all sources */		*dmastat = NETARM_DMA_STAT_INTPEN_MASK;	}}/* setup IRQ descriptor array */void irq_init_irq(void){	int irq;	unsigned long flags;	volatile unsigned long int *mask = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_CLR) ;	volatile unsigned long int *set = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE_SET) ;	volatile unsigned long int *ie = 		(volatile unsigned long *)(NETARM_GEN_MODULE_BASE + 		NETARM_GEN_INTR_ENABLE) ;	for (irq = 0; irq < NR_IRQS; irq++)	{		irq_desc[irq].valid	= 1;		irq_desc[irq].probe_ok	= 1;		switch (irq)		{			case IRQ_PORTC0:			case IRQ_PORTC1:			case IRQ_PORTC2:			case IRQ_PORTC3:					irq_desc[irq].mask_ack = netarm_mask_ack_portc_irq;					break;			case IRQ_TIMER2:					irq_desc[irq].mask_ack = netarm_mask_ack_t2_irq;					break;			case IRQ_TIMER1:					irq_desc[irq].mask_ack = netarm_mask_ack_t1_irq;					break;			case IRQ_SER1_TX:			case IRQ_SER1_RX:					irq_desc[irq].mask_ack = nas_mask_ack_serial1_irq;					break;						case IRQ_SER2_TX:			case IRQ_SER2_RX:					irq_desc[irq].mask_ack = nas_mask_ack_serial2_irq;					break;						case IRQ_DMA10:			case IRQ_DMA09:			case IRQ_DMA08:			case IRQ_DMA07:			case IRQ_DMA06:			case IRQ_DMA05:			case IRQ_DMA04:			case IRQ_DMA03:					irq_desc[irq].mask_ack = netarm_mask_ack_dmax_irq;					break;#ifdef CONFIG_ETHER_NETARM			/* The IRQ routines in netarmeth.c do their own acknowledge,			   so don't clear the pending bits here */			case IRQ_DMA02:					irq_desc[irq].mask_ack = netarm_mask_irq;					break;			case IRQ_DMA01:					irq_desc[irq].mask_ack = netarm_mask_irq;					break;#else			/* Use our Mask-Ack functions, just for the case... */			case IRQ_DMA02:					irq_desc[irq].mask_ack = netarm_mask_ack_dmax_irq;					break;			case IRQ_DMA01:					irq_desc[irq].mask_ack = netarm_mask_ack_dma1_irq;					break;#endif /* CONFIG_ETHER_NETARM... */			default:					irq_desc[irq].mask_ack = netarm_mask_ack_irq;					break;		};		irq_desc[irq].mask	= netarm_mask_irq;		irq_desc[irq].unmask	= netarm_unmask_irq;		irq_desc[irq].action	= NULL;	}	/* clear all status * disable all */	save_flags_cli (flags);	*mask = 0xffffffff;	*set = 0x5aa55aa5;	*set = 0x00000000;	if (*ie != 0x5aa55aa5)		 _netarm_led_FAIL();	*mask = 0xffffffff;		/* clear all interrupt enables */	restore_flags (flags);}

⌨️ 快捷键说明

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