mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/5] of-graph fixes
@ 2024-09-25 14:01 Sascha Hauer
  2024-09-25 14:01 ` [PATCH 1/5] of: fix of_get_next_child() for prev->parent != node Sascha Hauer
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-25 14:01 UTC (permalink / raw)
  To: open list:BAREBOX

Upcoming Rockchip VOP2 support makes use of of-graph which uncovered
some bugs in the existing code. This series contains fixes for it and
adds some missing functions.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Sascha Hauer (5):
      of: fix of_get_next_child() for prev->parent != node
      of: fix of_graph_get_next_endpoint()
      of: of_graph: honour ports subnode
      of: of_graph: fix of_graph_get_next_endpoint()
      of: of_graph: add missing functions

 drivers/of/base.c  | 104 +++++++++++++++++++++++++++++++++++++++++++++++++----
 include/of.h       |   8 +++++
 include/of_graph.h |   4 +++
 3 files changed, 110 insertions(+), 6 deletions(-)
---
base-commit: 419ea9350aa083d4a2806a70132129a49a5ecf95
change-id: 20240925-of-graph-fixes-1af3afb8595b

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] of: fix of_get_next_child() for prev->parent != node
  2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
@ 2024-09-25 14:01 ` Sascha Hauer
  2024-09-25 14:01 ` [PATCH 2/5] of: fix of_graph_get_next_endpoint() Sascha Hauer
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-25 14:01 UTC (permalink / raw)
  To: open list:BAREBOX

of_get_next_child() is supposed to return the next sibling of 'prev' and
the function does exactly that. It expects that 'node' is always the
same parent node. of_graph_get_next_endpoint() breaks this expectation,
it walks further down the tree and then calls of_get_next_child() with
'node' being some subnode of the original node. Fix this by retrieving
'node' always from 'prev' and use 'node' only on initial entry when
'prev' is NULL.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 62d84786ae..6fd69e7d7d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2054,6 +2054,9 @@ EXPORT_SYMBOL(of_get_next_available_child);
 struct device_node *of_get_next_child(const struct device_node *node,
 	struct device_node *prev)
 {
+	if (prev)
+		node = prev->parent;
+
 	prev = list_prepare_entry(prev, &node->children, parent_list);
 	list_for_each_entry_continue(prev, &node->children, parent_list)
 		return prev;

-- 
2.39.5




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/5] of: fix of_graph_get_next_endpoint()
  2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
  2024-09-25 14:01 ` [PATCH 1/5] of: fix of_get_next_child() for prev->parent != node Sascha Hauer
@ 2024-09-25 14:01 ` Sascha Hauer
  2024-09-25 14:01 ` [PATCH 3/5] of: of_graph: honour ports subnode Sascha Hauer
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-25 14:01 UTC (permalink / raw)
  To: open list:BAREBOX

of_get_child_by_name() behaves differently than the corresponding Linux
function. The barebox version matches the full name of the node whereas
the Linux version skips the part after the '@' in the node.

of_graph_get_next_endpoint() explicitly needs the Linux behaviour.

As of_get_child_by_name() is heavily used in barebox and some call sites
might depend on the different behaviour, do not alter
of_get_child_by_name(), but instead introduce a new function that has
the Linux behaviour and use that in of_graph_get_next_endpoint().

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 26 ++++++++++++++++++++++++--
 include/of.h      |  8 ++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6fd69e7d7d..fbbc3316fc 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2139,7 +2139,7 @@ EXPORT_SYMBOL(of_get_compatible_child);
  *	@node:	parent node
  *	@name:	child name to look for.
  *
- *      This function looks for child node for given matching name
+ *      This function looks for child node for given matching full name
  *
  *	Returns a node pointer if found or NULL.
  */
@@ -2156,6 +2156,28 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
 }
 EXPORT_SYMBOL(of_get_child_by_name);
 
