diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index 456134a9e8cf..ce09949178f6 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -1468,7 +1468,6 @@ static int tegra_vi_graph_build(struct tegra_vi_channel *chan, struct tegra_vi *vi = chan->vi; struct tegra_vi_graph_entity *ent; struct fwnode_handle *ep = NULL; - struct v4l2_fwnode_link link; struct media_entity *local = entity->entity; struct media_entity *remote; struct media_pad *local_pad; @@ -1478,70 +1477,64 @@ static int tegra_vi_graph_build(struct tegra_vi_channel *chan, dev_dbg(vi->dev, "creating links for entity %s\n", local->name); - while (1) { - ep = fwnode_graph_get_next_endpoint(entity->asd.match.fwnode, - ep); - if (!ep) - break; + fwnode_graph_for_each_endpoint(entity->asd.match.fwnode, ep) { + struct fwnode_handle *remote_parent __free(fwnode_handle) = NULL; + struct fwnode_handle *sink_ep __free(fwnode_handle) = NULL; + int src_idx, sink_idx; - ret = v4l2_fwnode_parse_link(ep, &link); - if (ret < 0) { - dev_err(vi->dev, "failed to parse link for %pOF: %d\n", - to_of_node(ep), ret); + src_idx = media_entity_get_fwnode_pad(local, ep, + MEDIA_PAD_FL_SOURCE); + if (src_idx < 0) { + dev_dbg(vi->dev, "no source pad found for %pfw\n", ep); continue; } - if (link.local_port >= local->num_pads) { - dev_err(vi->dev, "invalid port number %u on %pOF\n", - link.local_port, to_of_node(link.local_node)); - v4l2_fwnode_put_link(&link); - ret = -EINVAL; - break; + remote_parent = fwnode_graph_get_remote_port_parent(ep); + if (!remote_parent) { + dev_dbg(vi->dev, "no remote parent found for %pfw\n", + ep); + continue; } - local_pad = &local->pads[link.local_port]; + local_pad = &local->pads[src_idx]; /* Remote node is vi node. So use channel video entity and pad * as remote/sink. */ - if (link.remote_node == of_fwnode_handle(vi->dev->of_node)) { + if (remote_parent == of_fwnode_handle(vi->dev->of_node)) { remote = &chan->video.entity; remote_pad = &chan->pad; goto create_link; } - /* - * Skip sink ports, they will be processed from the other end - * of the link. - */ - if (local_pad->flags & MEDIA_PAD_FL_SINK) { - dev_dbg(vi->dev, "skipping sink port %pOF:%u\n", - to_of_node(link.local_node), link.local_port); - v4l2_fwnode_put_link(&link); - continue; - } - /* find the remote entity from notifier list */ ent = tegra_vi_graph_find_entity(&chan->notifier.done_list, - link.remote_node); + remote_parent); if (!ent) { - dev_err(vi->dev, "no entity found for %pOF\n", - to_of_node(link.remote_node)); - v4l2_fwnode_put_link(&link); + fwnode_handle_put(ep); + dev_err(vi->dev, "no entity found for %pfw\n", + remote_parent); ret = -ENODEV; break; } remote = ent->entity; - if (link.remote_port >= remote->num_pads) { - dev_err(vi->dev, "invalid port number %u on %pOF\n", - link.remote_port, - to_of_node(link.remote_node)); - v4l2_fwnode_put_link(&link); - ret = -EINVAL; - break; + + sink_ep = fwnode_graph_get_remote_endpoint(ep); + if (!sink_ep) { + dev_dbg(vi->dev, "no sink ep found for %pfw\n", + ep); + continue; } - remote_pad = &remote->pads[link.remote_port]; + sink_idx = media_entity_get_fwnode_pad(remote, sink_ep, + MEDIA_PAD_FL_SINK); + if (sink_idx < 0) { + dev_dbg(vi->dev, "no sink pad found for %pfw\n", + sink_ep); + continue; + } + + remote_pad = &remote->pads[sink_idx]; create_link: dev_dbg(vi->dev, "creating %s:%u -> %s:%u link\n", @@ -1551,8 +1544,8 @@ create_link: ret = media_create_pad_link(local, local_pad->index, remote, remote_pad->index, link_flags); - v4l2_fwnode_put_link(&link); if (ret < 0) { + fwnode_handle_put(ep); dev_err(vi->dev, "failed to create %s:%u -> %s:%u link: %d\n", local->name, local_pad->index, @@ -1561,7 +1554,6 @@ create_link: } } - fwnode_handle_put(ep); return ret; }