diff options
| author | Svyatoslav Ryhel <clamor95@gmail.com> | 2026-03-03 11:42:29 +0300 |
|---|---|---|
| committer | Hans Verkuil <hverkuil+cisco@kernel.org> | 2026-03-19 10:18:36 +0300 |
| commit | 6017e97f50f8c9cbdd448b3569bc19152f57cd87 (patch) | |
| tree | 92854e6ee0340ed085c07535dc5c911926c959d6 | |
| parent | c888c4c834c9afc18879fde91ad405be21b7425d (diff) | |
| download | linux-6017e97f50f8c9cbdd448b3569bc19152f57cd87.tar.xz | |
staging: media: tegra-video: vi: improve logic of source requesting
By default tegra_channel_get_remote_csi_subdev returns next device in pipe
assuming it is CSI but in case of Tegra20 and Tegra30 it can also be VIP
or even HOST.
Define tegra_channel_get_remote_csi_subdev within CSI and add check if
returned device is actually CSI by comparing subdevice operations.
Previous tegra_channel_get_remote_csi_subdev definition in VI rename to
tegra_channel_get_remote_bridge_subdev and use it only in VI driver since
core VI driver does not care about source and does not call any specific
functions.
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com> # tegra20, parallel camera
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
| -rw-r--r-- | drivers/staging/media/tegra-video/csi.c | 16 | ||||
| -rw-r--r-- | drivers/staging/media/tegra-video/vi.c | 14 |
2 files changed, 23 insertions, 7 deletions
diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c index bcaea20c3025..92078a1f9a4e 100644 --- a/drivers/staging/media/tegra-video/csi.c +++ b/drivers/staging/media/tegra-video/csi.c @@ -445,6 +445,22 @@ static const struct v4l2_subdev_ops tegra_csi_ops = { .pad = &tegra_csi_pad_ops, }; +struct v4l2_subdev *tegra_channel_get_remote_csi_subdev(struct tegra_vi_channel *chan) +{ + struct media_pad *pad; + struct v4l2_subdev *subdev; + + pad = media_pad_remote_pad_first(&chan->pad); + if (!pad) + return NULL; + + subdev = media_entity_to_v4l2_subdev(pad->entity); + if (!subdev) + return NULL; + + return subdev->ops == &tegra_csi_ops ? subdev : NULL; +} + static int tegra_csi_channel_alloc(struct tegra_csi *csi, struct device_node *node, unsigned int port_num, unsigned int lanes, diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index 19eebfdae221..7032c733577d 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -160,8 +160,8 @@ static void tegra_channel_buffer_queue(struct vb2_buffer *vb) wake_up_interruptible(&chan->start_wait); } -struct v4l2_subdev * -tegra_channel_get_remote_csi_subdev(struct tegra_vi_channel *chan) +static struct v4l2_subdev * +tegra_channel_get_remote_bridge_subdev(struct tegra_vi_channel *chan) { struct media_pad *pad; @@ -182,7 +182,7 @@ tegra_channel_get_remote_source_subdev(struct tegra_vi_channel *chan) struct v4l2_subdev *subdev; struct media_entity *entity; - subdev = tegra_channel_get_remote_csi_subdev(chan); + subdev = tegra_channel_get_remote_bridge_subdev(chan); if (!subdev) return NULL; @@ -204,7 +204,7 @@ static int tegra_channel_enable_stream(struct tegra_vi_channel *chan) struct v4l2_subdev *subdev; int ret; - subdev = tegra_channel_get_remote_csi_subdev(chan); + subdev = tegra_channel_get_remote_bridge_subdev(chan); ret = v4l2_subdev_call(subdev, video, s_stream, true); if (ret < 0 && ret != -ENOIOCTLCMD) return ret; @@ -217,7 +217,7 @@ static int tegra_channel_disable_stream(struct tegra_vi_channel *chan) struct v4l2_subdev *subdev; int ret; - subdev = tegra_channel_get_remote_csi_subdev(chan); + subdev = tegra_channel_get_remote_bridge_subdev(chan); ret = v4l2_subdev_call(subdev, video, s_stream, false); if (ret < 0 && ret != -ENOIOCTLCMD) return ret; @@ -1631,11 +1631,11 @@ static int tegra_vi_graph_notify_complete(struct v4l2_async_notifier *notifier) goto unregister_video; } - subdev = tegra_channel_get_remote_csi_subdev(chan); + subdev = tegra_channel_get_remote_bridge_subdev(chan); if (!subdev) { ret = -ENODEV; dev_err(vi->dev, - "failed to get remote csi subdev: %d\n", ret); + "failed to get remote bridge subdev: %d\n", ret); goto unregister_video; } |
