diff mbox series

[RFC,03/12] of: base: record root node in interator and use it for phandle lookup

Message ID 20210208222203.22335-4-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
For detached oftree support, find the root node and record it, on iterator
creation. If we find the root of the global oftree, record NULL, in order to
have a clear distinction between detached and non-detached cases. The recorded
root node is then used for resolving phandles.

Note that in the detached case, phandle cache can't be used, so we have a
little performance penalty on repeated phandle lookups.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
---
 drivers/of/base.c  | 13 ++++++++++++-
 include/linux/of.h |  1 +
 2 files changed, 13 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6b3d1e817808..e5ef611ed233 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1249,6 +1249,7 @@  int of_phandle_iterator_init(struct of_phandle_iterator *it,
 {
 	const __be32 *list;
 	int size;
+	struct device_node *walk;
 
 	memset(it, 0, sizeof(*it));
 
@@ -1270,6 +1271,16 @@  int of_phandle_iterator_init(struct of_phandle_iterator *it,
 	it->phandle_end = list;
 	it->cur = list;
 
+	/*
+	 * find the root of our tree and record it, if we're dealing with an
+	 * detached oftree - in non-detached case, we record NULL, for clear
+	 * distinction between these two cases.
+	 */
+	for (walk=(struct device_node*)np;
+	     walk->parent;
+	     walk=(struct device_node*)walk->parent);
+	it->root = ((walk == of_root) ? NULL : walk);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_phandle_iterator_init);
@@ -1297,7 +1308,7 @@  int of_phandle_iterator_next(struct of_phandle_iterator *it)
 		 * Find the provider node and parse the #*-cells property to
 		 * determine the argument length.
 		 */
-		it->node = of_find_node_by_phandle(it->phandle);
+		it->node = of_find_node_by_phandle_from(it->root, it->phandle);
 
 		if (it->cells_name) {
 			if (!it->node) {
diff --git a/include/linux/of.h b/include/linux/of.h
index c285141653e5..dbf2c7442389 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -82,6 +82,7 @@  struct of_phandle_iterator {
 	const char *cells_name;
 	int cell_count;
 	const struct device_node *parent;
+	struct device_node *root;
 
 	/* List size information */
 	const __be32 *list_end;