[PATCH 5/5] ARM: at91: Modify board_dt init sequence

Boris BREZILLON linux-arm at overkiz.com
Sat May 12 04:53:58 EDT 2012


This patch modifies the init sequence defined by board_dt machine.
PMC common clk implementation needs the slab allocator to be up => late_time_init.
GPIO needs the GPIO periph clks => after clk inits.
GPIO irq init needs the GPIO chips => after GPIO inits.


---
 arch/arm/mach-at91/board-dt.c |   72 +++++++++++++++++++++++++++++++++++++++--
 arch/arm/mach-at91/setup.c    |    8 ++---
 2 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index a1fce05..b12d43f 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -22,6 +22,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
+#include <asm/mach/time.h>
 
 #include "generic.h"
 
@@ -29,6 +30,11 @@
 static const struct of_device_id irq_of_match[] __initconst = {
 
 	{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
+	{ /*sentinel*/ }
+};
+
+static const struct of_device_id gpio_irq_of_match[] __initconst = {
+
 	{ .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup },
 	{ .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup },
 	{ /*sentinel*/ }
@@ -49,11 +55,73 @@ static const char *at91_dt_board_compat[] __initdata = {
 	NULL
 };
 
+static void __init at91_dt_late_time_init(void);
+
+static void __init at91_dt_timer_init(void) {
+	late_time_init = at91_dt_late_time_init;
+}
+
+struct sys_timer at91_dt_timer = {
+	.init = at91_dt_timer_init,
+};
+
+extern void __init at91_pmc_of_init(struct device_node *np);
+
+static const struct of_device_id clk_of_match[] __initconst = {
+
+	{ .compatible = "atmel,at91-pmc", .data = at91_pmc_of_init },
+	{ /*sentinel*/ }
+};
+
+static const struct of_device_id timer_of_match[] __initconst = {
+
+	{ .compatible = "atmel,at91sam9260-pit", .data = &at91sam926x_timer },
+	{ /*sentinel*/ }
+};
+
+static void __init at91_dt_late_time_init(void) {
+	struct device_node *np = NULL;
+	const struct of_device_id *match;
+	struct sys_timer *timer;
+	void (*init_fn) (struct device_node *np);
+
+	np = of_find_matching_node(NULL, clk_of_match);
+	if (!np)
+		panic("unable to find compatible clock controller node in dtb\n");
+
+	match = of_match_node(clk_of_match, np);
+	init_fn = match->data;
+	init_fn(np);
+
+	of_node_put(np);
+
+	at91_dt_initialize();
+
+	of_irq_init(gpio_irq_of_match);
+
+	np = of_find_matching_node(NULL, timer_of_match);
+	if (!np)
+		panic("unable to find compatible sys timer node in dtb\n");
+
+	match = of_match_node(timer_of_match, np);
+
+	timer = match->data;
+	timer->init();
+	at91_dt_timer.suspend = timer->suspend;
+	at91_dt_timer.resume = timer->resume;
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+	at91_dt_timer.offset = timer->offset;
+#endif
+
+	of_node_put(np);
+}
+
+
 DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
 	/* Maintainer: Atmel */
-	.timer		= &at91sam926x_timer,
+	.timer		= &at91_dt_timer,
 	.map_io		= at91_map_io,
-	.init_early	= at91_dt_initialize,
+/*	.init_early	= at91_dt_initialize, */
 	.init_irq	= at91_dt_init_irq,
 	.init_machine	= at91_dt_device_init,
 	.dt_compat	= at91_dt_board_compat,
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 97cc04d..ac3ee48 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -435,15 +435,14 @@ void __init at91_dt_initialize(void)
 	at91_dt_shdwc();
 
 	/* Init clock subsystem */
-	at91_dt_clock_init();
+	/*at91_dt_clock_init();*/
 
 	/* Register the processor-specific clocks */
-	at91_boot_soc.register_clocks();
+	/*at91_boot_soc.register_clocks();*/
 
 	at91_boot_soc.init();
 }
-#endif
-
+#else
 void __init at91_initialize(unsigned long main_clock)
 {
 	at91_boot_soc.ioremap_registers();
@@ -456,3 +455,4 @@ void __init at91_initialize(unsigned long main_clock)
 
 	at91_boot_soc.init();
 }
+#endif
-- 
1.7.9.5




More information about the linux-arm-kernel mailing list