diff mbox

[07/15] ARM: shmobile: INTC External IRQ pin driver on r8a7779

Message ID 1364358915-6063-8-git-send-email-horms+renesas@verge.net.au (mailing list archive)
State New, archived
Headers show

Commit Message

Simon Horman March 27, 2013, 4:35 a.m. UTC
From: Magnus Damm <damm@opensource.se>

Update the r8a7779 IRQ code to make use of the
INTC External IRQ pin driver for external
interrupt pins IRQ0 -> IRQ3.

The r8a7779 SoC can like older SH SoCs configure
to use the IRQ0 -> IRQ3 signals as individual
interrupts or a combined IRL mode.

Without this patch the r8a7779 SoC code does
not fully support external IRQ pins in individual
IRQ mode. The r8a7779 PFC code does not yet have
gpio_to_irq() support so no need to update such
code.

At this point the DT reference implementations
are not covered. In the future such code shall
tie in the INTC External IRQ pin driver via
DT, so this kind of verbose code is not needed
for the long term DT case.

Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
(cherry picked from commit dd9e1fa565b335a5fd2768b772c673a4860196d7)

Conflicts:
	arch/arm/mach-shmobile/Kconfig
	arch/arm/mach-shmobile/include/mach/common.h
	arch/arm/mach-shmobile/intc-r8a7779.c

Signed-off-by: Simon Horman <horms@verge.net.au>
---
 arch/arm/mach-shmobile/Kconfig               |    1 +
 arch/arm/mach-shmobile/board-marzen.c        |    3 +-
 arch/arm/mach-shmobile/include/mach/common.h |    2 +
 arch/arm/mach-shmobile/intc-r8a7779.c        |   52 ++++++++++++++++++++++++++
 4 files changed, 57 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index f8aaab7..4c678e5 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -40,6 +40,7 @@  config ARCH_R8A7779
 	select SH_CLK_CPG
 	select ARM_GIC
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select RENESAS_INTC_IRQPIN
 
 config ARCH_EMEV2
 	bool "Emma Mobile EV2"
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index fcf5a47f..9b0dcec 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -53,7 +53,7 @@  static struct resource smsc911x_resources[] = {
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start		= gic_spi(28), /* IRQ 1 */
+		.start		= irq_pin(1), /* IRQ1 */
 		.flags		= IORESOURCE_IRQ,
 	},
 };
@@ -84,6 +84,7 @@  static void __init marzen_init(void)
 	regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
 
 	r8a7779_pinmux_init();
+	r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */
 
 	/* SCIF2 (CN18: DEBUG0) */
 	gpio_request(GPIO_FN_TX2_C, NULL);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 54a37a5..8180a73 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -72,6 +72,8 @@  extern void r8a7740_reserve_memory(void);
 extern void r8a7740_pinmux_init(void);
 
 extern void r8a7779_init_irq(void);
+extern void r8a7779_init_irq_extpin(int irlm);
+extern void r8a7779_init_irq_dt(void);
 extern void r8a7779_map_io(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c
index f04fad4..9de6d03 100644
--- a/arch/arm/mach-shmobile/intc-r8a7779.c
+++ b/arch/arm/mach-shmobile/intc-r8a7779.c
@@ -19,11 +19,15 @@ 
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/platform_data/irq-renesas-intc-irqpin.h>
+#include <linux/irqchip.h>
 #include <mach/common.h>
 #include <mach/intc.h>
+#include <mach/irqs.h>
 #include <mach/r8a7779.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
@@ -38,6 +42,54 @@ 
 #define INT2NTSR0 0xfe700060
 #define INT2NTSR1 0xfe700064
 
+struct renesas_intc_irqpin_config irqpin0_platform_data = {
+	.irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
+	.sense_bitfield_width = 2,
+};
+
+static struct resource irqpin0_resources[] = {
+	DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */
+	DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */
+	DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */
+	DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */
+	DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */
+	DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */
+	DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */
+	DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */
+	DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
+};
+
+static struct platform_device irqpin0_device = {
+	.name		= "renesas_intc_irqpin",
+	.id		= 0,
+	.resource	= irqpin0_resources,
+	.num_resources	= ARRAY_SIZE(irqpin0_resources),
+	.dev		= {
+		.platform_data	= &irqpin0_platform_data,
+	},
+};
+
+void __init r8a7779_init_irq_extpin(int irlm)
+{
+	void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
+	unsigned long tmp;
+
+	if (icr0) {
+		tmp = ioread32(icr0);
+		if (irlm)
+			tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */
+		else
+			tmp &= ~(1 << 23); /* IRL mode - not supported */
+		tmp |= (1 << 21); /* LVLMODE = 1 */
+		iowrite32(tmp, icr0);
+		iounmap(icr0);
+
+		if (irlm)
+			platform_device_register(&irqpin0_device);
+	} else
+		pr_warn("r8a7779: unable to setup external irq pin mode\n");
+}
+
 static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
 {
 	return 0; /* always allow wakeup */