[ARM] pxa: integrate low IRQ chip (ICIP) and high IRQ chip (ICIP2) into one
This makes the code better organized and simplified a bit.  The change
will lose a bit of performance when performing IRQ ack/mask/unmask,but
that's not too much after checking the result binary.
This patch also removes the ugly #ifdef CONFIG_PXA27x .. #endif by
carefully not to access those pxa{27x,3xx} specific registers, this
is done by keeping an internal IRQ number variable.  The pxa-regs.h
is also modified so registers for IRQ > PXA_IRQ(31) are made public
even if CONFIG_PXA{27x,3xx} isn't defined (for pxa25x's sake)
The incorrect assumption in the original code that internal irq starts
from 0 is also corrected by comparing with PXA_IRQ(0).
"struct sys_device" for the IRQ are reduced into one single device on
pxa{27x,3xx}.
Signed-off-by: eric miao <eric.miao@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
			
			
This commit is contained in:
		
							parent
							
								
									e3630db1fa
								
							
						
					
					
						commit
						f6fb7af476
					
				| @ -12,8 +12,7 @@ | ||||
| struct sys_timer; | ||||
| 
 | ||||
| extern struct sys_timer pxa_timer; | ||||
| extern void __init pxa_init_irq_low(void); | ||||
| extern void __init pxa_init_irq_high(void); | ||||
| extern void __init pxa_init_irq(int irq_nr); | ||||
| extern void __init pxa_init_irq_gpio(int gpio_nr); | ||||
| extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); | ||||
| extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int)); | ||||
|  | ||||
| @ -24,92 +24,57 @@ | ||||
| 
 | ||||
| #include "generic.h" | ||||
| 
 | ||||
| #define IRQ_BIT(n)	(((n) - PXA_IRQ(0)) & 0x1f) | ||||
| #define _ICMR(n)	(*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR)) | ||||
| #define _ICLR(n)	(*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR)) | ||||
| 
 | ||||
| /*
 | ||||
|  * This is for peripheral IRQs internal to the PXA chip. | ||||
|  */ | ||||
| 
 | ||||
| static void pxa_mask_low_irq(unsigned int irq) | ||||
| static int pxa_internal_irq_nr; | ||||
| 
 | ||||
| static void pxa_mask_irq(unsigned int irq) | ||||
| { | ||||
| 	ICMR &= ~(1 << irq); | ||||
| 	_ICMR(irq) &= ~(1 << IRQ_BIT(irq)); | ||||
| } | ||||
| 
 | ||||
