summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2017-02-03 12:39:03 -0600
committerMax Krummenacher <max.krummenacher@toradex.com>2018-11-08 20:10:09 +0100
commit1dbfa5a417cacf05208025a43dbe0cf25d516e61 (patch)
treeb6062fb213f4b5dedc7b18346961f416d9c37949
parentee3e12170c924d5406a257b9e2cbe22d6e644586 (diff)
of: introduce of_graph_get_remote_node
The OF graph API leaves too much of the graph walking to clients when in many cases the driver doesn't care about accessing the port or endpoint nodes. The drivers typically just want the device connected via a particular graph connection. of_graph_get_remote_node provides this functionality. Signed-off-by: Rob Herring <robh@kernel.org> Acked-by: Philipp Zabel <p.zabel@pengutronix.de> (cherry picked from commit b85ad494098bf881c3713218fbd74193e5d5c488)
-rw-r--r--drivers/of/base.c37
-rw-r--r--include/linux/of_graph.h8
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 36f6bb39de5b..24a38cbacb4c 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2496,3 +2496,40 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
return of_get_next_parent(np);
}
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 %s\n",
+ port, endpoint, node->full_name);
+ 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");
+ return NULL;
+ }
+
+ return remote;
+}
+EXPORT_SYMBOL(of_graph_get_remote_node);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index bb3a5a2cd570..abdb02eaef06 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs(
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);
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+ u32 port, u32 endpoint);
#else
static inline int of_graph_parse_endpoint(const struct device_node *node,
@@ -89,6 +91,12 @@ static inline struct device_node *of_graph_get_remote_port(
{
return NULL;
}
+static inline struct device_node *of_graph_get_remote_node(
+ const struct device_node *node,
+ u32 port, u32 endpoint)
+{
+ return NULL;
+}
#endif /* CONFIG_OF */