On Thu Jun 25 11:33:02 2026 +0300, Svyatoslav Ryhel wrote:
> The existing tegra_vi_graph_build function relies heavily on a one-to-one
> match between Device Tree nodes and media pad links. While this works for
> simpler configurations, it causes issues when Device Tree nodes do not
> match media pad link logic (e.g., mt9m114). Switch to the
> media_entity_get_fwnode_pad helper to verify and retrieve the correct pad
> linked to an endpoint, rather than assuming the endpoint ID matches the
> pad ID.
>
> Tested-by: Luca Ceresoli <[email protected]> # tegra20, parallel
> camera
> Signed-off-by: Svyatoslav Ryhel <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/staging/media/tegra-video/vi.c | 78 +++++++++++++++-------------------
1 file changed, 35 insertions(+), 43 deletions(-)
---
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;
+ }
+
+ 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[link.remote_port];
+ 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;
}
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]