| static void pxa_unmask_low_irq(unsigned int irq) | ||||
| static void pxa_unmask_irq(unsigned int irq) | ||||
| { | ||||
| 	ICMR |= (1 << irq); | ||||
| 	_ICMR(irq) |= 1 << IRQ_BIT(irq); | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip pxa_internal_chip_low = { | ||||
| static struct irq_chip pxa_internal_irq_chip = { | ||||
| 	.name		= "SC", | ||||
| 	.ack		= pxa_mask_low_irq, | ||||
| 	.mask		= pxa_mask_low_irq, | ||||
| 	.unmask		= pxa_unmask_low_irq, | ||||
| 	.ack		= pxa_mask_irq, | ||||
| 	.mask		= pxa_mask_irq, | ||||
| 	.unmask		= pxa_unmask_irq, | ||||
| }; | ||||
| 
 | ||||
| void __init pxa_init_irq_low(void) | ||||
| void __init pxa_init_irq(int irq_nr) | ||||
| { | ||||
| 	int irq; | ||||
| 
 | ||||
| 	/* disable all IRQs */ | ||||
| 	ICMR = 0; | ||||
| 	pxa_internal_irq_nr = irq_nr; | ||||
| 
 | ||||
| 	/* all IRQs are IRQ, not FIQ */ | ||||
| 	ICLR = 0; | ||||
| 	for (irq = 0; irq < irq_nr; irq += 32) { | ||||
| 		_ICMR(irq) = 0;	/* disable all IRQs */ | ||||
| 		_ICLR(irq) = 0;	/* all IRQs are IRQ, not FIQ */ | ||||
| 	} | ||||
| 
 | ||||
| 	/* only unmasked interrupts kick us out of idle */ | ||||
| 	ICCR = 1; | ||||
| 
 | ||||
| 	for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) { | ||||
| 		set_irq_chip(irq, &pxa_internal_chip_low); | ||||
| 	for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) { | ||||
| 		set_irq_chip(irq, &pxa_internal_irq_chip); | ||||
| 		set_irq_handler(irq, handle_level_irq); | ||||
| 		set_irq_flags(irq, IRQF_VALID); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||||
| 
 | ||||
| /*
 | ||||
|  * This is for the second set of internal IRQs as found on the PXA27x. | ||||
|  */ | ||||
| 
 | ||||
| static void pxa_mask_high_irq(unsigned int irq) | ||||
| { | ||||
| 	ICMR2 &= ~(1 << (irq - 32)); | ||||
| } | ||||
| 
 | ||||
| static void pxa_unmask_high_irq(unsigned int irq) | ||||
| { | ||||
| 	ICMR2 |= (1 << (irq - 32)); | ||||
| } | ||||
| 
 | ||||
| static struct irq_chip pxa_internal_chip_high = { | ||||
| 	.name		= "SC-hi", | ||||
| 	.ack		= pxa_mask_high_irq, | ||||
| 	.mask		= pxa_mask_high_irq, | ||||
| 	.unmask		= pxa_unmask_high_irq, | ||||
| }; | ||||
| 
 | ||||
| void __init pxa_init_irq_high(void) | ||||
| { | ||||
| 	int irq; | ||||
| 
 | ||||
| 	ICMR2 = 0; | ||||
| 	ICLR2 = 0; | ||||
| 
 | ||||
| 	for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) { | ||||
| 		set_irq_chip(irq, &pxa_internal_chip_high); | ||||
| 		set_irq_handler(irq, handle_level_irq); | ||||
| 		set_irq_flags(irq, IRQF_VALID); | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) | ||||
| { | ||||
| 	pxa_internal_chip_low.set_wake = set_wake; | ||||
| #ifdef CONFIG_PXA27x | ||||
| 	pxa_internal_chip_high.set_wake = set_wake; | ||||
| #endif | ||||
| 	pxa_internal_irq_chip.set_wake = set_wake; | ||||
| 	pxa_init_gpio_set_wake(set_wake); | ||||
| } | ||||
| 
 | ||||
| @ -118,19 +83,11 @@ static unsigned long saved_icmr[2]; | ||||
| 
 | ||||
| static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | ||||
| { | ||||
| 	switch (dev->id) { | ||||
| 	case 0: | ||||
| 		saved_icmr[0] = ICMR; | ||||
| 		ICMR = 0; | ||||
| 		break; | ||||
| #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||||
| 	case 1: | ||||
| 		saved_icmr[1] = ICMR2; | ||||
| 		ICMR2 = 0; | ||||
| 		break; | ||||
| #endif | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	int i, irq = PXA_IRQ(0); | ||||
| 
 | ||||
| 	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { | ||||
| 		saved_icmr[i] = _ICMR(irq); | ||||
| 		_ICMR(irq) = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| @ -138,22 +95,14 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | ||||
| 
 | ||||
| static int pxa_irq_resume(struct sys_device *dev) | ||||
| { | ||||
| 	switch (dev->id) { | ||||
| 	case 0: | ||||
| 		ICMR = saved_icmr[0]; | ||||
| 		ICLR = 0; | ||||
| 		ICCR = 1; | ||||
| 		break; | ||||
| #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) | ||||
| 	case 1: | ||||
| 		ICMR2 = saved_icmr[1]; | ||||
| 		ICLR2 = 0; | ||||
| 		break; | ||||
| #endif | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	int i, irq = PXA_IRQ(0); | ||||
| 
 | ||||
| 	for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) { | ||||
| 		_ICMR(irq) = saved_icmr[i]; | ||||
| 		_ICLR(irq) = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	ICCR = 1; | ||||
| 	return 0; | ||||
| } | ||||
| #else | ||||
|  | ||||
| @ -267,7 +267,7 @@ set_pwer: | ||||
| 
 | ||||
| void __init pxa25x_init_irq(void) | ||||
| { | ||||
| 	pxa_init_irq_low(); | ||||
| 	pxa_init_irq(32); | ||||
| 	pxa_init_irq_gpio(85); | ||||
| 	pxa_init_irq_set_wake(pxa25x_set_wake); | ||||
| } | ||||
|  | ||||
| @ -340,8 +340,7 @@ set_pwer: | ||||
| 
 | ||||
| void __init pxa27x_init_irq(void) | ||||
| { | ||||
| 	pxa_init_irq_low(); | ||||
| 	pxa_init_irq_high(); | ||||
| 	pxa_init_irq(34); | ||||
| 	pxa_init_irq_gpio(128); | ||||
| 	pxa_init_irq_set_wake(pxa27x_set_wake); | ||||
| } | ||||
| @ -389,10 +388,6 @@ static struct platform_device *devices[] __initdata = { | ||||
| 
 | ||||
| static struct sys_device pxa27x_sysdev[] = { | ||||
| 	{ | ||||
| 		.id	= 0, | ||||
| 		.cls	= &pxa_irq_sysclass, | ||||
| 	}, { | ||||
| 		.id	= 1, | ||||
| 		.cls	= &pxa_irq_sysclass, | ||||
| 	}, { | ||||
| 		.cls	= &pxa_gpio_sysclass, | ||||
|  | ||||
| @ -513,8 +513,7 @@ void __init pxa3xx_init_irq(void) | ||||
| 	value |= (1 << 6); | ||||
| 	__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value)); | ||||
| 
 | ||||
| 	pxa_init_irq_low(); | ||||
| 	pxa_init_irq_high(); | ||||
| 	pxa_init_irq(56); | ||||
| 	pxa_init_irq_gpio(128); | ||||
| 	pxa3xx_init_irq_pm(); | ||||
| } | ||||
| @ -538,10 +537,6 @@ static struct platform_device *devices[] __initdata = { | ||||
| 
 | ||||
| static struct sys_device pxa3xx_sysdev[] = { | ||||
| 	{ | ||||
| 		.id	= 0, | ||||
| 		.cls	= &pxa_irq_sysclass, | ||||
| 	}, { | ||||
| 		.id	= 1, | ||||
| 		.cls	= &pxa_irq_sysclass, | ||||
| 	}, { | ||||
| 		.cls	= &pxa_gpio_sysclass, | ||||
|  | ||||
| @ -1129,6 +1129,11 @@ | ||||
| #define ICPR		__REG(0x40D00010)  /* Interrupt Controller Pending Register */ | ||||
| #define ICCR		__REG(0x40D00014)  /* Interrupt Controller Control Register */ | ||||
| 
 | ||||
| #define ICIP2		__REG(0x40D0009C)  /* Interrupt Controller IRQ Pending Register 2 */ | ||||
| #define ICMR2		__REG(0x40D000A0)  /* Interrupt Controller Mask Register 2 */ | ||||
| #define ICLR2		__REG(0x40D000A4)  /* Interrupt Controller Level Register 2 */ | ||||
| #define ICFP2		__REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */ | ||||
| #define ICPR2		__REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * General Purpose I/O | ||||
| @ -1200,12 +1205,6 @@ | ||||
| 
 | ||||
| /* Interrupt Controller */ | ||||
| 
 | ||||
| #define ICIP2		__REG(0x40D0009C)  /* Interrupt Controller IRQ Pending Register 2 */ | ||||
| #define ICMR2		__REG(0x40D000A0)  /* Interrupt Controller Mask Register 2 */ | ||||
| #define ICLR2		__REG(0x40D000A4)  /* Interrupt Controller Level Register 2 */ | ||||
| #define ICFP2		__REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */ | ||||
| #define ICPR2		__REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */ | ||||
| 
 | ||||
| #define _GPLR(x)	__REG2(0x40E00000, ((x) & 0x60) >> 3) | ||||
| #define _GPDR(x)	__REG2(0x40E0000C, ((x) & 0x60) >> 3) | ||||
| #define _GPSR(x)	__REG2(0x40E00018, ((x) & 0x60) >> 3) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user