diff options
author | Simon Glass <sjg@chromium.org> | 2014-07-23 06:55:18 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-07-23 14:08:36 +0100 |
commit | 1ca7e2062b4e8c3b211753dcb19c063b5b9b73ca (patch) | |
tree | 09873667a133ba84aed32e5b44cfcd08353d1138 /drivers/core | |
parent | 0040b9442947d00a540f6e93742384a14453c37e (diff) |
dm: Provide a function to scan child FDT nodes
At present only root nodes in the device tree are scanned for devices.
But some devices can have children. For example a SPI bus may have
several children for each of its chip selects.
Add a function which scans subnodes and binds devices for each one. This
can be used for the root node scan also, so change it.
A device can call this function in its bind() or probe() methods to bind
its children.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/core')
-rw-r--r-- | drivers/core/root.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/core/root.c b/drivers/core/root.c index 60597563d6..4f9c7e708a 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -80,29 +80,32 @@ int dm_scan_platdata(bool pre_reloc_only) } #ifdef CONFIG_OF_CONTROL -int dm_scan_fdt(const void *blob, bool pre_reloc_only) +int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, + bool pre_reloc_only) { - int offset = 0; int ret = 0, err; - int depth = 0; - - do { - offset = fdt_next_node(blob, offset, &depth); - if (offset > 0 && depth == 1) { - if (pre_reloc_only && - !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) - continue; - err = lists_bind_fdt(gd->dm_root, blob, offset); - if (err && !ret) - ret = err; - } - } while (offset > 0); + + for (offset = fdt_first_subnode(blob, offset); + offset > 0; + offset = fdt_next_subnode(blob, offset)) { + if (pre_reloc_only && + !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) + continue; + err = lists_bind_fdt(parent, blob, offset); + if (err && !ret) + ret = err; + } if (ret) dm_warn("Some drivers failed to bind\n"); return ret; } + +int dm_scan_fdt(const void *blob, bool pre_reloc_only) +{ + return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); +} #endif int dm_init_and_scan(bool pre_reloc_only) |