From c1aa3cab9b3b518b250b298ea5800a692eae0654 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 6 Jun 2017 12:37:40 +0300 Subject: [PATCH] UPSTREAM: device property: Add FW type agnostic fwnode_graph_get_remote_node Add fwnode_graph_get_remote_node() function which is equivalent to of_graph_get_remote_node() on OF. Signed-off-by: Sakari Ailus Reviewed-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki (cherry picked from commit 125ee6b3b0fa920c730b0991e6f083a9f5b1e4c3) Signed-off-by: Brian J Lovin BUG=b:64133998 TEST=media device topology shows subdevs registered successfully TEST=no camera regression Change-Id: Ic450222819fb987342af9170872b91b0044a181f Reviewed-on: https://chromium-review.googlesource.com/693679 Commit-Ready: Tomasz Figa Tested-by: Hyungwoo Yang Reviewed-by: Tomasz Figa Signed-off-by: Jacob Chen --- drivers/base/property.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/property.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/drivers/base/property.c b/drivers/base/property.c index 468efbd97c68..803b878b66f0 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -1142,6 +1142,43 @@ fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode) } EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint); +/** + * fwnode_graph_get_remote_node - get remote parent node for given port/endpoint + * @fwnode: pointer to parent fwnode_handle containing graph port/endpoint + * @port_id: identifier of the parent port node + * @endpoint_id: identifier of the endpoint node + * + * Return: Remote fwnode handle associated with remote endpoint node linked + * to @node. Use fwnode_node_put() on it when done. + */ +struct fwnode_handle *fwnode_graph_get_remote_node(struct fwnode_handle *fwnode, + u32 port_id, u32 endpoint_id) +{ + struct fwnode_handle *endpoint = NULL; + + while ((endpoint = fwnode_graph_get_next_endpoint(fwnode, endpoint))) { + struct fwnode_endpoint fwnode_ep; + struct fwnode_handle *remote; + int ret; + + ret = fwnode_graph_parse_endpoint(endpoint, &fwnode_ep); + if (ret < 0) + continue; + + if (fwnode_ep.port != port_id || fwnode_ep.id != endpoint_id) + continue; + + remote = fwnode_graph_get_remote_port_parent(endpoint); + if (!remote) + return NULL; + + return fwnode_device_is_available(remote) ? remote : NULL; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_node); + /** * fwnode_graph_parse_endpoint - parse common endpoint node properties * @fwnode: pointer to endpoint fwnode_handle diff --git a/include/linux/property.h b/include/linux/property.h index a3a31a923b5f..ba069ae89e87 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -222,6 +222,8 @@ struct fwnode_handle *fwnode_graph_get_remote_port( struct fwnode_handle *fwnode); struct fwnode_handle *fwnode_graph_get_remote_endpoint( struct fwnode_handle *fwnode); +struct fwnode_handle *fwnode_graph_get_remote_node(struct fwnode_handle *fwnode, + u32 port, u32 endpoint); int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode, struct fwnode_endpoint *endpoint);