diff options
-rw-r--r-- | arch/arm/mach-shmobile/board-ag5evm.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/sh73a0.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/intc-sh73a0.c | 65 |
3 files changed, 71 insertions, 15 deletions
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index d6e461710524..83624e26b884 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c | |||
@@ -59,7 +59,7 @@ static struct resource smsc9220_resources[] = { | |||
59 | .flags = IORESOURCE_MEM, | 59 | .flags = IORESOURCE_MEM, |
60 | }, | 60 | }, |
61 | [1] = { | 61 | [1] = { |
62 | .start = gic_spi(33), /* PINT1 */ | 62 | .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */ |
63 | .flags = IORESOURCE_IRQ, | 63 | .flags = IORESOURCE_IRQ, |
64 | }, | 64 | }, |
65 | }; | 65 | }; |
@@ -474,19 +474,6 @@ static void __init ag5evm_map_io(void) | |||
474 | shmobile_setup_console(); | 474 | shmobile_setup_console(); |
475 | } | 475 | } |
476 | 476 | ||
477 | #define PINTC_ADDR 0xe6900000 | ||
478 | #define PINTER0A (PINTC_ADDR + 0xa0) | ||
479 | #define PINTCR0A (PINTC_ADDR + 0xb0) | ||
480 | |||
481 | void __init ag5evm_init_irq(void) | ||
482 | { | ||
483 | sh73a0_init_irq(); | ||
484 | |||
485 | /* setup PINT: enable PINTA2 as active low */ | ||
486 | __raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A); | ||
487 | __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A); | ||
488 | } | ||
489 | |||
490 | #define DSI0PHYCR 0xe615006c | 477 | #define DSI0PHYCR 0xe615006c |
491 | 478 | ||
492 | static void __init ag5evm_init(void) | 479 | static void __init ag5evm_init(void) |
@@ -620,7 +607,7 @@ struct sys_timer ag5evm_timer = { | |||
620 | 607 | ||
621 | MACHINE_START(AG5EVM, "ag5evm") | 608 | MACHINE_START(AG5EVM, "ag5evm") |
622 | .map_io = ag5evm_map_io, | 609 | .map_io = ag5evm_map_io, |
623 | .init_irq = ag5evm_init_irq, | 610 | .init_irq = sh73a0_init_irq, |
624 | .handle_irq = shmobile_handle_irq_gic, | 611 | .handle_irq = shmobile_handle_irq_gic, |
625 | .init_machine = ag5evm_init, | 612 | .init_machine = ag5evm_init, |
626 | .timer = &ag5evm_timer, | 613 | .timer = &ag5evm_timer, |
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h index b385e976797a..18ae6a990bc2 100644 --- a/arch/arm/mach-shmobile/include/mach/sh73a0.h +++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h | |||
@@ -507,4 +507,8 @@ enum { | |||
507 | SHDMA_SLAVE_MMCIF_RX, | 507 | SHDMA_SLAVE_MMCIF_RX, |
508 | }; | 508 | }; |
509 | 509 | ||
510 | /* PINT interrupts are located at Linux IRQ 768 and up */ | ||
511 | #define SH73A0_PINT0_IRQ(irq) ((irq) + 768) | ||
512 | #define SH73A0_PINT1_IRQ(irq) ((irq) + 800) | ||
513 | |||
510 | #endif /* __ASM_SH73A0_H__ */ | 514 | #endif /* __ASM_SH73A0_H__ */ |
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 836e81557986..1eda6b0b69e3 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/sh_intc.h> | 24 | #include <linux/sh_intc.h> |
25 | #include <mach/intc.h> | 25 | #include <mach/intc.h> |
26 | #include <mach/sh73a0.h> | ||
26 | #include <asm/hardware/gic.h> | 27 | #include <asm/hardware/gic.h> |
27 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
28 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
@@ -363,6 +364,59 @@ static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id) | |||
363 | 364 | ||
364 | static struct irqaction sh73a0_irq_pin_cascade[32]; | 365 | static struct irqaction sh73a0_irq_pin_cascade[32]; |
365 | 366 | ||
367 | #define PINTER0 0xe69000a0 | ||
368 | #define PINTER1 0xe69000a4 | ||
369 | #define PINTRR0 0xe69000d0 | ||
370 | #define PINTRR1 0xe69000d4 | ||
371 | |||
372 | #define PINT0A_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq)) | ||
373 | #define PINT0B_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 8)) | ||
374 | #define PINT0C_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 16)) | ||
375 | #define PINT0D_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 24)) | ||
376 | #define PINT1E_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT1_IRQ(irq)) | ||
377 | |||
378 | INTC_PINT(intc_pint0, PINTER0, 0xe69000b0, "sh73a0-pint0", \ | ||
379 | INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \ | ||
380 | INTC_PINT_V(A, PINT0A_IRQ), INTC_PINT_V(B, PINT0B_IRQ), \ | ||
381 | INTC_PINT_V(C, PINT0C_IRQ), INTC_PINT_V(D, PINT0D_IRQ), \ | ||
382 | INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \ | ||
383 | INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D)); | ||
384 | |||
385 | INTC_PINT(intc_pint1, PINTER1, 0xe69000c0, "sh73a0-pint1", \ | ||
386 | INTC_PINT_E(E), INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, \ | ||
387 | INTC_PINT_V(E, PINT1E_IRQ), INTC_PINT_V_NONE, \ | ||
388 | INTC_PINT_V_NONE, INTC_PINT_V_NONE, \ | ||
389 | INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E(E), \ | ||
390 | INTC_PINT_E(E), INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE); | ||
391 | |||
392 | static struct irqaction sh73a0_pint0_cascade; | ||
393 | static struct irqaction sh73a0_pint1_cascade; | ||
394 | |||
395 | static void pint_demux(unsigned long rr, unsigned long er, int base_irq) | ||
396 | { | ||
397 | unsigned long value = ioread32(rr) & ioread32(er); | ||
398 | int k; | ||
399 | |||
400 | for (k = 0; k < 32; k++) { | ||
401 | if (value & (1 << (31 - k))) { | ||
402 | generic_handle_irq(base_irq + k); | ||
403 | iowrite32(~(1 << (31 - k)), rr); | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
408 | static irqreturn_t sh73a0_pint0_demux(int irq, void *dev_id) | ||
409 | { | ||
410 | pint_demux(PINTRR0, PINTER0, SH73A0_PINT0_IRQ(0)); | ||
411 | return IRQ_HANDLED; | ||
412 | } | ||
413 | |||
414 | static irqreturn_t sh73a0_pint1_demux(int irq, void *dev_id) | ||
415 | { | ||
416 | pint_demux(PINTRR1, PINTER1, SH73A0_PINT1_IRQ(0)); | ||
417 | return IRQ_HANDLED; | ||
418 | } | ||
419 | |||
366 | void __init sh73a0_init_irq(void) | 420 | void __init sh73a0_init_irq(void) |
367 | { | 421 | { |
368 | void __iomem *gic_dist_base = __io(0xf0001000); | 422 | void __iomem *gic_dist_base = __io(0xf0001000); |
@@ -375,6 +429,8 @@ void __init sh73a0_init_irq(void) | |||
375 | 429 | ||
376 | register_intc_controller(&intcs_desc); | 430 | register_intc_controller(&intcs_desc); |
377 | register_intc_controller(&intca_irq_pins_desc); | 431 | register_intc_controller(&intca_irq_pins_desc); |
432 | register_intc_controller(&intc_pint0_desc); | ||
433 | register_intc_controller(&intc_pint1_desc); | ||
378 | 434 | ||
379 | /* demux using INTEVTSA */ | 435 | /* demux using INTEVTSA */ |
380 | sh73a0_intcs_cascade.name = "INTCS cascade"; | 436 | sh73a0_intcs_cascade.name = "INTCS cascade"; |
@@ -393,4 +449,13 @@ void __init sh73a0_init_irq(void) | |||
393 | handle_level_irq, "level"); | 449 | handle_level_irq, "level"); |
394 | set_irq_flags(n, IRQF_VALID); /* yuck */ | 450 | set_irq_flags(n, IRQF_VALID); /* yuck */ |
395 | } | 451 | } |
452 | |||
453 | /* PINT pins are sanely tied to the GIC as SPI */ | ||
454 | sh73a0_pint0_cascade.name = "PINT0 cascade"; | ||
455 | sh73a0_pint0_cascade.handler = sh73a0_pint0_demux; | ||
456 | setup_irq(gic_spi(33), &sh73a0_pint0_cascade); | ||
457 | |||
458 | sh73a0_pint1_cascade.name = "PINT1 cascade"; | ||
459 | sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; | ||
460 | setup_irq(gic_spi(34), &sh73a0_pint1_cascade); | ||
396 | } | 461 | } |