diff options
Diffstat (limited to 'arch/arm/mach-sa1100/irq.c')
-rw-r--r-- | arch/arm/mach-sa1100/irq.c | 229 |
1 files changed, 130 insertions, 99 deletions
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index 2124f1fc2fbe..63e2901db416 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c | |||
@@ -14,17 +14,73 @@ | |||
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/irqdomain.h> | ||
17 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
18 | #include <linux/syscore_ops.h> | 19 | #include <linux/syscore_ops.h> |
19 | 20 | ||
20 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
21 | #include <mach/irqs.h> | 22 | #include <mach/irqs.h> |
22 | #include <asm/mach/irq.h> | 23 | #include <asm/mach/irq.h> |
24 | #include <asm/exception.h> | ||
23 | 25 | ||
24 | #include "generic.h" | 26 | #include "generic.h" |
25 | 27 | ||
26 | 28 | ||
27 | /* | 29 | /* |
30 | * We don't need to ACK IRQs on the SA1100 unless they're GPIOs | ||
31 | * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm. | ||
32 | */ | ||
33 | static void sa1100_mask_irq(struct irq_data *d) | ||
34 | { | ||
35 | ICMR &= ~BIT(d->hwirq); | ||
36 | } | ||
37 | |||
38 | static void sa1100_unmask_irq(struct irq_data *d) | ||
39 | { | ||
40 | ICMR |= BIT(d->hwirq); | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * Apart form GPIOs, only the RTC alarm can be a wakeup event. | ||
45 | */ | ||
46 | static int sa1100_set_wake(struct irq_data *d, unsigned int on) | ||
47 | { | ||
48 | if (BIT(d->hwirq) == IC_RTCAlrm) { | ||
49 | if (on) | ||
50 | PWER |= PWER_RTC; | ||
51 | else | ||
52 | PWER &= ~PWER_RTC; | ||
53 | return 0; | ||
54 | } | ||
55 | return -EINVAL; | ||
56 | } | ||
57 | |||
58 | static struct irq_chip sa1100_normal_chip = { | ||
59 | .name = "SC", | ||
60 | .irq_ack = sa1100_mask_irq, | ||
61 | .irq_mask = sa1100_mask_irq, | ||
62 | .irq_unmask = sa1100_unmask_irq, | ||
63 | .irq_set_wake = sa1100_set_wake, | ||
64 | }; | ||
65 | |||
66 | static int sa1100_normal_irqdomain_map(struct irq_domain *d, | ||
67 | unsigned int irq, irq_hw_number_t hwirq) | ||
68 | { | ||
69 | irq_set_chip_and_handler(irq, &sa1100_normal_chip, | ||
70 | handle_level_irq); | ||
71 | set_irq_flags(irq, IRQF_VALID); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static struct irq_domain_ops sa1100_normal_irqdomain_ops = { | ||
77 | .map = sa1100_normal_irqdomain_map, | ||
78 | .xlate = irq_domain_xlate_onetwocell, | ||
79 | }; | ||
80 | |||
81 | static struct irq_domain *sa1100_normal_irqdomain; | ||
82 | |||
83 | /* | ||
28 | * SA1100 GPIO edge detection for IRQs: | 84 | * SA1100 GPIO edge detection for IRQs: |
29 | * IRQs are generated on Falling-Edge, Rising-Edge, or both. | 85 | * IRQs are generated on Falling-Edge, Rising-Edge, or both. |
30 | * Use this instead of directly setting GRER/GFER. | 86 | * Use this instead of directly setting GRER/GFER. |
@@ -33,20 +89,11 @@ static int GPIO_IRQ_rising_edge; | |||
33 | static int GPIO_IRQ_falling_edge; | 89 | static int GPIO_IRQ_falling_edge; |
34 | static int GPIO_IRQ_mask = (1 << 11) - 1; | 90 | static int GPIO_IRQ_mask = (1 << 11) - 1; |
35 | 91 | ||
36 | /* | ||
37 | * To get the GPIO number from an IRQ number | ||
38 | */ | ||
39 | #define GPIO_11_27_IRQ(i) ((i) - 21) | ||
40 | #define GPIO11_27_MASK(irq) (1 << GPIO_11_27_IRQ(irq)) | ||
41 | |||
42 | static int sa1100_gpio_type(struct irq_data *d, unsigned int type) | 92 | static int sa1100_gpio_type(struct irq_data *d, unsigned int type) |
43 | { | 93 | { |
44 | unsigned int mask; | 94 | unsigned int mask; |
45 | 95 | ||
46 | if (d->irq <= 10) | 96 | mask = BIT(d->hwirq); |
47 | mask = 1 << d->irq; | ||
48 | else | ||
49 | mask = GPIO11_27_MASK(d->irq); | ||
50 | 97 | ||
51 | if (type == IRQ_TYPE_PROBE) { | 98 | if (type == IRQ_TYPE_PROBE) { |
52 | if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) | 99 | if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) |
@@ -70,41 +117,51 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type) | |||
70 | } | 117 | } |
71 | 118 | ||
72 | /* | 119 | /* |
73 | * GPIO IRQs must be acknowledged. This is for IRQs from 0 to 10. | 120 | * GPIO IRQs must be acknowledged. |
74 | */ | 121 | */ |
75 | static void sa1100_low_gpio_ack(struct irq_data *d) | 122 | static void sa1100_gpio_ack(struct irq_data *d) |
76 | { | ||
77 | GEDR = (1 << d->irq); | ||
78 | } | ||
79 | |||
80 | static void sa1100_low_gpio_mask(struct irq_data *d) | ||
81 | { | ||
82 | ICMR &= ~(1 << d->irq); | ||
83 | } | ||
84 | |||
85 | static void sa1100_low_gpio_unmask(struct irq_data *d) | ||
86 | { | 123 | { |
87 | ICMR |= 1 << d->irq; | 124 | GEDR = BIT(d->hwirq); |
88 | } | 125 | } |
89 | 126 | ||
90 | static int sa1100_low_gpio_wake(struct irq_data *d, unsigned int on) | 127 | static int sa1100_gpio_wake(struct irq_data *d, unsigned int on) |
91 | { | 128 | { |
92 | if (on) | 129 | if (on) |
93 | PWER |= 1 << d->irq; | 130 | PWER |= BIT(d->hwirq); |
94 | else | 131 | else |
95 | PWER &= ~(1 << d->irq); | 132 | PWER &= ~BIT(d->hwirq); |
96 | return 0; | 133 | return 0; |
97 | } | 134 | } |
98 | 135 | ||
136 | /* | ||
137 | * This is for IRQs from 0 to 10. | ||
138 | */ | ||
99 | static struct irq_chip sa1100_low_gpio_chip = { | 139 | static struct irq_chip sa1100_low_gpio_chip = { |
100 | .name = "GPIO-l", | 140 | .name = "GPIO-l", |
101 | .irq_ack = sa1100_low_gpio_ack, | 141 | .irq_ack = sa1100_gpio_ack, |
102 | .irq_mask = sa1100_low_gpio_mask, | 142 | .irq_mask = sa1100_mask_irq, |
103 | .irq_unmask = sa1100_low_gpio_unmask, | 143 | .irq_unmask = sa1100_unmask_irq, |
104 | .irq_set_type = sa1100_gpio_type, | 144 | .irq_set_type = sa1100_gpio_type, |
105 | .irq_set_wake = sa1100_low_gpio_wake, | 145 | .irq_set_wake = sa1100_gpio_wake, |
146 | }; | ||
147 | |||
148 | static int sa1100_low_gpio_irqdomain_map(struct irq_domain *d, | ||
149 | unsigned int irq, irq_hw_number_t hwirq) | ||
150 | { | ||
151 | irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip, | ||
152 | handle_edge_irq); | ||
153 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static struct irq_domain_ops sa1100_low_gpio_irqdomain_ops = { | ||
159 | .map = sa1100_low_gpio_irqdomain_map, | ||
160 | .xlate = irq_domain_xlate_onetwocell, | ||
106 | }; | 161 | }; |
107 | 162 | ||
163 | static struct irq_domain *sa1100_low_gpio_irqdomain; | ||
164 | |||
108 | /* | 165 | /* |
109 | * IRQ11 (GPIO11 through 27) handler. We enter here with the | 166 | * IRQ11 (GPIO11 through 27) handler. We enter here with the |
110 | * irq_controller_lock held, and IRQs disabled. Decode the IRQ | 167 | * irq_controller_lock held, and IRQs disabled. Decode the IRQ |
@@ -141,16 +198,9 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc) | |||
141 | * In addition, the IRQs are all collected up into one bit in the | 198 | * In addition, the IRQs are all collected up into one bit in the |
142 | * interrupt controller registers. | 199 | * interrupt controller registers. |
143 | */ | 200 | */ |
144 | static void sa1100_high_gpio_ack(struct irq_data *d) | ||
145 | { | ||
146 | unsigned int mask = GPIO11_27_MASK(d->irq); | ||
147 | |||
148 | GEDR = mask; | ||
149 | } | ||
150 | |||
151 | static void sa1100_high_gpio_mask(struct irq_data *d) | 201 | static void sa1100_high_gpio_mask(struct irq_data *d) |
152 | { | 202 | { |
153 | unsigned int mask = GPIO11_27_MASK(d->irq); | 203 | unsigned int mask = BIT(d->hwirq); |
154 | 204 | ||
155 | GPIO_IRQ_mask &= ~mask; | 205 | GPIO_IRQ_mask &= ~mask; |
156 | 206 | ||
@@ -160,7 +210,7 @@ static void sa1100_high_gpio_mask(struct irq_data *d) | |||
160 | 210 | ||
161 | static void sa1100_high_gpio_unmask(struct irq_data *d) | 211 | static void sa1100_high_gpio_unmask(struct irq_data *d) |
162 | { | 212 | { |
163 | unsigned int mask = GPIO11_27_MASK(d->irq); | 213 | unsigned int mask = BIT(d->hwirq); |
164 | 214 | ||
165 | GPIO_IRQ_mask |= mask; | 215 | GPIO_IRQ_mask |= mask; |
166 | 216 | ||
@@ -168,61 +218,32 @@ static void sa1100_high_gpio_unmask(struct irq_data *d) | |||
168 | GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; | 218 | GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; |
169 | } | 219 | } |
170 | 220 | ||
171 | static int sa1100_high_gpio_wake(struct irq_data *d, unsigned int on) | ||
172 | { | ||
173 | if (on) | ||
174 | PWER |= GPIO11_27_MASK(d->irq); | ||
175 | else | ||
176 | PWER &= ~GPIO11_27_MASK(d->irq); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static struct irq_chip sa1100_high_gpio_chip = { | 221 | static struct irq_chip sa1100_high_gpio_chip = { |
181 | .name = "GPIO-h", | 222 | .name = "GPIO-h", |
182 | .irq_ack = sa1100_high_gpio_ack, | 223 | .irq_ack = sa1100_gpio_ack, |
183 | .irq_mask = sa1100_high_gpio_mask, | 224 | .irq_mask = sa1100_high_gpio_mask, |
184 | .irq_unmask = sa1100_high_gpio_unmask, | 225 | .irq_unmask = sa1100_high_gpio_unmask, |
185 | .irq_set_type = sa1100_gpio_type, | 226 | .irq_set_type = sa1100_gpio_type, |
186 | .irq_set_wake = sa1100_high_gpio_wake, | 227 | .irq_set_wake = sa1100_gpio_wake, |
187 | }; | 228 | }; |
188 | 229 | ||
189 | /* | 230 | static int sa1100_high_gpio_irqdomain_map(struct irq_domain *d, |
190 | * We don't need to ACK IRQs on the SA1100 unless they're GPIOs | 231 | unsigned int irq, irq_hw_number_t hwirq) |
191 | * this is for internal IRQs i.e. from 11 to 31. | ||
192 | */ | ||
193 | static void sa1100_mask_irq(struct irq_data *d) | ||
194 | { | ||
195 | ICMR &= ~(1 << d->irq); | ||
196 | } | ||
197 | |||
198 | static void sa1100_unmask_irq(struct irq_data *d) | ||
199 | { | 232 | { |
200 | ICMR |= (1 << d->irq); | 233 | irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip, |
201 | } | 234 | handle_edge_irq); |
235 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
202 | 236 | ||
203 | /* | 237 | return 0; |
204 | * Apart form GPIOs, only the RTC alarm can be a wakeup event. | ||
205 | */ | ||
206 | static int sa1100_set_wake(struct irq_data *d, unsigned int on) | ||
207 | { | ||
208 | if (d->irq == IRQ_RTCAlrm) { | ||
209 | if (on) | ||
210 | PWER |= PWER_RTC; | ||
211 | else | ||
212 | PWER &= ~PWER_RTC; | ||
213 | return 0; | ||
214 | } | ||
215 | return -EINVAL; | ||
216 | } | 238 | } |
217 | 239 | ||
218 | static struct irq_chip sa1100_normal_chip = { | 240 | static struct irq_domain_ops sa1100_high_gpio_irqdomain_ops = { |
219 | .name = "SC", | 241 | .map = sa1100_high_gpio_irqdomain_map, |
220 | .irq_ack = sa1100_mask_irq, | 242 | .xlate = irq_domain_xlate_onetwocell, |
221 | .irq_mask = sa1100_mask_irq, | ||
222 | .irq_unmask = sa1100_unmask_irq, | ||
223 | .irq_set_wake = sa1100_set_wake, | ||
224 | }; | 243 | }; |
225 | 244 | ||
245 | static struct irq_domain *sa1100_high_gpio_irqdomain; | ||
246 | |||
226 | static struct resource irq_resource = | 247 | static struct resource irq_resource = |
227 | DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); | 248 | DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); |
228 | 249 | ||
@@ -291,10 +312,25 @@ static int __init sa1100irq_init_devicefs(void) | |||
291 | 312 | ||
292 | device_initcall(sa1100irq_init_devicefs); | 313 | device_initcall(sa1100irq_init_devicefs); |
293 | 314 | ||
294 | void __init sa1100_init_irq(void) | 315 | static asmlinkage void __exception_irq_entry |
316 | sa1100_handle_irq(struct pt_regs *regs) | ||
295 | { | 317 | { |
296 | unsigned int irq; | 318 | uint32_t icip, icmr, mask; |
319 | |||
320 | do { | ||
321 | icip = (ICIP); | ||
322 | icmr = (ICMR); | ||
323 | mask = icip & icmr; | ||
324 | |||
325 | if (mask == 0) | ||
326 | break; | ||
327 | |||
328 | handle_IRQ(ffs(mask) - 1 + IRQ_GPIO0, regs); | ||
329 | } while (1); | ||
330 | } | ||
297 | 331 | ||
332 | void __init sa1100_init_irq(void) | ||
333 | { | ||
298 | request_resource(&iomem_resource, &irq_resource); | 334 | request_resource(&iomem_resource, &irq_resource); |
299 | 335 | ||
300 | /* disable all IRQs */ | 336 | /* disable all IRQs */ |
@@ -314,29 +350,24 @@ void __init sa1100_init_irq(void) | |||
314 | */ | 350 | */ |
315 | ICCR = 1; | 351 | ICCR = 1; |
316 | 352 | ||
317 | for (irq = 0; irq <= 10; irq++) { | 353 | sa1100_low_gpio_irqdomain = irq_domain_add_legacy(NULL, |
318 | irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip, | 354 | 11, IRQ_GPIO0, 0, |
319 | handle_edge_irq); | 355 | &sa1100_low_gpio_irqdomain_ops, NULL); |
320 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
321 | } | ||
322 | 356 | ||
323 | for (irq = 12; irq <= 31; irq++) { | 357 | sa1100_normal_irqdomain = irq_domain_add_legacy(NULL, |
324 | irq_set_chip_and_handler(irq, &sa1100_normal_chip, | 358 | 21, IRQ_GPIO11_27, 11, |
325 | handle_level_irq); | 359 | &sa1100_normal_irqdomain_ops, NULL); |
326 | set_irq_flags(irq, IRQF_VALID); | ||
327 | } | ||
328 | 360 | ||
329 | for (irq = 32; irq <= 48; irq++) { | 361 | sa1100_high_gpio_irqdomain = irq_domain_add_legacy(NULL, |
330 | irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip, | 362 | 17, IRQ_GPIO11, 11, |
331 | handle_edge_irq); | 363 | &sa1100_high_gpio_irqdomain_ops, NULL); |
332 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
333 | } | ||
334 | 364 | ||
335 | /* | 365 | /* |
336 | * Install handler for GPIO 11-27 edge detect interrupts | 366 | * Install handler for GPIO 11-27 edge detect interrupts |
337 | */ | 367 | */ |
338 | irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip); | ||
339 | irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler); | 368 | irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler); |
340 | 369 | ||
370 | set_handle_irq(sa1100_handle_irq); | ||
371 | |||
341 | sa1100_init_gpio(); | 372 | sa1100_init_gpio(); |
342 | } | 373 | } |