summaryrefslogtreecommitdiff
path: root/drivers/media/platform/video-mux.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-07-05 10:42:32 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-07-05 10:42:32 -0700
commit15ac468614e5e4fee82e1eb32568f427b0e51adc (patch)
treeab0c2f7a282c390a9aa337c14d9941e963a1049a /drivers/media/platform/video-mux.c
parent2784d74bcc811e9d743398da38552e6f9c73e96b (diff)
parentc61480a2ea5e5b997d10dfda556d3a63e31f87cd (diff)
Merge tag 'media/v6.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - Lots of improvement at atomisp driver, which is starting to look in good shape - Mediatek vcodec driver has gained support for av1 and hevc stateless codecs - New sensor driver: ov01a10 - verisilicon driver has gained AV1 entropy helpers - tegra-video has gained support for Tegra20 parallel input - dvb core has gained an extra property to better support DVB-S2X - as usual, lots of cleanups, fixes and improvements on media drivers * tag 'media/v6.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (253 commits) media: wl128x: fix a clang warning media: dvb: mb86a20s: get rid of a clang-15 warning media: cec: i2c: ch7322: also select REGMAP media: add HAS_IOPORT dependencies media: tc358746: select CONFIG_GENERIC_PHY media: mediatek: vcodec: Add dbgfs help function media: mediatek: vcodec: Add encode to support dbgfs media: mediatek: vcodec: Change dbgfs interface to support encode media: mediatek: vcodec: Get each instance format type media: mediatek: vcodec: Get each context resolution information media: mediatek: vcodec: Add a debugfs file to get different useful information media: mediatek: vcodec: Add debug params to control different log level media: mediatek: vcodec: Add debugfs interface to get debug information media: mediatek: vcodec: support stateless AV1 decoder media: verisilicon: Conditionally ignore native formats media: verisilicon: Enable AV1 decoder on rk3588 media: verisilicon: Add film grain feature to AV1 driver media: verisilicon: Add Rockchip AV1 decoder media: verisilicon: Add AV1 entropy helpers media: verisilicon: Compute motion vectors size for AV1 frames ...
Diffstat (limited to 'drivers/media/platform/video-mux.c')
-rw-r--r--drivers/media/platform/video-mux.c102
1 files changed, 42 insertions, 60 deletions
diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index 1d9f32e5a917..6d273abfe16c 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -24,7 +24,6 @@ struct video_mux {
struct v4l2_subdev subdev;
struct v4l2_async_notifier notifier;
struct media_pad *pads;
- struct v4l2_mbus_framefmt *format_mbus;
struct mux_control *mux;
struct mutex lock;
int active;
@@ -71,6 +70,9 @@ static int video_mux_link_setup(struct media_entity *entity,
mutex_lock(&vmux->lock);
if (flags & MEDIA_LNK_FL_ENABLED) {
+ struct v4l2_subdev_state *sd_state;
+ struct v4l2_mbus_framefmt *source_mbusformat;
+
if (vmux->active == local->index)
goto out;
@@ -86,7 +88,12 @@ static int video_mux_link_setup(struct media_entity *entity,
vmux->active = local->index;
/* Propagate the active format to the source */
- vmux->format_mbus[source_pad] = vmux->format_mbus[vmux->active];
+ sd_state = v4l2_subdev_lock_and_get_active_state(sd);
+ source_mbusformat = v4l2_subdev_get_pad_format(sd, sd_state,
+ source_pad);
+ *source_mbusformat = *v4l2_subdev_get_pad_format(sd, sd_state,
+ vmux->active);
+ v4l2_subdev_unlock_state(sd_state);
} else {
if (vmux->active != local->index)
goto out;
@@ -138,40 +145,6 @@ static const struct v4l2_subdev_video_ops video_mux_subdev_video_ops = {
.s_stream = video_mux_s_stream,
};
-static struct v4l2_mbus_framefmt *
-__video_mux_get_pad_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad, u32 which)
-{
- struct video_mux *vmux = v4l2_subdev_to_video_mux(sd);
-
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(sd, sd_state, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &vmux->format_mbus[pad];
- default:
- return NULL;
- }
-}
-
-static int video_mux_get_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *sdformat)
-{
- struct video_mux *vmux = v4l2_subdev_to_video_mux(sd);
-
- mutex_lock(&vmux->lock);
-
- sdformat->format = *__video_mux_get_pad_format(sd, sd_state,
- sdformat->pad,
- sdformat->which);
-
- mutex_unlock(&vmux->lock);
-
- return 0;
-}
-
static int video_mux_set_format(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *sdformat)
@@ -181,14 +154,11 @@ static int video_mux_set_format(struct v4l2_subdev *sd,
struct media_pad *pad = &vmux->pads[sdformat->pad];
u16 source_pad = sd->entity.num_pads - 1;
- mbusformat = __video_mux_get_pad_format(sd, sd_state, sdformat->pad,
- sdformat->which);
+ mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, sdformat->pad);
if (!mbusformat)
return -EINVAL;
- source_mbusformat = __video_mux_get_pad_format(sd, sd_state,
- source_pad,
- sdformat->which);
+ source_mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, source_pad);
if (!source_mbusformat)
return -EINVAL;
@@ -298,7 +268,8 @@ static int video_mux_set_format(struct v4l2_subdev *sd,
/* Source pad mirrors active sink pad, no limitations on sink pads */
if ((pad->flags & MEDIA_PAD_FL_SOURCE) && vmux->active >= 0)
- sdformat->format = vmux->format_mbus[vmux->active];
+ sdformat->format = *v4l2_subdev_get_pad_format(sd, sd_state,
+ vmux->active);
*mbusformat = sdformat->format;
@@ -321,7 +292,7 @@ static int video_mux_init_cfg(struct v4l2_subdev *sd,
mutex_lock(&vmux->lock);
for (i = 0; i < sd->entity.num_pads; i++) {
- mbusformat = v4l2_subdev_get_try_format(sd, sd_state, i);
+ mbusformat = v4l2_subdev_get_pad_format(sd, sd_state, i);
*mbusformat = video_mux_format_mbus_default;
}
@@ -332,7 +303,7 @@ static int video_mux_init_cfg(struct v4l2_subdev *sd,
static const struct v4l2_subdev_pad_ops video_mux_pad_ops = {
.init_cfg = video_mux_init_cfg,
- .get_fmt = video_mux_get_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = video_mux_set_format,
};
@@ -389,7 +360,7 @@ static int video_mux_async_register(struct video_mux *vmux,
ret = PTR_ERR(asd);
/* OK if asd already exists */
if (ret != -EEXIST)
- return ret;
+ goto err_nf_cleanup;
}
}
@@ -397,9 +368,19 @@ static int video_mux_async_register(struct video_mux *vmux,
ret = v4l2_async_subdev_nf_register(&vmux->subdev, &vmux->notifier);
if (ret)
- return ret;
+ goto err_nf_cleanup;
+
+ ret = v4l2_async_register_subdev(&vmux->subdev);
+ if (ret)
+ goto err_nf_unregister;
- return v4l2_async_register_subdev(&vmux->subdev);
+ return 0;
+
+err_nf_unregister:
+ v4l2_async_nf_unregister(&vmux->notifier);
+err_nf_cleanup:
+ v4l2_async_nf_cleanup(&vmux->notifier);
+ return ret;
}
static int video_mux_probe(struct platform_device *pdev)
@@ -452,17 +433,9 @@ static int video_mux_probe(struct platform_device *pdev)
if (!vmux->pads)
return -ENOMEM;
- vmux->format_mbus = devm_kcalloc(dev, num_pads,
- sizeof(*vmux->format_mbus),
- GFP_KERNEL);
- if (!vmux->format_mbus)
- return -ENOMEM;
-
- for (i = 0; i < num_pads; i++) {
+ for (i = 0; i < num_pads; i++)
vmux->pads[i].flags = (i < num_pads - 1) ? MEDIA_PAD_FL_SINK
: MEDIA_PAD_FL_SOURCE;
- vmux->format_mbus[i] = video_mux_format_mbus_default;
- }
vmux->subdev.entity.function = MEDIA_ENT_F_VID_MUX;
ret = media_entity_pads_init(&vmux->subdev.entity, num_pads,
@@ -472,12 +445,20 @@ static int video_mux_probe(struct platform_device *pdev)
vmux->subdev.entity.ops = &video_mux_ops;
+ ret = v4l2_subdev_init_finalize(&vmux->subdev);
+ if (ret < 0)
+ goto err_entity_cleanup;
+
ret = video_mux_async_register(vmux, num_pads - 1);
- if (ret) {
- v4l2_async_nf_unregister(&vmux->notifier);
- v4l2_async_nf_cleanup(&vmux->notifier);
- }
+ if (ret)
+ goto err_subdev_cleanup;
+
+ return 0;
+err_subdev_cleanup:
+ v4l2_subdev_cleanup(&vmux->subdev);
+err_entity_cleanup:
+ media_entity_cleanup(&vmux->subdev.entity);
return ret;
}
@@ -489,6 +470,7 @@ static void video_mux_remove(struct platform_device *pdev)
v4l2_async_nf_unregister(&vmux->notifier);
v4l2_async_nf_cleanup(&vmux->notifier);
v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
media_entity_cleanup(&sd->entity);
}