+/**
+ *	of_get_child_by_name_stem - Find the child node by name for a given parent
+ *	@node:	parent node
+ *	@name:	child name to look for.
+ *
+ *      This function looks for child node for given matching name excluding the
+ *      unit address
+ *
+ *	Returns a node pointer if found or NULL.
+ */
+struct device_node *of_get_child_by_name_stem(const struct device_node *node,
+				const char *name)
+{
+	struct device_node *child;
+
+	for_each_child_of_node(node, child)
+		if (of_node_name_eq(child, name))
+			break;
+	return child;
+}
+EXPORT_SYMBOL(of_get_child_by_name_stem);
+
 /**
  * of_property_read_string_helper() - Utility helper for parsing string properties
  * @np:		device node from which the property value is to be read.
@@ -3296,7 +3318,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 		if (node)
 			parent = node;
 
-		port = of_get_child_by_name(parent, "port");
+		port = of_get_child_by_name_stem(parent, "port");
 		if (!port) {
 			pr_err("%s(): no port node found in %pOF\n",
 			       __func__, parent);
diff --git a/include/of.h b/include/of.h
index 55f2c0cbde..05e92d41b9 100644
--- a/include/of.h
+++ b/include/of.h
@@ -218,6 +218,8 @@ extern struct device_node *of_get_compatible_child(const struct device_node *par
 					const char *compatible);
 extern struct device_node *of_get_child_by_name(const struct device_node *node,
 					const char *name);
+extern struct device_node *of_get_child_by_name_stem(const struct device_node *node,
+					const char *name);
 extern char *of_get_reproducible_name(struct device_node *node);
 extern struct device_node *of_get_node_by_reproducible_name(struct device_node *dstroot,
 							    struct device_node *srcnp);
@@ -560,6 +562,12 @@ static inline struct device_node *of_get_child_by_name(
 	return NULL;
 }
 
+static inline struct device_node *of_get_child_by_name_stem(
+			const struct device_node *node, const char *name)
+{
+	return NULL;
+}
+
 static inline char *of_get_reproducible_name(struct device_node *node)
 {
 	return NULL;

-- 
2.39.5




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/5] of: of_graph: honour ports subnode
  2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
  2024-09-25 14:01 ` [PATCH 1/5] of: fix of_get_next_child() for prev->parent != node Sascha Hauer
  2024-09-25 14:01 ` [PATCH 2/5] of: fix of_graph_get_next_endpoint() Sascha Hauer
@ 2024-09-25 14:01 ` Sascha Hauer
  2024-09-25 14:01 ` [PATCH 4/5] of: of_graph: fix of_graph_get_next_endpoint() Sascha Hauer
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-25 14:01 UTC (permalink / raw)
  To: open list:BAREBOX

The of_graph ports of a node nowadays are usually collected under a
'ports' subnode instead of being directly under the devices node.
Handle this case correctly.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index fbbc3316fc..398e39340f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -3271,11 +3271,14 @@ EXPORT_SYMBOL(of_graph_parse_endpoint);
  *
  * Return: A 'port' node pointer with refcount incremented.
  */
-struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id)
+struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
 {
-	struct device_node *port;
+	struct device_node *port, *node = of_get_child_by_name(parent, "ports");
+
+	if (node)
+		parent = node;
 
-	for_each_child_of_node(node, port) {
+	for_each_child_of_node(parent, port) {
 		u32 port_id = 0;
 
 		if (strncmp(port->name, "port", 4) != 0)

-- 
2.39.5




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/5] of: of_graph: fix of_graph_get_next_endpoint()
  2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
                   ` (2 preceding siblings ...)
  2024-09-25 14:01 ` [PATCH 3/5] of: of_graph: honour ports subnode Sascha Hauer
@ 2024-09-25 14:01 ` Sascha Hauer
  2024-09-25 14:01 ` [PATCH 5/5] of: of_graph: add missing functions Sascha Hauer
  2024-09-27 10:39 ` [PATCH 0/5] of-graph fixes Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-25 14:01 UTC (permalink / raw)
  To: open list:BAREBOX

of_node_cmp() compares the whole node name for matching whereas
of_node_name_eq() only compares the part before the '@' sign. For
of_graph_get_next_endpoint() we need the latter. Fix this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 398e39340f..5981650f2a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -3353,7 +3353,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 			port = of_get_next_child(parent, port);
 			if (!port)
 				return NULL;
-		} while (of_node_cmp(port->name, "port"));
+		} while (port->name && !of_node_name_eq(port, "port"));
 	}
 }
 EXPORT_SYMBOL(of_graph_get_next_endpoint);

-- 
2.39.5




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/5] of: of_graph: add missing functions
  2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
                   ` (3 preceding siblings ...)
  2024-09-25 14:01 ` [PATCH 4/5] of: of_graph: fix of_graph_get_next_endpoint() Sascha Hauer
@ 2024-09-25 14:01 ` Sascha Hauer
  2024-09-27 10:39 ` [PATCH 0/5] of-graph fixes Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-25 14:01 UTC (permalink / raw)
  To: open list:BAREBOX

This adds of_graph_get_endpoint_by_regs() and of_graph_get_remote_node()
as-is from Linux.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c  | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/of_graph.h |  4 ++++
 2 files changed, 68 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 5981650f2a..960a9327ae 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -3358,6 +3358,32 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
 }
 EXPORT_SYMBOL(of_graph_get_next_endpoint);
 
+/**
+ * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers
+ * @parent: pointer to the parent device node
+ * @port_reg: identifier (value of reg property) of the parent port node
+ * @reg: identifier (value of reg property) of the endpoint node
+ *
+ * Return: An 'endpoint' node pointer which is identified by reg and at the same
+ * is the child of a port node identified by port_reg. reg and port_reg are
+ * ignored when they are -1. Use of_node_put() on the pointer when done.
+ */
+struct device_node *of_graph_get_endpoint_by_regs(
+	const struct device_node *parent, int port_reg, int reg)
+{
+	struct of_endpoint endpoint;
+	struct device_node *node = NULL;
+
+	for_each_endpoint_of_node(parent, node) {
+		of_graph_parse_endpoint(node, &endpoint);
+		if (((port_reg == -1) || (endpoint.port == port_reg)) &&
+			((reg == -1) || (endpoint.id == reg)))
+			return node;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
+
 /**
  * of_graph_get_remote_port_parent() - get remote port's parent node
  * @node: pointer to a local endpoint device_node
@@ -3403,6 +3429,44 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
 }
 EXPORT_SYMBOL(of_graph_get_remote_port);
 
+/**
+ * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
+ * @node: pointer to parent device_node containing graph port/endpoint
+ * @port: identifier (value of reg property) of the parent port node
+ * @endpoint: identifier (value of reg property) of the endpoint node
+ *
+ * Return: Remote device node associated with remote endpoint node linked
+ * to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+					     u32 port, u32 endpoint)
+{
+	struct device_node *endpoint_node, *remote;
+
+	endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
+	if (!endpoint_node) {
+		pr_debug("no valid endpoint (%d, %d) for node %pOF\n",
+			 port, endpoint, node);
+		return NULL;
+	}
+
+	remote = of_graph_get_remote_port_parent(endpoint_node);
+	of_node_put(endpoint_node);
+	if (!remote) {
+		pr_debug("no valid remote node\n");
+		return NULL;
+	}
+
+	if (!of_device_is_available(remote)) {
+		pr_debug("not available for remote node\n");
+		of_node_put(remote);
+		return NULL;
+	}
+
+	return remote;
+}
+EXPORT_SYMBOL(of_graph_get_remote_node);
+
 int of_graph_port_is_available(struct device_node *node)
 {
 	struct device_node *endpoint;
diff --git a/include/of_graph.h b/include/of_graph.h
index ef3fb8b94a..bd25643e25 100644
--- a/include/of_graph.h
+++ b/include/of_graph.h
@@ -43,5 +43,9 @@ struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node);
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
 int of_graph_port_is_available(struct device_node *node);
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+					     u32 port, u32 endpoint);
+struct device_node *of_graph_get_endpoint_by_regs(
+	const struct device_node *parent, int port_reg, int reg);
 
 #endif /* __LINUX_OF_GRAPH_H */

-- 
2.39.5




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] of-graph fixes
  2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
                   ` (4 preceding siblings ...)
  2024-09-25 14:01 ` [PATCH 5/5] of: of_graph: add missing functions Sascha Hauer
@ 2024-09-27 10:39 ` Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2024-09-27 10:39 UTC (permalink / raw)
  To: open list:BAREBOX, Sascha Hauer


On Wed, 25 Sep 2024 16:01:10 +0200, Sascha Hauer wrote:
> Upcoming Rockchip VOP2 support makes use of of-graph which uncovered
> some bugs in the existing code. This series contains fixes for it and
> adds some missing functions.
> 
> 

Applied, thanks!

[1/5] of: fix of_get_next_child() for prev->parent != node
      https://git.pengutronix.de/cgit/barebox/commit/?id=c07ce9b0678c (link may not be stable)
[2/5] of: fix of_graph_get_next_endpoint()
      https://git.pengutronix.de/cgit/barebox/commit/?id=c8c506a779dd (link may not be stable)
[3/5] of: of_graph: honour ports subnode
      https://git.pengutronix.de/cgit/barebox/commit/?id=2a5d0ab7dc64 (link may not be stable)
[4/5] of: of_graph: fix of_graph_get_next_endpoint()
      https://git.pengutronix.de/cgit/barebox/commit/?id=09fb886aa387 (link may not be stable)
[5/5] of: of_graph: add missing functions
      https://git.pengutronix.de/cgit/barebox/commit/?id=52dd0d4c8a75 (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-09-27 10:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-09-25 14:01 [PATCH 0/5] of-graph fixes Sascha Hauer
2024-09-25 14:01 ` [PATCH 1/5] of: fix of_get_next_child() for prev->parent != node Sascha Hauer
2024-09-25 14:01 ` [PATCH 2/5] of: fix of_graph_get_next_endpoint() Sascha Hauer
2024-09-25 14:01 ` [PATCH 3/5] of: of_graph: honour ports subnode Sascha Hauer
2024-09-25 14:01 ` [PATCH 4/5] of: of_graph: fix of_graph_get_next_endpoint() Sascha Hauer
2024-09-25 14:01 ` [PATCH 5/5] of: of_graph: add missing functions Sascha Hauer
2024-09-27 10:39 ` [PATCH 0/5] of-graph fixes Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox