diff mbox series

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

Message ID 20210208222203.22335-3-info@metux.net
State New
Headers show
Series [RFC,01/12] of: base: improve error message in of_phandle_iterator_next() | expand

Commit Message

Enrico Weigelt, metux IT consult Feb. 8, 2021, 10:21 p.m. UTC
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@metux.net>
---
 drivers/of/base.c  | 14 +++++++++-----
 include/linux/of.h |  7 ++++++-
 2 files changed, 15 insertions(+), 6 deletions(-)
diff mbox series

Patch

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,