[U-Boot] [PATCH v2 4/8] dm: core: Respect drivers with the DM_FLAG_PRE_RELOC flag in lists_bind_fdt()

Bin Meng bmeng.cn at gmail.com
Sun Oct 7 10:01:13 UTC 2018


Currently the comments of several APIs (eg: dm_init_and_scan()) say:

@pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC
flag. If false bind all drivers.

The 'Pre-Relocation Support' chapter in doc/driver-model/README.txt
documents the same that both device tree properties and driver flag
are supported.

However the implementation only checks these special device tree
properties without checking the driver flag at all. This updates
lists_bind_fdt() to consider both scenarios.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>

---

Changes in v2:
- rebase on u-boot/master, and fix one build error

 drivers/core/device.c          |  2 +-
 drivers/core/lists.c           |  9 ++++++++-
 drivers/core/root.c            | 12 ++++--------
 drivers/serial/serial-uclass.c |  2 +-
 drivers/timer/timer-uclass.c   |  2 +-
 include/dm/lists.h             |  5 ++++-
 6 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index feed43c..1451689 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -815,5 +815,5 @@ int dev_enable_by_path(const char *path)
 	if (ret)
 		return ret;
 
-	return lists_bind_fdt(parent, node, NULL);
+	return lists_bind_fdt(parent, node, NULL, false);
 }
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index a167726..a1f8284 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -122,7 +122,8 @@ static int driver_check_compatible(const struct udevice_id *of_match,
 	return -ENOENT;
 }
 
-int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp)
+int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
+		   bool pre_reloc_only)
 {
 	struct driver *driver = ll_entry_start(struct driver, driver);
 	const int n_ents = ll_entry_count(struct driver, driver);
@@ -171,6 +172,12 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp)
 		if (entry == driver + n_ents)
 			continue;
 
+		if (pre_reloc_only) {
+			if (!dm_ofnode_pre_reloc(node) &&
+			    !(entry->flags & DM_FLAG_PRE_RELOC))
+				return 0;
+		}
+
 		pr_debug("   - found match at '%s'\n", entry->name);
 		ret = device_bind_with_driver_data(parent, entry, name,
 						   id->data, node, &dev);
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 47d10b8..f918ee1 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -222,14 +222,12 @@ static int dm_scan_fdt_live(struct udevice *parent,
 	int ret = 0, err;
 
 	for (np = node_parent->child; np; np = np->sibling) {
-		if (pre_reloc_only &&
-		    !of_find_property(np, "u-boot,dm-pre-reloc", NULL))
-			continue;
 		if (!of_device_is_available(np)) {
 			pr_debug("   - ignoring disabled device\n");
 			continue;
 		}
-		err = lists_bind_fdt(parent, np_to_ofnode(np), NULL);
+		err = lists_bind_fdt(parent, np_to_ofnode(np), NULL,
+				     pre_reloc_only);
 		if (err && !ret) {
 			ret = err;
 			debug("%s: ret=%d\n", np->name, ret);
@@ -276,14 +274,12 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob,
 			continue;
 		}
 
-		if (pre_reloc_only &&
-		    !dm_fdt_pre_reloc(blob, offset))
-			continue;
 		if (!fdtdec_get_is_enabled(blob, offset)) {
 			pr_debug("   - ignoring disabled device\n");
 			continue;
 		}
-		err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL);
+		err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL,
+				     pre_reloc_only);
 		if (err && !ret) {
 			ret = err;
 			debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL),
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index ffdcae0..cc11474 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -61,7 +61,7 @@ static int serial_check_stdout(const void *blob, struct udevice **devp)
 	 * anyway.
 	 */
 	if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
-					devp)) {
+					devp, false)) {
 		if (!device_probe(*devp))
 			return 0;
 	}
diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c
index fe73f71..12ee6eb 100644
--- a/drivers/timer/timer-uclass.c
+++ b/drivers/timer/timer-uclass.c
@@ -108,7 +108,7 @@ int notrace dm_timer_init(void)
 		 * If the timer is not marked to be bound before
 		 * relocation, bind it anyway.
 		 */
-		if (!lists_bind_fdt(dm_root(), node, &dev)) {
+		if (!lists_bind_fdt(dm_root(), node, &dev, false)) {
 			ret = device_probe(dev);
 			if (ret)
 				return ret;
diff --git a/include/dm/lists.h b/include/dm/lists.h
index 13d1516..59094d7 100644
--- a/include/dm/lists.h
+++ b/include/dm/lists.h
@@ -53,10 +53,13 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
  * @parent: parent device (root)
  * @node: device tree node to bind
  * @devp: if non-NULL, returns a pointer to the bound device
+ * @pre_reloc_only: If true, bind only nodes with special devicetree properties,
+ * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
  * @return 0 if device was bound, -EINVAL if the device tree is invalid,
  * other -ve value on error
  */
-int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp);
+int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
+		   bool pre_reloc_only);
 
 /**
  * device_bind_driver() - bind a device to a driver
-- 
2.7.4



More information about the U-Boot mailing list