From 3991f42ed2e38aff28ba3c24369bfbd90620bea7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 5 Aug 2017 15:45:54 -0600 Subject: dm: core: Add ofnode_for_each_subnode() Add a convenience macro to iterate over subnodes of a node. Make use of this where appropriate in the code. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include/dm') diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index de2769ed537..79374b8f91a 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -628,4 +628,28 @@ int ofnode_read_resource(ofnode node, uint index, struct resource *res); int ofnode_read_resource_byname(ofnode node, const char *name, struct resource *res); +/** + * ofnode_for_each_subnode() - iterate over all subnodes of a parent + * + * @node: child node (ofnode, lvalue) + * @parent: parent node (ofnode) + * + * This is a wrapper around a for loop and is used like so: + * + * ofnode node; + * + * ofnode_for_each_subnode(node, parent) { + * Use node + * ... + * } + * + * Note that this is implemented as a macro and @node is used as + * iterator in the loop. The parent variable can be a constant or even a + * literal. + */ +#define ofnode_for_each_subnode(node, parent) \ + for (node = ofnode_first_subnode(parent); \ + ofnode_valid(node); \ + node = ofnode_next_subnode(node)) + #endif -- cgit v1.3.1 From e81c98649b7a67d43c5baae407430a242d3b26b9 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 4 Sep 2017 14:55:56 +0200 Subject: dm: core: add clocks node scan Currently, all fixed-clock declared in "clocks" node in device tree can be binded by clk_fixed_rate.c driver only if each of them have the "simple-bus" compatible string. This constraint has been invoked here [1]. This patch offers a solution to avoid adding "simple-bus" compatible string to nodes that are not busses. [1] https://patchwork.ozlabs.org/patch/558837/ Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass --- drivers/core/root.c | 34 ++++++++++++++++++++++++++++++++-- include/dm/root.h | 14 ++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) (limited to 'include/dm') diff --git a/drivers/core/root.c b/drivers/core/root.c index d691d6ff947..757d109e57a 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -312,8 +312,38 @@ int dm_scan_fdt(const void *blob, bool pre_reloc_only) #endif return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); } +#else +static int dm_scan_fdt_node(struct udevice *parent, const void *blob, + int offset, bool pre_reloc_only) +{ + return 0; +} #endif +int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) +{ + int node, ret; + + ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); + if (ret) { + debug("dm_scan_fdt() failed: %d\n", ret); + return ret; + } + + /* bind fixed-clock */ + node = ofnode_to_offset(ofnode_path("/clocks")); + /* if no DT "clocks" node, no need to go further */ + if (node < 0) + return ret; + + ret = dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node, + pre_reloc_only); + if (ret) + debug("dm_scan_fdt_node() failed: %d\n", ret); + + return ret; +} + __weak int dm_scan_other(bool pre_reloc_only) { return 0; @@ -335,9 +365,9 @@ int dm_init_and_scan(bool pre_reloc_only) } if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { - ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); + ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only); if (ret) { - debug("dm_scan_fdt() failed: %d\n", ret); + debug("dm_extended_scan_dt() failed: %d\n", ret); return ret; } } diff --git a/include/dm/root.h b/include/dm/root.h index 50a6011644f..b075eef2c1a 100644 --- a/include/dm/root.h +++ b/include/dm/root.h @@ -55,6 +55,20 @@ int dm_scan_platdata(bool pre_reloc_only); */ int dm_scan_fdt(const void *blob, bool pre_reloc_only); +/** + * dm_extended_scan_fdt() - Scan the device tree and bind drivers + * + * This calls dm_scna_dft() which scans the device tree and creates a driver + * for each node. the top-level subnodes are examined and also all sub-nodes + * of "clocks" node. + * + * @blob: Pointer to device tree blob + * @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_extended_scan_fdt(const void *blob, bool pre_reloc_only); + /** * dm_scan_other() - Scan for other devices * -- cgit v1.3.1