[RFC PATCH 02/12] of: base: introduce of_find_node_by_phandle_from()

From: Enrico Weigelt, metux IT consult
Date: Mon Feb 08 2021 - 17:24:58 EST


Introducing a variant of of_find_node_by_phandle() that starts off a
different root node. This root can also point to an detached oftree,
which has no relations to primary oftree, even on platforms that natively
don't have oftree at all (eg. ACPI platforms).

Note that this has nothing to do with oftree overlays.

Signed-off-by: Enrico Weigelt, metux IT consult <info@xxxxxxxxx>
---
drivers/of/base.c | 14 +++++++++-----
include/linux/of.h | 7 ++++++-
2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 8a348f0d3c5e..6b3d1e817808 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1187,13 +1187,15 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
EXPORT_SYMBOL_GPL(of_modalias_node);

/**
- * of_find_node_by_phandle - Find a node given a phandle
+ * of_find_node_by_phandle_from - Find a node given a phandle
+ * @root: root of the tree (on NULL default to of_root)
* @handle: phandle of the node to find
*
* Returns a node pointer with refcount incremented, use
* of_node_put() on it when done.
*/
-struct device_node *of_find_node_by_phandle(phandle handle)
+struct device_node *of_find_node_by_phandle_from(struct device_node *root,
+ phandle handle)
{
struct device_node *np = NULL;
unsigned long flags;
@@ -1211,19 +1213,21 @@ struct device_node *of_find_node_by_phandle(phandle handle)
np = phandle_cache[handle_hash];

if (!np) {
- for_each_of_allnodes(np)
+ for_each_of_allnodes_from(root, np) {
if (np->phandle == handle &&
!of_node_check_flag(np, OF_DETACHED)) {
- phandle_cache[handle_hash] = np;
+ if (!root)
+ phandle_cache[handle_hash] = np;
break;
}
+ }
}

of_node_get(np);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return np;
}
-EXPORT_SYMBOL(of_find_node_by_phandle);
+EXPORT_SYMBOL(of_find_node_by_phandle_from);

void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
{
diff --git a/include/linux/of.h b/include/linux/of.h
index 4b27c9a27df3..c285141653e5 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -282,7 +282,12 @@ static inline struct device_node *of_find_node_by_path(const char *path)
return of_find_node_opts_by_path(path, NULL);
}

-extern struct device_node *of_find_node_by_phandle(phandle handle);
+extern struct device_node *of_find_node_by_phandle_from(
+ struct device_node* root, phandle handle);
+static inline struct device_node *of_find_node_by_phandle(phandle handle)
+{
+ return of_find_node_by_phandle_from(NULL, handle);
+}
extern struct device_node *of_get_parent(const struct device_node *node);
extern struct device_node *of_get_next_parent(struct device_node *node);
extern struct device_node *of_get_next_child(const struct device_node *node,
--
2.11.0