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@xxxxxxxxxxxxxx> --- 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