aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa/irq.c
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/mach-pxa/irq.c
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/mach-pxa/irq.c')
-rw-r--r--arch/arm/mach-pxa/irq.c117
1 files changed, 33 insertions, 84 deletions
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