diff options
author | Michael Tretter <m.tretter@pengutronix.de> | 2019-09-13 15:14:41 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-09-16 09:06:18 +0200 |
commit | ca7b8f85f0d9455b631461288535a3cef7e58fdf (patch) | |
tree | 52dbfabd218296e0d7c76389a1339f387e8cb5ec | |
parent | da2c36c0a911992d80448f9afa5acc9d70871ed0 (diff) | |
download | barebox-ca7b8f85f0d9455b631461288535a3cef7e58fdf.tar.gz barebox-ca7b8f85f0d9455b631461288535a3cef7e58fdf.tar.xz |
of: add iterator for overlays
Device tree overlays (the dto files) may contain multiple fragments for
different target nodes. Each fragment contains a __overlay__ node that
is applied to target node specified in the fragment.
Add a helper to call a function for each fragment in a device tree
overlay to avoid having device tree overlay internal information in
other modules.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | drivers/of/overlay.c | 38 | ||||
-rw-r--r-- | include/of.h | 13 |
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index f6a0576183..de79e05cbc 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -195,6 +195,44 @@ static int of_overlay_fixup(struct device_node *root, void *data) } /** + * Iterate the overlay and call process for each fragment + * + * If process() fails for any fragment, the function will stop to process + * other fragments and return the error of the failed process() call. + */ +int of_process_overlay(struct device_node *root, + struct device_node *overlay, + int (*process)(struct device_node *target, + struct device_node *overlay, void *data), + void *data) +{ + struct device_node *fragment; + int err = 0; + + for_each_child_of_node(overlay, fragment) { + struct device_node *ovl; + struct device_node *target; + + ovl = of_get_child_by_name(fragment, "__overlay__"); + if (!ovl) + continue; + + target = find_target(root, fragment); + if (!target) + continue; + + err = process(target, ovl, data); + if (err) { + pr_warn("failed to process overlay for %s\n", + target->name); + break; + } + } + + return err; +} + +/** * Register a devicetree overlay * * The overlay is not applied to the live device tree, but registered as fixup diff --git a/include/of.h b/include/of.h index 1483c22db1..06dc9f61a5 100644 --- a/include/of.h +++ b/include/of.h @@ -877,6 +877,11 @@ struct device_node *of_resolve_phandles(struct device_node *root, int of_overlay_apply_tree(struct device_node *root, struct device_node *overlay); int of_register_overlay(struct device_node *overlay); +int of_process_overlay(struct device_node *root, + struct device_node *overlay, + int (*process)(struct device_node *target, + struct device_node *overlay, void *data), + void *data); #else static inline struct device_node *of_resolve_phandles(struct device_node *root, const struct device_node *overlay) @@ -895,6 +900,14 @@ static inline int of_register_overlay(struct device_node *overlay) return -ENOSYS; } +static inline int of_process_overlay(struct device_node *root, + struct device_node *overlay, + int (*process)(struct device_node *target, + struct device_node *overlay, void *data), + void *data) +{ + return -ENOSYS; +} #endif #endif /* __OF_H */ |