From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 39af728649b05e88a2b40e714feeee6451c3f18e ]
The 'parent' returned by fwnode_graph_get_port_parent() with refcount incremented when 'prev' is not NULL, it needs be put when finish using it.
Because the parent is const, introduce a new variable to store the returned fwnode, then put it before returning from fwnode_graph_get_next_endpoint().
Fixes: b5b41ab6b0c1 ("device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Reviewed-and-tested-by: Daniel Scally djrscally@gmail.com Link: https://lore.kernel.org/r/20221123022542.2999510-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/property.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c index 735a23db1b5e..17a648d64356 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -1055,26 +1055,32 @@ struct fwnode_handle * fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, struct fwnode_handle *prev) { + struct fwnode_handle *ep, *port_parent = NULL; const struct fwnode_handle *parent; - struct fwnode_handle *ep;
/* * If this function is in a loop and the previous iteration returned * an endpoint from fwnode->secondary, then we need to use the secondary * as parent rather than @fwnode. */ - if (prev) - parent = fwnode_graph_get_port_parent(prev); - else + if (prev) { + port_parent = fwnode_graph_get_port_parent(prev); + parent = port_parent; + } else { parent = fwnode; + } if (IS_ERR_OR_NULL(parent)) return NULL;
ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); if (ep) - return ep; + goto out_put_port_parent; + + ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
- return fwnode_graph_get_next_endpoint(parent->secondary, NULL); +out_put_port_parent: + fwnode_handle_put(port_parent); + return ep; } EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);