@@ -71,6 +71,7 @@ struct vsp1_device {
struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
struct list_head entities;
+ struct list_head videos;
struct v4l2_device v4l2_dev;
struct media_device media_dev;
@@ -19,6 +19,7 @@
#include "vsp1.h"
#include "vsp1_bru.h"
#include "vsp1_rwpf.h"
+#include "vsp1_video.h"
#define BRU_MIN_SIZE 1U
#define BRU_MAX_SIZE 8190U
@@ -28,6 +28,7 @@
#include "vsp1_rwpf.h"
#include "vsp1_sru.h"
#include "vsp1_uds.h"
+#include "vsp1_video.h"
/* -----------------------------------------------------------------------------
* Interrupt Handling
@@ -117,14 +118,19 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
static void vsp1_destroy_entities(struct vsp1_device *vsp1)
{
- struct vsp1_entity *entity;
- struct vsp1_entity *next;
+ struct vsp1_entity *entity, *_entity;
+ struct vsp1_video *video, *_video;
- list_for_each_entry_safe(entity, next, &vsp1->entities, list_dev) {
+ list_for_each_entry_safe(entity, _entity, &vsp1->entities, list_dev) {
list_del(&entity->list_dev);
vsp1_entity_destroy(entity);
}
+ list_for_each_entry_safe(video, _video, &vsp1->videos, list) {
+ list_del(&video->list);
+ vsp1_video_cleanup(video);
+ }
+
v4l2_device_unregister(&vsp1->v4l2_dev);
media_device_unregister(&vsp1->media_dev);
}
@@ -202,6 +208,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+ struct vsp1_video *video;
struct vsp1_rwpf *rpf;
rpf = vsp1_rpf_create(vsp1, i);
@@ -212,6 +219,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
vsp1->rpf[i] = rpf;
list_add_tail(&rpf->entity.list_dev, &vsp1->entities);
+
+ video = vsp1_video_create(vsp1, rpf);
+ if (IS_ERR(video)) {
+ ret = PTR_ERR(video);
+ goto done;
+ }
+
+ list_add_tail(&video->list, &vsp1->videos);
}
if (vsp1->pdata.features & VSP1_HAS_SRU) {
@@ -238,6 +253,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+ struct vsp1_video *video;
struct vsp1_rwpf *wpf;
wpf = vsp1_wpf_create(vsp1, i);
@@ -248,6 +264,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
vsp1->wpf[i] = wpf;
list_add_tail(&wpf->entity.list_dev, &vsp1->entities);
+
+ video = vsp1_video_create(vsp1, wpf);
+ if (IS_ERR(video)) {
+ ret = PTR_ERR(video);
+ goto done;
+ }
+
+ list_add_tail(&video->list, &vsp1->videos);
+ wpf->entity.sink = &video->video.entity;
}
/* Create links. */
@@ -261,6 +286,37 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
goto done;
}
+ for (i = 0; i < vsp1->pdata.rpf_count; ++i) {
+ struct vsp1_rwpf *rpf = vsp1->rpf[i];
+
+ ret = media_entity_create_link(&rpf->entity.video->video.entity,
+ 0, &rpf->entity.subdev.entity,
+ RWPF_PAD_SINK,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
+ if (ret < 0)
+ goto done;
+ }
+
+ for (i = 0; i < vsp1->pdata.wpf_count; ++i) {
+ /* Connect the video device to the WPF. All connections are
+ * immutable except for the WPF0 source link if a LIF is
+ * present.
+ */
+ struct vsp1_rwpf *wpf = vsp1->wpf[i];
+ unsigned int flags = MEDIA_LNK_FL_ENABLED;
+
+ if (!(vsp1->pdata.features & VSP1_HAS_LIF) || i != 0)
+ flags |= MEDIA_LNK_FL_IMMUTABLE;
+
+ ret = media_entity_create_link(&wpf->entity.subdev.entity,
+ RWPF_PAD_SOURCE,
+ &wpf->entity.video->video.entity,
+ 0, flags);
+ if (ret < 0)
+ goto done;
+ }
+
if (vsp1->pdata.features & VSP1_HAS_LIF) {
ret = media_entity_create_link(
&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
@@ -486,6 +542,7 @@ static int vsp1_probe(struct platform_device *pdev)
vsp1->dev = &pdev->dev;
mutex_init(&vsp1->lock);
INIT_LIST_HEAD(&vsp1->entities);
+ INIT_LIST_HEAD(&vsp1->videos);
ret = vsp1_parse_dt(vsp1);
if (ret < 0)
@@ -20,7 +20,6 @@
#include "vsp1.h"
#include "vsp1_entity.h"
-#include "vsp1_video.h"
bool vsp1_entity_is_streaming(struct vsp1_entity *entity)
{
@@ -225,8 +224,6 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
void vsp1_entity_destroy(struct vsp1_entity *entity)
{
- if (entity->video)
- vsp1_video_cleanup(entity->video);
if (entity->subdev.ctrl_handler)
v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
media_entity_cleanup(&entity->subdev.entity);
@@ -217,7 +217,6 @@ static const struct vsp1_rwpf_operations rpf_vdev_ops = {
struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
{
struct v4l2_subdev *subdev;
- struct vsp1_video *video;
struct vsp1_rwpf *rpf;
int ret;
@@ -264,27 +263,6 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
goto error;
}
- /* Initialize the video device. */
- video = &rpf->video;
-
- video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- video->vsp1 = vsp1;
-
- ret = vsp1_video_init(video, rpf);
- if (ret < 0)
- goto error;
-
- rpf->entity.video = video;
-
- /* Connect the video device to the RPF. */
- ret = media_entity_create_link(&rpf->video.video.entity, 0,
- &rpf->entity.subdev.entity,
- RWPF_PAD_SINK,
- MEDIA_LNK_FL_ENABLED |
- MEDIA_LNK_FL_IMMUTABLE);
- if (ret < 0)
- goto error;
-
return rpf;
error:
@@ -19,7 +19,6 @@
#include "vsp1.h"
#include "vsp1_entity.h"
-#include "vsp1_video.h"
#define RWPF_PAD_SINK 0
#define RWPF_PAD_SOURCE 1
@@ -33,7 +32,6 @@ struct vsp1_rwpf_operations {
struct vsp1_rwpf {
struct vsp1_entity entity;
- struct vsp1_video video;
struct v4l2_ctrl_handler ctrls;
const struct vsp1_rwpf_operations *ops;
@@ -435,11 +435,11 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
if (e->type == VSP1_ENTITY_RPF) {
rwpf = to_rwpf(subdev);
pipe->inputs[pipe->num_inputs++] = rwpf;
- rwpf->video.pipe_index = pipe->num_inputs;
+ rwpf->entity.video->pipe_index = pipe->num_inputs;
} else if (e->type == VSP1_ENTITY_WPF) {
rwpf = to_rwpf(subdev);
pipe->output = to_rwpf(subdev);
- rwpf->video.pipe_index = 0;
+ rwpf->entity.video->pipe_index = 0;
} else if (e->type == VSP1_ENTITY_LIF) {
pipe->lif = e;
} else if (e->type == VSP1_ENTITY_BRU) {
@@ -648,10 +648,10 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
/* Complete buffers on all video nodes. */
for (i = 0; i < pipe->num_inputs; ++i)
- vsp1_video_frame_end(pipe, &pipe->inputs[i]->video);
+ vsp1_video_frame_end(pipe, pipe->inputs[i]->entity.video);
if (!pipe->lif)
- vsp1_video_frame_end(pipe, &pipe->output->video);
+ vsp1_video_frame_end(pipe, pipe->output->entity.video);
spin_lock_irqsave(&pipe->irqlock, flags);
@@ -1190,29 +1190,34 @@ static struct v4l2_file_operations vsp1_video_fops = {
* Initialization and Cleanup
*/
-int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
+struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
+ struct vsp1_rwpf *rwpf)
{
+ struct vsp1_video *video;
const char *direction;
int ret;
- switch (video->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- direction = "output";
- video->pad.flags = MEDIA_PAD_FL_SINK;
- break;
+ video = devm_kzalloc(vsp1->dev, sizeof(*video), GFP_KERNEL);
+ if (!video)
+ return ERR_PTR(-ENOMEM);
+
+ rwpf->entity.video = video;
+
+ video->vsp1 = vsp1;
+ video->rwpf = rwpf;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ if (rwpf->entity.type == VSP1_ENTITY_RPF) {
direction = "input";
+ video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
video->pad.flags = MEDIA_PAD_FL_SOURCE;
video->video.vfl_dir = VFL_DIR_TX;
- break;
-
- default:
- return -EINVAL;
+ } else {
+ direction = "output";
+ video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ video->pad.flags = MEDIA_PAD_FL_SINK;
+ video->video.vfl_dir = VFL_DIR_RX;
}
- video->rwpf = rwpf;
-
mutex_init(&video->lock);
spin_lock_init(&video->irqlock);
INIT_LIST_HEAD(&video->irqqueue);
@@ -1226,7 +1231,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
/* Initialize the media entity... */
ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
if (ret < 0)
- return ret;
+ return ERR_PTR(ret);
/* ... and the format ... */
rwpf->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT);
@@ -1281,12 +1286,12 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf)
goto error;
}
- return 0;
+ return video;
error:
vb2_dma_contig_cleanup_ctx(video->alloc_ctx);
vsp1_video_cleanup(video);
- return ret;
+ return ERR_PTR(ret);
}
void vsp1_video_cleanup(struct vsp1_video *video)
@@ -109,6 +109,7 @@ to_vsp1_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
}
struct vsp1_video {
+ struct list_head list;
struct vsp1_device *vsp1;
struct vsp1_rwpf *rwpf;
@@ -133,7 +134,8 @@ static inline struct vsp1_video *to_vsp1_video(struct video_device *vdev)
return container_of(vdev, struct vsp1_video, video);
}
-int vsp1_video_init(struct vsp1_video *video, struct vsp1_rwpf *rwpf);
+struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
+ struct vsp1_rwpf *rwpf);
void vsp1_video_cleanup(struct vsp1_video *video);
void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
@@ -215,9 +215,7 @@ static const struct vsp1_rwpf_operations wpf_vdev_ops = {
struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
{
struct v4l2_subdev *subdev;
- struct vsp1_video *video;
struct vsp1_rwpf *wpf;
- unsigned int flags;
int ret;
wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL);
@@ -263,33 +261,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
goto error;
}
- /* Initialize the video device. */
- video = &wpf->video;
-
- video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- video->vsp1 = vsp1;
-
- ret = vsp1_video_init(video, wpf);
- if (ret < 0)
- goto error;
-
- wpf->entity.video = video;
-
- /* Connect the video device to the WPF. All connections are immutable
- * except for the WPF0 source link if a LIF is present.
- */
- flags = MEDIA_LNK_FL_ENABLED;
- if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
- flags |= MEDIA_LNK_FL_IMMUTABLE;
-
- ret = media_entity_create_link(&wpf->entity.subdev.entity,
- RWPF_PAD_SOURCE,
- &wpf->video.video.entity, 0, flags);
- if (ret < 0)
- goto error;
-
- wpf->entity.sink = &wpf->video.video.entity;
-
return wpf;
error:
To make the video device nodes optional we need to decouple the [rw]pf instances from the video devices. Move video devices out of struct vsp1_rwpf and instantiate them dynamically in the core driver code. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> --- drivers/media/platform/vsp1/vsp1.h | 1 + drivers/media/platform/vsp1/vsp1_bru.c | 1 + drivers/media/platform/vsp1/vsp1_drv.c | 63 +++++++++++++++++++++++++++++-- drivers/media/platform/vsp1/vsp1_entity.c | 3 -- drivers/media/platform/vsp1/vsp1_rpf.c | 22 ----------- drivers/media/platform/vsp1/vsp1_rwpf.h | 2 - drivers/media/platform/vsp1/vsp1_video.c | 45 ++++++++++++---------- drivers/media/platform/vsp1/vsp1_video.h | 4 +- drivers/media/platform/vsp1/vsp1_wpf.c | 29 -------------- 9 files changed, 90 insertions(+), 80 deletions(-)