diff options
Diffstat (limited to 'arch/arm/common/locomo.c')
-rw-r--r-- | arch/arm/common/locomo.c | 362 |
1 files changed, 31 insertions, 331 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index bd36c778c819..90ae00b631c2 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c | |||
@@ -32,6 +32,12 @@ | |||
32 | 32 | ||
33 | #include <asm/hardware/locomo.h> | 33 | #include <asm/hardware/locomo.h> |
34 | 34 | ||
35 | /* LoCoMo Interrupts */ | ||
36 | #define IRQ_LOCOMO_KEY (0) | ||
37 | #define IRQ_LOCOMO_GPIO (1) | ||
38 | #define IRQ_LOCOMO_LT (2) | ||
39 | #define IRQ_LOCOMO_SPI (3) | ||
40 | |||
35 | /* M62332 output channel selection */ | 41 | /* M62332 output channel selection */ |
36 | #define M62332_EVR_CH 1 /* M62332 volume channel number */ | 42 | #define M62332_EVR_CH 1 /* M62332 volume channel number */ |
37 | /* 0 : CH.1 , 1 : CH. 2 */ | 43 | /* 0 : CH.1 , 1 : CH. 2 */ |
@@ -58,6 +64,7 @@ struct locomo { | |||
58 | struct device *dev; | 64 | struct device *dev; |
59 | unsigned long phys; | 65 | unsigned long phys; |
60 | unsigned int irq; | 66 | unsigned int irq; |
67 | int irq_base; | ||
61 | spinlock_t lock; | 68 | spinlock_t lock; |
62 | void __iomem *base; | 69 | void __iomem *base; |
63 | #ifdef CONFIG_PM | 70 | #ifdef CONFIG_PM |
@@ -81,9 +88,7 @@ struct locomo_dev_info { | |||
81 | static struct locomo_dev_info locomo_devices[] = { | 88 | static struct locomo_dev_info locomo_devices[] = { |
82 | { | 89 | { |
83 | .devid = LOCOMO_DEVID_KEYBOARD, | 90 | .devid = LOCOMO_DEVID_KEYBOARD, |
84 | .irq = { | 91 | .irq = { IRQ_LOCOMO_KEY }, |
85 | IRQ_LOCOMO_KEY, | ||
86 | }, | ||
87 | .name = "locomo-keyboard", | 92 | .name = "locomo-keyboard", |
88 | .offset = LOCOMO_KEYBOARD, | 93 | .offset = LOCOMO_KEYBOARD, |
89 | .length = 16, | 94 | .length = 16, |
@@ -133,53 +138,20 @@ static struct locomo_dev_info locomo_devices[] = { | |||
133 | }, | 138 | }, |
134 | }; | 139 | }; |
135 | 140 | ||
136 | |||
137 | /** LoCoMo interrupt handling stuff. | ||
138 | * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs. | ||
139 | * that is, there is only one real hardware interrupt | ||
140 | * we determine which interrupt it is by reading some IO memory. | ||
141 | * We have two levels of expansion, first in the handler for the | ||
142 | * hardware interrupt we generate an interrupt | ||
143 | * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts | ||
144 | * | ||
145 | * hardware irq reads LOCOMO_ICR & 0x0f00 | ||
146 | * IRQ_LOCOMO_KEY_BASE | ||
147 | * IRQ_LOCOMO_GPIO_BASE | ||
148 | * IRQ_LOCOMO_LT_BASE | ||
149 | * IRQ_LOCOMO_SPI_BASE | ||
150 | * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001 | ||
151 | * IRQ_LOCOMO_KEY | ||
152 | * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff | ||
153 | * IRQ_LOCOMO_GPIO[0-15] | ||
154 | * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001 | ||
155 | * IRQ_LOCOMO_LT | ||
156 | * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F | ||
157 | * IRQ_LOCOMO_SPI_RFR | ||
158 | * IRQ_LOCOMO_SPI_RFW | ||
159 | * IRQ_LOCOMO_SPI_OVRN | ||
160 | * IRQ_LOCOMO_SPI_TEND | ||
161 | */ | ||
162 | |||
163 | #define LOCOMO_IRQ_START (IRQ_LOCOMO_KEY_BASE) | ||
164 | #define LOCOMO_IRQ_KEY_START (IRQ_LOCOMO_KEY) | ||
165 | #define LOCOMO_IRQ_GPIO_START (IRQ_LOCOMO_GPIO0) | ||
166 | #define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT) | ||
167 | #define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR) | ||
168 | |||
169 | static void locomo_handler(unsigned int irq, struct irq_desc *desc) | 141 | static void locomo_handler(unsigned int irq, struct irq_desc *desc) |
170 | { | 142 | { |
143 | struct locomo *lchip = get_irq_chip_data(irq); | ||
171 | int req, i; | 144 | int req, i; |
172 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
173 | 145 | ||
174 | /* Acknowledge the parent IRQ */ | 146 | /* Acknowledge the parent IRQ */ |
175 | desc->chip->ack(irq); | 147 | desc->chip->ack(irq); |
176 | 148 | ||
177 | /* check why this interrupt was generated */ | 149 | /* check why this interrupt was generated */ |
178 | req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00; | 150 | req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00; |
179 | 151 | ||
180 | if (req) { | 152 | if (req) { |
181 | /* generate the next interrupt(s) */ | 153 | /* generate the next interrupt(s) */ |
182 | irq = LOCOMO_IRQ_START; | 154 | irq = lchip->irq_base; |
183 | for (i = 0; i <= 3; i++, irq++) { | 155 | for (i = 0; i <= 3; i++, irq++) { |
184 | if (req & (0x0100 << i)) { | 156 | if (req & (0x0100 << i)) { |
185 | generic_handle_irq(irq); | 157 | generic_handle_irq(irq); |
@@ -195,20 +167,20 @@ static void locomo_ack_irq(unsigned int irq) | |||
195 | 167 | ||
196 | static void locomo_mask_irq(unsigned int irq) | 168 | static void locomo_mask_irq(unsigned int irq) |
197 | { | 169 | { |
198 | void __iomem *mapbase = get_irq_chip_data(irq); | 170 | struct locomo *lchip = get_irq_chip_data(irq); |
199 | unsigned int r; | 171 | unsigned int r; |
200 | r = locomo_readl(mapbase + LOCOMO_ICR); | 172 | r = locomo_readl(lchip->base + LOCOMO_ICR); |
201 | r &= ~(0x0010 << (irq - LOCOMO_IRQ_START)); | 173 | r &= ~(0x0010 << (irq - lchip->irq_base)); |
202 | locomo_writel(r, mapbase + LOCOMO_ICR); | 174 | locomo_writel(r, lchip->base + LOCOMO_ICR); |
203 | } | 175 | } |
204 | 176 | ||
205 | static void locomo_unmask_irq(unsigned int irq) | 177 | static void locomo_unmask_irq(unsigned int irq) |
206 | { | 178 | { |
207 | void __iomem *mapbase = get_irq_chip_data(irq); | 179 | struct locomo *lchip = get_irq_chip_data(irq); |
208 | unsigned int r; | 180 | unsigned int r; |
209 | r = locomo_readl(mapbase + LOCOMO_ICR); | 181 | r = locomo_readl(lchip->base + LOCOMO_ICR); |
210 | r |= (0x0010 << (irq - LOCOMO_IRQ_START)); | 182 | r |= (0x0010 << (irq - lchip->irq_base)); |
211 | locomo_writel(r, mapbase + LOCOMO_ICR); | 183 | locomo_writel(r, lchip->base + LOCOMO_ICR); |
212 | } | 184 | } |
213 | 185 | ||
214 | static struct irq_chip locomo_chip = { | 186 | static struct irq_chip locomo_chip = { |
@@ -218,297 +190,22 @@ static struct irq_chip locomo_chip = { | |||
218 | .unmask = locomo_unmask_irq, | 190 | .unmask = locomo_unmask_irq, |
219 | }; | 191 | }; |
220 | 192 | ||
221 | static void locomo_key_handler(unsigned int irq, struct irq_desc *desc) | ||
222 | { | ||
223 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
224 | |||
225 | if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { | ||
226 | generic_handle_irq(LOCOMO_IRQ_KEY_START); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | static void locomo_key_ack_irq(unsigned int irq) | ||
231 | { | ||
232 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
233 | unsigned int r; | ||
234 | r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
235 | r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START)); | ||
236 | locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
237 | } | ||
238 | |||
239 | static void locomo_key_mask_irq(unsigned int irq) | ||
240 | { | ||
241 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
242 | unsigned int r; | ||
243 | r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
244 | r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START)); | ||
245 | locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
246 | } | ||
247 | |||
248 | static void locomo_key_unmask_irq(unsigned int irq) | ||
249 | { | ||
250 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
251 | unsigned int r; | ||
252 | r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
253 | r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START)); | ||
254 | locomo_writel(r, mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); | ||
255 | } | ||
256 | |||
257 | static struct irq_chip locomo_key_chip = { | ||
258 | .name = "LOCOMO-key", | ||
259 | .ack = locomo_key_ack_irq, | ||
260 | .mask = locomo_key_mask_irq, | ||
261 | .unmask = locomo_key_unmask_irq, | ||
262 | }; | ||
263 | |||
264 | static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc) | ||
265 | { | ||
266 | int req, i; | ||
267 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
268 | |||
269 | req = locomo_readl(mapbase + LOCOMO_GIR) & | ||
270 | locomo_readl(mapbase + LOCOMO_GPD) & | ||
271 | 0xffff; | ||
272 | |||
273 | if (req) { | ||
274 | irq = LOCOMO_IRQ_GPIO_START; | ||
275 | for (i = 0; i <= 15; i++, irq++) { | ||
276 | if (req & (0x0001 << i)) { | ||
277 | generic_handle_irq(irq); | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static void locomo_gpio_ack_irq(unsigned int irq) | ||
284 | { | ||
285 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
286 | unsigned int r; | ||
287 | r = locomo_readl(mapbase + LOCOMO_GWE); | ||
288 | r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); | ||
289 | locomo_writel(r, mapbase + LOCOMO_GWE); | ||
290 | |||
291 | r = locomo_readl(mapbase + LOCOMO_GIS); | ||
292 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); | ||
293 | locomo_writel(r, mapbase + LOCOMO_GIS); | ||
294 | |||
295 | r = locomo_readl(mapbase + LOCOMO_GWE); | ||
296 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); | ||
297 | locomo_writel(r, mapbase + LOCOMO_GWE); | ||
298 | } | ||
299 | |||
300 | static void locomo_gpio_mask_irq(unsigned int irq) | ||
301 | { | ||
302 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
303 | unsigned int r; | ||
304 | r = locomo_readl(mapbase + LOCOMO_GIE); | ||
305 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); | ||
306 | locomo_writel(r, mapbase + LOCOMO_GIE); | ||
307 | } | ||
308 | |||
309 | static void locomo_gpio_unmask_irq(unsigned int irq) | ||
310 | { | ||
311 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
312 | unsigned int r; | ||
313 | r = locomo_readl(mapbase + LOCOMO_GIE); | ||
314 | r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); | ||
315 | locomo_writel(r, mapbase + LOCOMO_GIE); | ||
316 | } | ||
317 | |||
318 | static int GPIO_IRQ_rising_edge; | ||
319 | static int GPIO_IRQ_falling_edge; | ||
320 | |||
321 | static int locomo_gpio_type(unsigned int irq, unsigned int type) | ||
322 | { | ||
323 | unsigned int mask; | ||
324 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
325 | |||
326 | mask = 1 << (irq - LOCOMO_IRQ_GPIO_START); | ||
327 | |||
328 | if (type == IRQ_TYPE_PROBE) { | ||
329 | if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) | ||
330 | return 0; | ||
331 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | ||
332 | } | ||
333 | |||
334 | if (type & IRQ_TYPE_EDGE_RISING) | ||
335 | GPIO_IRQ_rising_edge |= mask; | ||
336 | else | ||
337 | GPIO_IRQ_rising_edge &= ~mask; | ||
338 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
339 | GPIO_IRQ_falling_edge |= mask; | ||
340 | else | ||
341 | GPIO_IRQ_falling_edge &= ~mask; | ||
342 | locomo_writel(GPIO_IRQ_rising_edge, mapbase + LOCOMO_GRIE); | ||
343 | locomo_writel(GPIO_IRQ_falling_edge, mapbase + LOCOMO_GFIE); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static struct irq_chip locomo_gpio_chip = { | ||
349 | .name = "LOCOMO-gpio", | ||
350 | .ack = locomo_gpio_ack_irq, | ||
351 | .mask = locomo_gpio_mask_irq, | ||
352 | .unmask = locomo_gpio_unmask_irq, | ||
353 | .set_type = locomo_gpio_type, | ||
354 | }; | ||
355 | |||
356 | static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc) | ||
357 | { | ||
358 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
359 | |||
360 | if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { | ||
361 | generic_handle_irq(LOCOMO_IRQ_LT_START); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | static void locomo_lt_ack_irq(unsigned int irq) | ||
366 | { | ||
367 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
368 | unsigned int r; | ||
369 | r = locomo_readl(mapbase + LOCOMO_LTINT); | ||
370 | r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START)); | ||
371 | locomo_writel(r, mapbase + LOCOMO_LTINT); | ||
372 | } | ||
373 | |||
374 | static void locomo_lt_mask_irq(unsigned int irq) | ||
375 | { | ||
376 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
377 | unsigned int r; | ||
378 | r = locomo_readl(mapbase + LOCOMO_LTINT); | ||
379 | r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START)); | ||
380 | locomo_writel(r, mapbase + LOCOMO_LTINT); | ||
381 | } | ||
382 | |||
383 | static void locomo_lt_unmask_irq(unsigned int irq) | ||
384 | { | ||
385 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
386 | unsigned int r; | ||
387 | r = locomo_readl(mapbase + LOCOMO_LTINT); | ||
388 | r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START)); | ||
389 | locomo_writel(r, mapbase + LOCOMO_LTINT); | ||
390 | } | ||
391 | |||
392 | static struct irq_chip locomo_lt_chip = { | ||
393 | .name = "LOCOMO-lt", | ||
394 | .ack = locomo_lt_ack_irq, | ||
395 | .mask = locomo_lt_mask_irq, | ||
396 | .unmask = locomo_lt_unmask_irq, | ||
397 | }; | ||
398 | |||
399 | static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc) | ||
400 | { | ||
401 | int req, i; | ||
402 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
403 | |||
404 | req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F; | ||
405 | if (req) { | ||
406 | irq = LOCOMO_IRQ_SPI_START; | ||
407 | |||
408 | for (i = 0; i <= 3; i++, irq++) { | ||
409 | if (req & (0x0001 << i)) { | ||
410 | generic_handle_irq(irq); | ||
411 | } | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static void locomo_spi_ack_irq(unsigned int irq) | ||
417 | { | ||
418 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
419 | unsigned int r; | ||
420 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); | ||
421 | r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | ||
422 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); | ||
423 | |||
424 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS); | ||
425 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | ||
426 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS); | ||
427 | |||
428 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); | ||
429 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | ||
430 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); | ||
431 | } | ||
432 | |||
433 | static void locomo_spi_mask_irq(unsigned int irq) | ||
434 | { | ||
435 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
436 | unsigned int r; | ||
437 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); | ||
438 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | ||
439 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); | ||
440 | } | ||
441 | |||
442 | static void locomo_spi_unmask_irq(unsigned int irq) | ||
443 | { | ||
444 | void __iomem *mapbase = get_irq_chip_data(irq); | ||
445 | unsigned int r; | ||
446 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); | ||
447 | r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | ||
448 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); | ||
449 | } | ||
450 | |||
451 | static struct irq_chip locomo_spi_chip = { | ||
452 | .name = "LOCOMO-spi", | ||
453 | .ack = locomo_spi_ack_irq, | ||
454 | .mask = locomo_spi_mask_irq, | ||
455 | .unmask = locomo_spi_unmask_irq, | ||
456 | }; | ||
457 | |||
458 | static void locomo_setup_irq(struct locomo *lchip) | 193 | static void locomo_setup_irq(struct locomo *lchip) |
459 | { | 194 | { |
460 | int irq; | 195 | int irq = lchip->irq_base; |
461 | void __iomem *irqbase = lchip->base; | ||
462 | 196 | ||
463 | /* | 197 | /* |
464 | * Install handler for IRQ_LOCOMO_HW. | 198 | * Install handler for IRQ_LOCOMO_HW. |
465 | */ | 199 | */ |
466 | set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); | 200 | set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING); |
467 | set_irq_chip_data(lchip->irq, irqbase); | 201 | set_irq_chip_data(lchip->irq, lchip); |
468 | set_irq_chained_handler(lchip->irq, locomo_handler); | 202 | set_irq_chained_handler(lchip->irq, locomo_handler); |
469 | 203 | ||
470 | /* Install handlers for IRQ_LOCOMO_*_BASE */ | 204 | /* Install handlers for IRQ_LOCOMO_* */ |
471 | set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip); | 205 | for ( ; irq <= lchip->irq_base + 3; irq++) { |
472 | set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase); | 206 | set_irq_chip(irq, &locomo_chip); |
473 | set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler); | 207 | set_irq_chip_data(irq, lchip); |
474 | 208 | set_irq_handler(irq, handle_level_irq); | |
475 | set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip); | ||
476 | set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase); | ||
477 | set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler); | ||
478 | |||
479 | set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip); | ||
480 | set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase); | ||
481 | set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler); | ||
482 | |||
483 | set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip); | ||
484 | set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase); | ||
485 | set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler); | ||
486 | |||
487 | /* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */ | ||
488 | set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip); | ||
489 | set_irq_chip_data(LOCOMO_IRQ_KEY_START, irqbase); | ||
490 | set_irq_handler(LOCOMO_IRQ_KEY_START, handle_edge_irq); | ||
491 | set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE); | ||
492 | |||
493 | /* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */ | ||
494 | for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) { | ||
495 | set_irq_chip(irq, &locomo_gpio_chip); | ||
496 | set_irq_chip_data(irq, irqbase); | ||
497 | set_irq_handler(irq, handle_edge_irq); | ||
498 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
499 | } | ||
500 | |||
501 | /* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */ | ||
502 | set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip); | ||
503 | set_irq_chip_data(LOCOMO_IRQ_LT_START, irqbase); | ||
504 | set_irq_handler(LOCOMO_IRQ_LT_START, handle_edge_irq); | ||
505 | set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE); | ||
506 | |||
507 | /* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */ | ||
508 | for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 4; irq++) { | ||
509 | set_irq_chip(irq, &locomo_spi_chip); | ||
510 | set_irq_chip_data(irq, irqbase); | ||
511 | set_irq_handler(irq, handle_edge_irq); | ||
512 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 209 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
513 | } | 210 | } |
514 | } | 211 | } |
@@ -555,7 +252,8 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) | |||
555 | dev->mapbase = 0; | 252 | dev->mapbase = 0; |
556 | dev->length = info->length; | 253 | dev->length = info->length; |
557 | 254 | ||
558 | memmove(dev->irq, info->irq, sizeof(dev->irq)); | 255 | dev->irq[0] = (lchip->irq_base == NO_IRQ) ? |
256 | NO_IRQ : lchip->irq_base + info->irq[0]; | ||
559 | 257 | ||
560 | ret = device_register(&dev->dev); | 258 | ret = device_register(&dev->dev); |
561 | if (ret) { | 259 | if (ret) { |
@@ -672,6 +370,7 @@ static int locomo_resume(struct platform_device *dev) | |||
672 | static int | 370 | static int |
673 | __locomo_probe(struct device *me, struct resource *mem, int irq) | 371 | __locomo_probe(struct device *me, struct resource *mem, int irq) |
674 | { | 372 | { |
373 | struct locomo_platform_data *pdata = me->platform_data; | ||
675 | struct locomo *lchip; | 374 | struct locomo *lchip; |
676 | unsigned long r; | 375 | unsigned long r; |
677 | int i, ret = -ENODEV; | 376 | int i, ret = -ENODEV; |
@@ -687,6 +386,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) | |||
687 | 386 | ||
688 | lchip->phys = mem->start; | 387 | lchip->phys = mem->start; |
689 | lchip->irq = irq; | 388 | lchip->irq = irq; |
389 | lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ; | ||
690 | 390 | ||
691 | /* | 391 | /* |
692 | * Map the whole region. This also maps the | 392 | * Map the whole region. This also maps the |
@@ -753,7 +453,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) | |||
753 | * The interrupt controller must be initialised before any | 453 | * The interrupt controller must be initialised before any |
754 | * other device to ensure that the interrupts are available. | 454 | * other device to ensure that the interrupts are available. |
755 | */ | 455 | */ |
756 | if (lchip->irq != NO_IRQ) | 456 | if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ) |
757 | locomo_setup_irq(lchip); | 457 | locomo_setup_irq(lchip); |
758 | 458 | ||
759 | for (i = 0; i < ARRAY_SIZE(locomo_devices); i++) | 459 | for (i = 0; i < ARRAY_SIZE(locomo_devices); i++) |