| From ba8cc79e847a7743d3c835c92fb2f73c32871f3d Mon Sep 17 00:00:00 2001 |
| From: Magnus Damm <damm@opensource.se> |
| Date: Mon, 17 Oct 2011 18:00:52 +0900 |
| Subject: ARM: mach-shmobile: sh73a0 and AG5EVM PINT support |
| |
| Support PINT on sh73a0 and AG5EVM using INTC PINT macros. |
| |
| With this patch applied the AG5EVM ethernet is handled |
| through one of the chained sh73a0 PINT interrupt controllers. |
| |
| Signed-off-by: Magnus Damm <damm@opensource.se> |
| Signed-off-by: Paul Mundt <lethal@linux-sh.org> |
| (cherry picked from commit 566aad39df77211467078e0b3dcd62100f56b5e4) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| arch/arm/mach-shmobile/board-ag5evm.c | 17 +------- |
| arch/arm/mach-shmobile/include/mach/sh73a0.h | 4 ++ |
| 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 f04ee16..430c723 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[] = { |
| .flags = IORESOURCE_MEM, |
| }, |
| [1] = { |
| - .start = gic_spi(33), /* PINT1 */ |
| + .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */ |
| .flags = IORESOURCE_IRQ, |
| }, |
| }; |
| @@ -445,19 +445,6 @@ static void __init ag5evm_map_io(void) |
| shmobile_setup_console(); |
| } |
| |
| -#define PINTC_ADDR 0xe6900000 |
| -#define PINTER0A (PINTC_ADDR + 0xa0) |
| -#define PINTCR0A (PINTC_ADDR + 0xb0) |
| - |
| -void __init ag5evm_init_irq(void) |
| -{ |
| - sh73a0_init_irq(); |
| - |
| - /* setup PINT: enable PINTA2 as active low */ |
| - __raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A); |
| - __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A); |
| -} |
| - |
| #define DSI0PHYCR 0xe615006c |
| |
| static void __init ag5evm_init(void) |
| @@ -584,7 +571,7 @@ struct sys_timer ag5evm_timer = { |
| |
| MACHINE_START(AG5EVM, "ag5evm") |
| .map_io = ag5evm_map_io, |
| - .init_irq = ag5evm_init_irq, |
| + .init_irq = sh73a0_init_irq, |
| .handle_irq = shmobile_handle_irq_gic, |
| .init_machine = ag5evm_init, |
| .timer = &ag5evm_timer, |
| diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h |
| index b385e97..18ae6a9 100644 |
| --- a/arch/arm/mach-shmobile/include/mach/sh73a0.h |
| +++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h |
| @@ -507,4 +507,8 @@ enum { |
| SHDMA_SLAVE_MMCIF_RX, |
| }; |
| |
| +/* PINT interrupts are located at Linux IRQ 768 and up */ |
| +#define SH73A0_PINT0_IRQ(irq) ((irq) + 768) |
| +#define SH73A0_PINT1_IRQ(irq) ((irq) + 800) |
| + |
| #endif /* __ASM_SH73A0_H__ */ |
| diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c |
| index 836e815..1eda6b0 100644 |
| --- a/arch/arm/mach-shmobile/intc-sh73a0.c |
| +++ b/arch/arm/mach-shmobile/intc-sh73a0.c |
| @@ -23,6 +23,7 @@ |
| #include <linux/io.h> |
| #include <linux/sh_intc.h> |
| #include <mach/intc.h> |
| +#include <mach/sh73a0.h> |
| #include <asm/hardware/gic.h> |
| #include <asm/mach-types.h> |
| #include <asm/mach/arch.h> |
| @@ -363,6 +364,59 @@ static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id) |
| |
| static struct irqaction sh73a0_irq_pin_cascade[32]; |
| |
| +#define PINTER0 0xe69000a0 |
| +#define PINTER1 0xe69000a4 |
| +#define PINTRR0 0xe69000d0 |
| +#define PINTRR1 0xe69000d4 |
| + |
| +#define PINT0A_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq)) |
| +#define PINT0B_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 8)) |
| +#define PINT0C_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 16)) |
| +#define PINT0D_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 24)) |
| +#define PINT1E_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT1_IRQ(irq)) |
| + |
| +INTC_PINT(intc_pint0, PINTER0, 0xe69000b0, "sh73a0-pint0", \ |
| + INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \ |
| + INTC_PINT_V(A, PINT0A_IRQ), INTC_PINT_V(B, PINT0B_IRQ), \ |
| + INTC_PINT_V(C, PINT0C_IRQ), INTC_PINT_V(D, PINT0D_IRQ), \ |
| + INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \ |
| + INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D)); |
| + |
| +INTC_PINT(intc_pint1, PINTER1, 0xe69000c0, "sh73a0-pint1", \ |
| + INTC_PINT_E(E), INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, \ |
| + INTC_PINT_V(E, PINT1E_IRQ), INTC_PINT_V_NONE, \ |
| + INTC_PINT_V_NONE, INTC_PINT_V_NONE, \ |
| + INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E(E), \ |
| + INTC_PINT_E(E), INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE); |
| + |
| +static struct irqaction sh73a0_pint0_cascade; |
| +static struct irqaction sh73a0_pint1_cascade; |
| + |
| +static void pint_demux(unsigned long rr, unsigned long er, int base_irq) |
| +{ |
| + unsigned long value = ioread32(rr) & ioread32(er); |
| + int k; |
| + |
| + for (k = 0; k < 32; k++) { |
| + if (value & (1 << (31 - k))) { |
| + generic_handle_irq(base_irq + k); |
| + iowrite32(~(1 << (31 - k)), rr); |
| + } |
| + } |
| +} |
| + |
| +static irqreturn_t sh73a0_pint0_demux(int irq, void *dev_id) |
| +{ |
| + pint_demux(PINTRR0, PINTER0, SH73A0_PINT0_IRQ(0)); |
| + return IRQ_HANDLED; |
| +} |
| + |
| +static irqreturn_t sh73a0_pint1_demux(int irq, void *dev_id) |
| +{ |
| + pint_demux(PINTRR1, PINTER1, SH73A0_PINT1_IRQ(0)); |
| + return IRQ_HANDLED; |
| +} |
| + |
| void __init sh73a0_init_irq(void) |
| { |
| void __iomem *gic_dist_base = __io(0xf0001000); |
| @@ -375,6 +429,8 @@ void __init sh73a0_init_irq(void) |
| |
| register_intc_controller(&intcs_desc); |
| register_intc_controller(&intca_irq_pins_desc); |
| + register_intc_controller(&intc_pint0_desc); |
| + register_intc_controller(&intc_pint1_desc); |
| |
| /* demux using INTEVTSA */ |
| sh73a0_intcs_cascade.name = "INTCS cascade"; |
| @@ -393,4 +449,13 @@ void __init sh73a0_init_irq(void) |
| handle_level_irq, "level"); |
| set_irq_flags(n, IRQF_VALID); /* yuck */ |
| } |
| + |
| + /* PINT pins are sanely tied to the GIC as SPI */ |
| + sh73a0_pint0_cascade.name = "PINT0 cascade"; |
| + sh73a0_pint0_cascade.handler = sh73a0_pint0_demux; |
| + setup_irq(gic_spi(33), &sh73a0_pint0_cascade); |
| + |
| + sh73a0_pint1_cascade.name = "PINT1 cascade"; |
| + sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; |
| + setup_irq(gic_spi(34), &sh73a0_pint1_cascade); |
| } |
| -- |
| 1.7.10.2.565.gbd578b5 |
| |