aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authoreric miao <eric.miao@marvell.com>2008-03-04 00:53:05 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-04-19 06:29:04 -0400
commitf6fb7af4768bc1ddc2349f6eaefedd746c8e4913 (patch)
treeade9682bb833f1b576609b4344b4e55ce20a8500 /arch/arm
parente3630db1fa7677b350fd5a1ac5498cc48448ae28 (diff)
[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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-pxa/generic.h3
-rw-r--r--arch/arm/mach-pxa/irq.c117
-rw-r--r--arch/arm/mach-pxa/pxa25x.c2
-rw-r--r--arch/arm/mach-pxa/pxa27x.c7
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c7
5 files changed, 37 insertions, 99 deletions
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index cbe6693b1b6f..0e3e058296fa 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -12,8 +12,7 @@
12struct sys_timer; 12struct sys_timer;
13 13
14extern struct sys_timer pxa_timer; 14extern struct sys_timer pxa_timer;
15extern void __init pxa_init_irq_low(void); 15extern void __init pxa_init_irq(int irq_nr);
16extern void __init pxa_init_irq_high(void);
17extern void __init pxa_init_irq_gpio(int gpio_nr); 16extern void __init pxa_init_irq_gpio(int gpio_nr);
18extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); 17extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
19extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int)); 18extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int));
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index da3a44a4249a..cccc3ed3c679 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -24,92 +24,57 @@
24 24
25#include "generic.h" 25#include "generic.h"
26 26
27#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
28#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
29#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
27 30
28/* 31/*
29 * This is for peripheral IRQs internal to the PXA chip. 32 * This is for peripheral IRQs internal to the PXA chip.
30 */ 33 */
31 34
32static void pxa_mask_low_irq(unsigned int irq) 35static int pxa_internal_irq_nr;
36
37static void pxa_mask_irq(unsigned int irq)
33{ 38{
34 ICMR &= ~(1 << irq); 39 _ICMR(irq) &= ~(1 << IRQ_BIT(irq));
35} 40}
36 41
37static void pxa_unmask_low_irq(unsigned int irq) 42static void pxa_unmask_irq(unsigned int irq)
38{ 43{
39 ICMR |= (1 << irq); 44 _ICMR(irq) |= 1 << IRQ_BIT(irq);
40} 45}
41 46
42static struct irq_chip pxa_internal_chip_low = { 47static struct irq_chip pxa_internal_irq_chip = {
43 .name = "SC", 48 .name = "SC",
44 .ack = pxa_mask_low_irq, 49 .ack = pxa_mask_irq,
45 .mask = pxa_mask_low_irq, 50 .mask = pxa_mask_irq,
46 .unmask = pxa_unmask_low_irq, 51 .unmask = pxa_unmask_irq,
47}; 52};
48 53
49void __init pxa_init_irq_low(void) 54void __init pxa_init_irq(int irq_nr)
50{ 55{
51 int irq; 56 int irq;
52 57
53 /* disable all IRQs */ 58 pxa_internal_irq_nr = irq_nr;
54 ICMR = 0;
55 59
56 /* all IRQs are IRQ, not FIQ */ 60 for (irq = 0; irq < irq_nr; irq += 32) {
57 ICLR = 0; 61 _ICMR(irq) = 0; /* disable all IRQs */
62 _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */
63 }
58 64
59 /* only unmasked interrupts kick us out of idle */ 65 /* only unmasked interrupts kick us out of idle */
60 ICCR = 1; 66 ICCR = 1;
61 67
62 for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) { 68 for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
63 set_irq_chip(irq, &pxa_internal_chip_low); 69 set_irq_chip(irq, &pxa_internal_irq_chip);
64 set_irq_handler(irq, handle_level_irq);
65 set_irq_flags(irq, IRQF_VALID);
66 }
67}
68
69#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
70
71/*
72 * This is for the second set of internal IRQs as found on the PXA27x.
73 */
74
75static void pxa_mask_high_irq(unsigned int irq)
76{
77 ICMR2 &= ~(1 << (irq - 32));
78}
79
80static void pxa_unmask_high_irq(unsigned int irq)
81{
82 ICMR2 |= (1 << (irq - 32));
83}
84
85static struct irq_chip pxa_internal_chip_high = {
86 .name = "SC-hi",
87 .ack = pxa_mask_high_irq,
88 .mask = pxa_mask_high_irq,
89 .unmask = pxa_unmask_high_irq,
90};
91
92void __init pxa_init_irq_high(void)
93{
94 int irq;
95
96 ICMR2 = 0;
97 ICLR2 = 0;
98
99 for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
100 set_irq_chip(irq, &pxa_internal_chip_high);
101 set_irq_handler(irq, handle_level_irq); 70 set_irq_handler(irq, handle_level_irq);
102 set_irq_flags(irq, IRQF_VALID); 71 set_irq_flags(irq, IRQF_VALID);
103 } 72 }
104} 73}
105#endif
106 74
107void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) 75void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
108{ 76{
109 pxa_internal_chip_low.set_wake = set_wake; 77 pxa_internal_irq_chip.set_wake = set_wake;
110#ifdef CONFIG_PXA27x
111 pxa_internal_chip_high.set_wake = set_wake;
112#endif
113 pxa_init_gpio_set_wake(set_wake); 78 pxa_init_gpio_set_wake(set_wake);
114} 79}
115 80
@@ -118,19 +83,11 @@ static unsigned long saved_icmr[2];
118 83
119static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) 84static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
120{ 85{
121 switch (dev->id) { 86 int i, irq = PXA_IRQ(0);
122 case 0: 87
123 saved_icmr[0] = ICMR; 88 for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
124 ICMR = 0; 89 saved_icmr[i] = _ICMR(irq);
125 break; 90 _ICMR(irq) = 0;
126#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
127 case 1:
128 saved_icmr[1] = ICMR2;
129 ICMR2 = 0;
130 break;
131#endif
132 default:
133 return -EINVAL;
134 } 91 }
135 92
136 return 0; 93 return 0;
@@ -138,22 +95,14 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
138 95
139static int pxa_irq_resume(struct sys_device *dev) 96static int pxa_irq_resume(struct sys_device *dev)
140{ 97{
141 switch (dev->id) { 98 int i, irq = PXA_IRQ(0);
142 case 0: 99
143 ICMR = saved_icmr[0]; 100 for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
144 ICLR = 0; 101 _ICMR(irq) = saved_icmr[i];
145 ICCR = 1; 102 _ICLR(irq) = 0;
146 break;
147#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
148 case 1:
149 ICMR2 = saved_icmr[1];
150 ICLR2 = 0;
151 break;
152#endif
153 default:
154 return -EINVAL;
155 } 103 }
156 104
105 ICCR = 1;
157 return 0; 106 return 0;
158} 107}
159#else 108#else
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index f3799289b8f0..bb0bf51f5039 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -267,7 +267,7 @@ set_pwer:
267 267
268void __init pxa25x_init_irq(void) 268void __init pxa25x_init_irq(void)
269{ 269{
270 pxa_init_irq_low(); 270 pxa_init_irq(32);
271 pxa_init_irq_gpio(85); 271 pxa_init_irq_gpio(85);
272 pxa_init_irq_set_wake(pxa25x_set_wake); 272 pxa_init_irq_set_wake(pxa25x_set_wake);
273} 273}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index c186bd1f8673..54d8448cad7b 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -340,8 +340,7 @@ set_pwer:
340 340
341void __init pxa27x_init_irq(void) 341void __init pxa27x_init_irq(void)
342{ 342{
343 pxa_init_irq_low(); 343 pxa_init_irq(34);
344 pxa_init_irq_high();
345 pxa_init_irq_gpio(128); 344 pxa_init_irq_gpio(128);
346 pxa_init_irq_set_wake(pxa27x_set_wake); 345 pxa_init_irq_set_wake(pxa27x_set_wake);
347} 346}
@@ -389,10 +388,6 @@ static struct platform_device *devices[] __initdata = {
389 388
390static struct sys_device pxa27x_sysdev[] = { 389static struct sys_device pxa27x_sysdev[] = {
391 { 390 {
392 .id = 0,
393 .cls = &pxa_irq_sysclass,
394 }, {
395 .id = 1,
396 .cls = &pxa_irq_sysclass, 391 .cls = &pxa_irq_sysclass,
397 }, { 392 }, {
398 .cls = &pxa_gpio_sysclass, 393 .cls = &pxa_gpio_sysclass,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 93f3236b4100..8f8179b2fc38 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -513,8 +513,7 @@ void __init pxa3xx_init_irq(void)
513 value |= (1 << 6); 513 value |= (1 << 6);
514 __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value)); 514 __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
515 515
516 pxa_init_irq_low(); 516 pxa_init_irq(56);
517 pxa_init_irq_high();
518 pxa_init_irq_gpio(128); 517 pxa_init_irq_gpio(128);
519 pxa3xx_init_irq_pm(); 518 pxa3xx_init_irq_pm();
520} 519}
@@ -538,10 +537,6 @@ static struct platform_device *devices[] __initdata = {
538 537
539static struct sys_device pxa3xx_sysdev[] = { 538static struct sys_device pxa3xx_sysdev[] = {
540 { 539 {
541 .id = 0,
542 .cls = &pxa_irq_sysclass,
543 }, {
544 .id = 1,
545 .cls = &pxa_irq_sysclass, 540 .cls = &pxa_irq_sysclass,
546 }, { 541 }, {
547 .cls = &pxa_gpio_sysclass, 542 .cls = &pxa_gpio_sysclass,