dm: core: Respect drivers with the DM_FLAG_PRE_RELOC flag in lists_bind_fdt()
authorBin Meng <bmeng.cn@gmail.com>
Thu, 11 Oct 2018 05:06:58 +0000 (22:06 -0700)
committerSimon Glass <sjg@chromium.org>
Wed, 14 Nov 2018 17:16:27 +0000 (09:16 -0800)
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@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Squashed in http://patchwork.ozlabs.org/patch/996473/ :
Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/core/device.c
drivers/core/lists.c
drivers/core/root.c
drivers/misc/imx8/scu.c
drivers/serial/serial-uclass.c
drivers/timer/timer-uclass.c
include/dm/lists.h

index 5176aa3f866f49a422a0dba715237144ad5039cd..47a697f3e5c3fa0329816db779bcf67129742431 100644 (file)
@@ -834,5 +834,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);
 }
index a1677269d8d657279c219cf046905bd389a52bca..a1f828463ecd615ba1e9175fc68cabd35543615a 100644 (file)
@@ -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);
index b54bf5bcdc5937352f81a950238d7cd85defaaa1..cd6a5a0276a7db089fcaf88d85240f228f7f60d4 100644 (file)
@@ -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);
@@ -282,14 +280,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", node_name, ret);
index 0647ddf10321594624e14232f9b53fbca8dbbd62..b824ac79e6ddb53ed33e561f9a13645eae61c519 100644 (file)
@@ -223,7 +223,7 @@ static int imx8_scu_bind(struct udevice *dev)
        if (node < 0)
                panic("No clk node found\n");
 
-       ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child);
+       ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child, true);
        if (ret)
                return ret;
 
@@ -234,7 +234,7 @@ static int imx8_scu_bind(struct udevice *dev)
        if (node < 0)
                panic("No iomuxc node found\n");
 
-       ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child);
+       ret = lists_bind_fdt(dev, offset_to_ofnode(node), &child, true);
        if (ret)
                return ret;
 
index 665cca85cb5683f024cba340ab96d6742075fd4b..3ded62732d4b21324cd981153b71aee22a99a496 100644 (file)
@@ -62,7 +62,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;
        }
index fe73f71819914c948e3bcac65d90e49b321f825c..12ee6eb80434130eeeada1a9739e027b8d3580f1 100644 (file)
@@ -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;
index 13d1516a121934ca280fdba32ee772248ab4e3fc..59094d78fc3a5a2a9e3bb996435c2fb4845f090c 100644 (file)
@@ -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