
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.
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 ---
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 ++++- 5 files changed, 18 insertions(+), 12 deletions(-)
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