[U-Boot] [PATCH v3 09/29] dm: Support driver model prior to relocation

Simon Glass sjg at chromium.org
Wed Jul 23 14:55:04 CEST 2014


Initialise devices marked 'pre-reloc' and make them available prior to
relocation. Note that this requires pre-reloc malloc() to be available.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v3: None
Changes in v2:
- Minor reword to comment for dm_init_and_scan()

 common/board_f.c                  | 16 ++++++++++++++++
 common/board_r.c                  | 25 ++++---------------------
 drivers/core/root.c               | 25 +++++++++++++++++++++++++
 include/asm-generic/global_data.h |  3 ++-
 include/dm/root.h                 | 13 +++++++++++++
 5 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index b5e2031..8782c43 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -14,6 +14,7 @@
 #include <linux/compiler.h>
 #include <version.h>
 #include <environment.h>
+#include <dm.h>
 #include <fdtdec.h>
 #include <fs.h>
 #if defined(CONFIG_CMD_IDE)
@@ -52,6 +53,7 @@
 #ifdef CONFIG_SANDBOX
 #include <asm/state.h>
 #endif
+#include <dm/root.h>
 #include <linux/compiler.h>
 
 /*
@@ -787,6 +789,19 @@ static int initf_malloc(void)
 	return 0;
 }
 
+static int initf_dm(void)
+{
+#if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN)
+	int ret;
+
+	ret = dm_init_and_scan(true);
+	if (ret)
+		return ret;
+#endif
+
+	return 0;
+}
+
 static init_fnc_t init_sequence_f[] = {
 #ifdef CONFIG_SANDBOX
 	setup_ram_buf,
@@ -845,6 +860,7 @@ static init_fnc_t init_sequence_f[] = {
 	init_timebase,
 #endif
 	initf_malloc,
+	initf_dm,
 	init_baud_rate,		/* initialze baudrate settings */
 	serial_init,		/* serial communications setup */
 	console_init_f,		/* stage 1 init of console */
diff --git a/common/board_r.c b/common/board_r.c
index e43a318..a35ffa5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -273,27 +273,10 @@ static int initr_malloc(void)
 #ifdef CONFIG_DM
 static int initr_dm(void)
 {
-	int ret;
-
-	ret = dm_init();
-	if (ret) {
-		debug("dm_init() failed: %d\n", ret);
-		return ret;
-	}
-	ret = dm_scan_platdata(false);
-	if (ret) {
-		debug("dm_scan_platdata() failed: %d\n", ret);
-		return ret;
-	}
-#ifdef CONFIG_OF_CONTROL
-	ret = dm_scan_fdt(gd->fdt_blob, false);
-	if (ret) {
-		debug("dm_scan_fdt() failed: %d\n", ret);
-		return ret;
-	}
-#endif
-
-	return 0;
+	/* Save the pre-reloc driver model and start a new one */
+	gd->dm_root_f = gd->dm_root;
+	gd->dm_root = NULL;
+	return dm_init_and_scan(false);
 }
 #endif
 
diff --git a/drivers/core/root.c b/drivers/core/root.c
index b76c10d..c37d666 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -104,6 +104,31 @@ int dm_scan_fdt(const void *blob, bool pre_reloc_only)
 }
 #endif
 
+int dm_init_and_scan(bool pre_reloc_only)
+{
+	int ret;
+
+	ret = dm_init();
+	if (ret) {
+		debug("dm_init() failed: %d\n", ret);
+		return ret;
+	}
+	ret = dm_scan_platdata(pre_reloc_only);
+	if (ret) {
+		debug("dm_scan_platdata() failed: %d\n", ret);
+		return ret;
+	}
+#ifdef CONFIG_OF_CONTROL
+	ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only);
+	if (ret) {
+		debug("dm_scan_fdt() failed: %d\n", ret);
+		return ret;
+	}
+#endif
+
+	return 0;
+}
+
 /* This is the root driver - all drivers are children of this */
 U_BOOT_DRIVER(root_driver) = {
 	.name	= "root_driver",
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index f6a2a20..edde9d7 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -65,7 +65,8 @@ typedef struct global_data {
 	struct global_data *new_gd;	/* relocated global data */
 
 #ifdef CONFIG_DM
-	struct udevice	*dm_root;/* Root instance for Driver Model */
+	struct udevice	*dm_root;	/* Root instance for Driver Model */
+	struct udevice	*dm_root_f;	/* Pre-relocation root instance */
 	struct list_head uclass_root;	/* Head of core tree */
 #endif
 
diff --git a/include/dm/root.h b/include/dm/root.h
index d37b452..09f9303 100644
--- a/include/dm/root.h
+++ b/include/dm/root.h
@@ -45,6 +45,19 @@ int dm_scan_platdata(bool pre_reloc_only);
 int dm_scan_fdt(const void *blob, bool pre_reloc_only);
 
 /**
+ * dm_init_and_scan() - Initialise Driver Model structures and scan for devices
+ *
+ * This function initialises the roots of the driver tree and uclass trees,
+ * then scans and binds available devices from platform data and the FDT.
+ * This calls dm_init() to set up Driver Model structures.
+ *
+ * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC
+ * flag. If false bind all drivers.
+ * @return 0 if OK, -ve on error
+ */
+int dm_init_and_scan(bool pre_reloc_only);
+
+/**
  * dm_init() - Initialise Driver Model structures
  *
  * This function will initialize roots of driver tree and class tree.
-- 
2.0.0.526.g5318336



More information about the U-Boot mailing list