[PATCH 4/7] Samsung: SMDKV210 Init VIC using Device Tree
Shaju Abraham
shaju.abraham at linaro.org
Mon Sep 20 20:19:46 EST 2010
SMDKV210 has 4 VICs. Use the device tree to get the virtual and
physical address and the bit mask for the populted IRQ on each
VIC.
The DT probing of VIC is moved to a seperate file which gets compiled
only if device tree support is enabled
Signed-off-by: Shaju Abraham <shaju.abraham at linaro.org>
---
arch/arm/mach-s5pv210/cpu.c | 3 +-
arch/arm/mach-s5pv210/mach-smdkv210_dt.c | 9 +++-
arch/arm/plat-s5p/Makefile | 4 +
arch/arm/plat-s5p/irq_dt.c | 98 ++++++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/plat-s5p/irq_dt.c
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 411a4a9..94165b7 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -103,6 +103,7 @@ void __init s5pv210_init_clocks(int xtal)
s5pv210_setup_clocks();
}
+#ifndef CONFIG_USE_OF
void __init s5pv210_init_irq(void)
{
u32 vic[4]; /* S5PV210 supports 4 VIC */
@@ -115,7 +116,7 @@ void __init s5pv210_init_irq(void)
s5p_init_irq(vic, ARRAY_SIZE(vic));
}
-
+#endif
struct sysdev_class s5pv210_sysclass = {
.name = "s5pv210-core",
};
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210_dt.c b/arch/arm/mach-s5pv210/mach-smdkv210_dt.c
index 679401b..d0e930c 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210_dt.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210_dt.c
@@ -41,6 +41,7 @@
#include <plat/ts.h>
+extern void s5p_dt_init_irq(void);
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -88,6 +89,12 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
};
+void __init s5pv210_dt_init_irq(void)
+{
+ s5p_dt_init_irq();
+}
+
+
static void __init smdkv210_map_io(void)
{
@@ -114,7 +121,7 @@ static int __init smdkv210_dt_probe(unsigned long dt)
DT_MACHINE_START(SMDKV210, "SMDKV210 (Device Tree Support)")
.boot_params = 0x00000100,
.map_io = smdkv210_map_io,
- .init_irq = s5pv210_init_irq,
+ .init_irq = s5pv210_dt_init_irq,
.init_machine = smdkv210_dt_init,
.timer = &s3c24xx_timer,
.probe_dt = smdkv210_dt_probe,
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index cdfb78d..e4d7218 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -16,6 +16,10 @@ obj-y += dev-uart.o
obj-y += cpu.o
obj-$(CONFIG_USE_NONCOMMON_STRUCT_CLK) += clock.o
obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clock-common-clk.o
+ifeq ($(CONFIG_USE_OF),y)
+obj-y += irq_dt.o
+else
obj-y += irq.o
+endif
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
diff --git a/arch/arm/plat-s5p/irq_dt.c b/arch/arm/plat-s5p/irq_dt.c
new file mode 100644
index 0000000..2fca196
--- /dev/null
+++ b/arch/arm/plat-s5p/irq_dt.c
@@ -0,0 +1,98 @@
+/* arch/arm/plat-s5p/irq_dt.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Interrupt handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+
+#include <asm/hardware/vic.h>
+
+#include <linux/serial_core.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
+
+/*
+ * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
+ * are consecutive when looking up the interrupt in the demux routines.
+ */
+static struct s3c_uart_irq uart_irqs[] = {
+ [0] = {
+ .regs = S5P_VA_UART0,
+ .base_irq = IRQ_S5P_UART_BASE0,
+ .parent_irq = IRQ_UART0,
+ },
+ [1] = {
+ .regs = S5P_VA_UART1,
+ .base_irq = IRQ_S5P_UART_BASE1,
+ .parent_irq = IRQ_UART1,
+ },
+ [2] = {
+ .regs = S5P_VA_UART2,
+ .base_irq = IRQ_S5P_UART_BASE2,
+ .parent_irq = IRQ_UART2,
+ },
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+ [3] = {
+ .regs = S5P_VA_UART3,
+ .base_irq = IRQ_S5P_UART_BASE3,
+ .parent_irq = IRQ_UART3,
+ },
+#endif
+};
+
+
+static int __init s5p_dt_vic_init(void)
+{
+ struct device_node *node;
+ struct resource r;
+ int err = -ENODEV , irq = 0;
+ const u32 *prop;
+ u32 virt_reg = 0, src_mask = 0;
+
+ for_each_compatible_node(node , NULL , "arm,vic") {
+ err = of_address_to_resource(node, 0 , &r);
+ prop = of_get_property(node, "virtual-reg" , NULL);
+ if (prop)
+ virt_reg = of_read_number(prop, 1);
+ prop = of_get_property(node, "irq-src", NULL);
+ if (prop)
+ src_mask = of_read_number(prop, 1);
+ vic_init((void __iomem __force *) virt_reg, VIC_BASE(irq), src_mask, 0);
+ irq++;
+ }
+ of_node_put(node);
+ return err;
+}
+
+void __init s5p_dt_init_irq(void)
+{
+
+ /* initialize the VICs */
+ s5p_dt_vic_init();
+ s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
+ s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
+ s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
+ s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
+ s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
+
+ s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
--
1.7.2
More information about the devicetree-discuss
mailing list