diff options
author | eric miao <eric.miao@marvell.com> | 2008-03-04 00:53:05 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-04-19 06:29:04 -0400 |
commit | f6fb7af4768bc1ddc2349f6eaefedd746c8e4913 (patch) | |
tree | ade9682bb833f1b576609b4344b4e55ce20a8500 /arch/arm/mach-pxa | |
parent | e3630db1fa7677b350fd5a1ac5498cc48448ae28 (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/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/generic.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-pxa/irq.c | 117 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa27x.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-pxa/pxa3xx.c | 7 |
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 @@ | |||
12 | struct sys_timer; | 12 | struct sys_timer; |
13 | 13 | ||
14 | extern struct sys_timer pxa_timer; | 14 | extern struct sys_timer pxa_timer; |
15 | extern void __init pxa_init_irq_low(void); | 15 | extern void __init pxa_init_irq(int irq_nr); |
16 | extern void __init pxa_init_irq_high(void); | ||
17 | extern void __init pxa_init_irq_gpio(int gpio_nr); | 16 | extern void __init pxa_init_irq_gpio(int gpio_nr); |
18 | extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); | 17 | extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); |
19 | extern void __init pxa_init_gpio_set_wake(int (*set_wake)(unsigned int, unsigned int)); | 18 | extern 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 | ||
32 | static void pxa_mask_low_irq(unsigned int irq) | 35 | static int pxa_internal_irq_nr; |
36 | |||
37 | static void pxa_mask_irq(unsigned int irq) | ||
33 | { | 38 | { |
34 | ICMR &= ~(1 << irq); | 39 | _ICMR(irq) &= ~(1 << IRQ_BIT(irq)); |
35 | } | 40 | } |
36 | 41 | ||
37 | static void pxa_unmask_low_irq(unsigned int irq) | 42 | static void pxa_unmask_irq(unsigned int irq) |
38 | { | 43 | { |
39 | ICMR |= (1 << irq); | 44 | _ICMR(irq) |= 1 << IRQ_BIT(irq); |
40 | } | 45 | } |
41 | 46 | ||
42 | static struct irq_chip pxa_internal_chip_low = { | 47 | static 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 | ||
49 | void __init pxa_init_irq_low(void) | 54 | void __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 | |||
75 | static void pxa_mask_high_irq(unsigned int irq) | ||
76 | { | ||
77 | ICMR2 &= ~(1 << (irq - 32)); | ||
78 | } | ||
79 | |||
80 | static void pxa_unmask_high_irq(unsigned int irq) | ||
81 | { | ||
82 | ICMR2 |= (1 << (irq - 32)); | ||
83 | } | ||
84 | |||
85 | static 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 | |||
92 | void __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 | ||
107 | void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) | 75 | void __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 | ||
119 | static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) | 84 | static 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 | ||
139 | static int pxa_irq_resume(struct sys_device *dev) | 96 | static 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 | ||
268 | void __init pxa25x_init_irq(void) | 268 | void __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 | ||
341 | void __init pxa27x_init_irq(void) | 341 | void __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 | ||
390 | static struct sys_device pxa27x_sysdev[] = { | 389 | static 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 | ||
539 | static struct sys_device pxa3xx_sysdev[] = { | 538 | static 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, |