summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe.c11
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipeif.c17
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_isif.c17
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_resizer.c39
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c10
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.c58
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.h1
-rw-r--r--drivers/staging/media/omap4iss/iss.c199
-rw-r--r--drivers/staging/media/omap4iss/iss.h8
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c48
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.h1
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipe.c11
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipeif.c44
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipeif.h1
-rw-r--r--drivers/staging/media/omap4iss/iss_resizer.c42
-rw-r--r--drivers/staging/media/omap4iss/iss_resizer.h1
-rw-r--r--drivers/staging/media/omap4iss/iss_video.c61
-rw-r--r--drivers/staging/media/omap4iss/iss_video.h5
18 files changed, 375 insertions, 199 deletions
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index c492914768ea..ac78ed2f8bcc 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1712,8 +1712,11 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local,
struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
- switch (local->index | media_entity_type(remote->entity)) {
- case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ if (!is_media_entity_v4l2_subdev(remote->entity))
+ return -EINVAL;
+
+ switch (local->index) {
+ case IPIPE_PAD_SINK:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
ipipe->input = IPIPE_INPUT_NONE;
break;
@@ -1726,7 +1729,7 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local,
ipipe->input = IPIPE_INPUT_CCDC;
break;
- case IPIPE_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+ case IPIPE_PAD_SOURCE:
/* out to RESIZER */
if (flags & MEDIA_LNK_FL_ENABLED)
ipipe->output = IPIPE_OUTPUT_RESIZER;
@@ -1840,7 +1843,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
v4l2_ctrl_handler_setup(&ipipe->ctrls);
sd->ctrl_handler = &ipipe->ctrls;
- return media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+ return media_entity_pads_init(me, IPIPE_PADS_NUM, pads);
}
/*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8b230541b1d1..633d6456fdce 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -885,9 +885,14 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local,
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
struct vpfe_device *vpfe = to_vpfe_device(ipipeif);
+ unsigned int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) {
- case IPIPEIF_PAD_SINK | MEDIA_ENT_T_DEVNODE:
+ /* FIXME: this is actually a hack! */
+ if (is_media_entity_v4l2_subdev(remote->entity))
+ index |= 2 << 16;
+
+ switch (index) {
+ case IPIPEIF_PAD_SINK:
/* Single shot mode */
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
ipipeif->input = IPIPEIF_INPUT_NONE;
@@ -896,7 +901,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local,
ipipeif->input = IPIPEIF_INPUT_MEMORY;
break;
- case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ case IPIPEIF_PAD_SINK | 2 << 16:
/* read from isif */
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
ipipeif->input = IPIPEIF_INPUT_NONE;
@@ -908,7 +913,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local,
ipipeif->input = IPIPEIF_INPUT_ISIF;
break;
- case IPIPEIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+ case IPIPEIF_PAD_SOURCE | 2 << 16:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
ipipeif->output = IPIPEIF_OUTPUT_NONE;
break;
@@ -971,7 +976,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
ipipeif->video_in.vpfe_dev = vpfe_dev;
flags = 0;
- ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+ ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
&ipipeif->subdev.entity, 0, flags);
if (ret < 0)
goto fail;
@@ -1026,7 +1031,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
ipipeif->output = IPIPEIF_OUTPUT_NONE;
me->ops = &ipipeif_media_ops;
- ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads, 0);
+ ret = media_entity_pads_init(me, IPIPEIF_NUM_PADS, pads);
if (ret)
goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 80907b464412..99057892d88d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1707,9 +1707,14 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local,
{
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
+ unsigned int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) {
- case ISIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ /* FIXME: this is actually a hack! */
+ if (is_media_entity_v4l2_subdev(remote->entity))
+ index |= 2 << 16;
+
+ switch (index) {
+ case ISIF_PAD_SINK | 2 << 16:
/* read from decoder/sensor */
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
isif->input = ISIF_INPUT_NONE;
@@ -1720,7 +1725,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local,
isif->input = ISIF_INPUT_PARALLEL;
break;
- case ISIF_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+ case ISIF_PAD_SOURCE:
/* write to memory */
if (flags & MEDIA_LNK_FL_ENABLED)
isif->output = ISIF_OUTPUT_MEMORY;
@@ -1728,7 +1733,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local,
isif->output = ISIF_OUTPUT_NONE;
break;
- case ISIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+ case ISIF_PAD_SOURCE | 2 << 16:
if (flags & MEDIA_LNK_FL_ENABLED)
isif->output = ISIF_OUTPUT_IPIPEIF;
else
@@ -1817,7 +1822,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
isif->video_out.vpfe_dev = vpfe_dev;
flags = 0;
/* connect isif to video node */
- ret = media_entity_create_link(&isif->subdev.entity, 1,
+ ret = media_create_pad_link(&isif->subdev.entity, 1,
&isif->video_out.video_dev.entity,
0, flags);
if (ret < 0)
@@ -2052,7 +2057,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
isif->input = ISIF_INPUT_NONE;
isif->output = ISIF_OUTPUT_NONE;
me->ops = &isif_media_ops;
- status = media_entity_init(me, ISIF_PADS_NUM, pads, 0);
+ status = media_entity_pads_init(me, ISIF_PADS_NUM, pads);
if (status)
goto isif_fail;
isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index d892fee3f52f..a91395ce91e1 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1648,10 +1648,15 @@ static int resizer_link_setup(struct media_entity *entity,
struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output;
u16 ipipe_source = vpfe_dev->vpfe_ipipe.output;
+ unsigned int index = local->index;
+
+ /* FIXME: this is actually a hack! */
+ if (is_media_entity_v4l2_subdev(remote->entity))
+ index |= 2 << 16;
if (&resizer->crop_resizer.subdev == sd) {
- switch (local->index | media_entity_type(remote->entity)) {
- case RESIZER_CROP_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ switch (index) {
+ case RESIZER_CROP_PAD_SINK | 2 << 16:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->crop_resizer.input =
RESIZER_CROP_INPUT_NONE;
@@ -1671,7 +1676,7 @@ static int resizer_link_setup(struct media_entity *entity,
return -EINVAL;
break;
- case RESIZER_CROP_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+ case RESIZER_CROP_PAD_SOURCE | 2 << 16:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->crop_resizer.output =
RESIZER_CROP_OUTPUT_NONE;
@@ -1683,7 +1688,7 @@ static int resizer_link_setup(struct media_entity *entity,
resizer->crop_resizer.output = RESIZER_A;
break;
- case RESIZER_CROP_PAD_SOURCE2 | MEDIA_ENT_T_V4L2_SUBDEV:
+ case RESIZER_CROP_PAD_SOURCE2 | 2 << 16:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->crop_resizer.output2 =
RESIZER_CROP_OUTPUT_NONE;
@@ -1699,8 +1704,8 @@ static int resizer_link_setup(struct media_entity *entity,
return -EINVAL;
}
} else if (&resizer->resizer_a.subdev == sd) {
- switch (local->index | media_entity_type(remote->entity)) {
- case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ switch (index) {
+ case RESIZER_PAD_SINK | 2 << 16:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->resizer_a.input = RESIZER_INPUT_NONE;
break;
@@ -1710,7 +1715,7 @@ static int resizer_link_setup(struct media_entity *entity,
resizer->resizer_a.input = RESIZER_INPUT_CROP_RESIZER;
break;
- case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+ case RESIZER_PAD_SOURCE:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->resizer_a.output = RESIZER_OUTPUT_NONE;
break;
@@ -1724,8 +1729,8 @@ static int resizer_link_setup(struct media_entity *entity,
return -EINVAL;
}
} else if (&resizer->resizer_b.subdev == sd) {
- switch (local->index | media_entity_type(remote->entity)) {
- case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ switch (index) {
+ case RESIZER_PAD_SINK | 2 << 16:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->resizer_b.input = RESIZER_INPUT_NONE;
break;
@@ -1735,7 +1740,7 @@ static int resizer_link_setup(struct media_entity *entity,
resizer->resizer_b.input = RESIZER_INPUT_CROP_RESIZER;
break;
- case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+ case RESIZER_PAD_SOURCE:
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->resizer_b.output = RESIZER_OUTPUT_NONE;
break;
@@ -1826,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
/* create link between Resizer Crop----> Resizer A*/
- ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+ ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
&resizer->resizer_a.subdev.entity,
0, flags);
if (ret < 0)
goto out_create_link;
/* create link between Resizer Crop----> Resizer B*/
- ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+ ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
&resizer->resizer_b.subdev.entity,
0, flags);
if (ret < 0)
goto out_create_link;
/* create link between Resizer A ----> video out */
- ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+ ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
if (ret < 0)
goto out_create_link;
/* create link between Resizer B ----> video out */
- ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+ ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
if (ret < 0)
goto out_create_link;
@@ -1910,7 +1915,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE;
vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz;
me->ops = &resizer_media_ops;
- ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, RESIZER_CROP_PADS_NUM, pads);
if (ret)
return ret;
@@ -1932,7 +1937,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE;
vpfe_rsz->resizer_a.rsz_device = vpfe_rsz;
me->ops = &resizer_media_ops;
- ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
if (ret)
return ret;
@@ -1954,7 +1959,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE;
vpfe_rsz->resizer_b.rsz_device = vpfe_rsz;
me->ops = &resizer_media_ops;
- ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
if (ret)
return ret;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 69b678ca40c0..ec46f366dd17 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
/* if entity has no pads (ex: amplifier),
cant establish link */
if (vpfe_dev->sd[i]->entity.num_pads) {
- ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+ ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
0, &vpfe_dev->vpfe_isif.subdev.entity,
0, flags);
if (ret < 0)
goto out_resizer_register;
}
- ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+ ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
&vpfe_dev->vpfe_ipipeif.subdev.entity,
0, flags);
if (ret < 0)
goto out_resizer_register;
- ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+ ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
&vpfe_dev->vpfe_ipipe.subdev.entity,
0, flags);
if (ret < 0)
goto out_resizer_register;
- ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+ ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
0, flags);
if (ret < 0)
goto out_resizer_register;
- ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+ ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
0, flags);
if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index adb2bc8811ab..3ec7e65a3ffa 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -88,7 +88,7 @@ vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad)
{
struct media_pad *remote = media_entity_remote_pad(&video->pad);
- if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
+ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
return NULL;
if (pad)
*pad = remote->index;
@@ -127,13 +127,14 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
}
/* make a note of pipeline details */
-static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
+static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
{
+ struct media_entity_graph graph;
struct media_entity *entity = &video->video_dev.entity;
- struct media_device *mdev = entity->parent;
+ struct media_device *mdev = entity->graph_obj.mdev;
struct vpfe_pipeline *pipe = &video->pipe;
struct vpfe_video_device *far_end = NULL;
- struct media_entity_graph graph;
+ int ret;
pipe->input_num = 0;
pipe->output_num = 0;
@@ -144,11 +145,16 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
pipe->outputs[pipe->output_num++] = video;
mutex_lock(&mdev->graph_mutex);
+ ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
+ if (ret) {
+ mutex_unlock(&video->lock);
+ return -ENOMEM;
+ }
media_entity_graph_walk_start(&graph, entity);
while ((entity = media_entity_graph_walk_next(&graph))) {
if (entity == &video->video_dev.entity)
continue;
- if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+ if (!is_media_entity_v4l2_io(entity))
continue;
far_end = to_vpfe_video(media_entity_to_video_device(entity));
if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -156,7 +162,10 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
else
pipe->outputs[pipe->output_num++] = far_end;
}
+ media_entity_graph_walk_cleanup(&graph);
mutex_unlock(&mdev->graph_mutex);
+
+ return 0;
}
/* update pipe state selected by user */
@@ -165,7 +174,9 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video)
struct vpfe_pipeline *pipe = &video->pipe;
int ret;
- vpfe_prepare_pipeline(video);
+ ret = vpfe_prepare_pipeline(video);
+ if (ret)
+ return ret;
/* Find out if there is any input video
if yes, it is single shot.
@@ -243,8 +254,7 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
/* Retrieve the source format */
pad = media_entity_remote_pad(pad);
- if (pad == NULL ||
- pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
break;
subdev = media_entity_to_v4l2_subdev(pad->entity);
@@ -277,29 +287,35 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
*/
static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
{
- struct media_entity_graph graph;
struct media_entity *entity;
struct v4l2_subdev *subdev;
struct media_device *mdev;
- int ret = 0;
+ int ret;
if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS)
entity = vpfe_get_input_entity(pipe->outputs[0]);
else
entity = &pipe->inputs[0]->video_dev.entity;
- mdev = entity->parent;
+ mdev = entity->graph_obj.mdev;
mutex_lock(&mdev->graph_mutex);
- media_entity_graph_walk_start(&graph, entity);
- while ((entity = media_entity_graph_walk_next(&graph))) {
+ ret = media_entity_graph_walk_init(&pipe->graph,
+ entity->graph_obj.mdev);
+ if (ret)
+ goto out;
+ media_entity_graph_walk_start(&pipe->graph, entity);
+ while ((entity = media_entity_graph_walk_next(&pipe->graph))) {
- if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+ if (!is_media_entity_v4l2_subdev(entity))
continue;
subdev = media_entity_to_v4l2_subdev(entity);
ret = v4l2_subdev_call(subdev, video, s_stream, 1);
if (ret < 0 && ret != -ENOIOCTLCMD)
break;
}
+out:
+ if (ret)
+ media_entity_graph_walk_cleanup(&pipe->graph);
mutex_unlock(&mdev->graph_mutex);
return ret;
}
@@ -317,7 +333,6 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
*/
static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
{
- struct media_entity_graph graph;
struct media_entity *entity;
struct v4l2_subdev *subdev;
struct media_device *mdev;
@@ -328,13 +343,13 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
else
entity = &pipe->inputs[0]->video_dev.entity;
- mdev = entity->parent;
+ mdev = entity->graph_obj.mdev;
mutex_lock(&mdev->graph_mutex);
- media_entity_graph_walk_start(&graph, entity);
+ media_entity_graph_walk_start(&pipe->graph, entity);
- while ((entity = media_entity_graph_walk_next(&graph))) {
+ while ((entity = media_entity_graph_walk_next(&pipe->graph))) {
- if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+ if (!is_media_entity_v4l2_subdev(entity))
continue;
subdev = media_entity_to_v4l2_subdev(entity);
ret = v4l2_subdev_call(subdev, video, s_stream, 0);
@@ -343,6 +358,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
}
mutex_unlock(&mdev->graph_mutex);
+ media_entity_graph_walk_cleanup(&pipe->graph);
return ret ? -ETIMEDOUT : 0;
}
@@ -1600,8 +1616,8 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
spin_lock_init(&video->irqlock);
spin_lock_init(&video->dma_queue_lock);
mutex_init(&video->lock);
- ret = media_entity_init(&video->video_dev.entity,
- 1, &video->pad, 0);
+ ret = media_entity_pads_init(&video->video_dev.entity,
+ 1, &video->pad);
if (ret < 0)
return ret;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.h b/drivers/staging/media/davinci_vpfe/vpfe_video.h
index 673cefe3ef61..653334d537d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.h
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.h
@@ -52,6 +52,7 @@ enum vpfe_video_state {
struct vpfe_pipeline {
/* media pipeline */
struct media_pipeline *pipe;
+ struct media_entity_graph graph;
/* state of the pipeline, continuous,
* single-shot or stopped
*/
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index e27a988540a6..30b473cfb020 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -389,15 +389,15 @@ static irqreturn_t iss_isr(int irq, void *_iss)
*
* Return the total number of users of all video device nodes in the pipeline.
*/
-static int iss_pipeline_pm_use_count(struct media_entity *entity)
+static int iss_pipeline_pm_use_count(struct media_entity *entity,
+ struct media_entity_graph *graph)
{
- struct media_entity_graph graph;
int use = 0;
- media_entity_graph_walk_start(&graph, entity);
+ media_entity_graph_walk_start(graph, entity);
- while ((entity = media_entity_graph_walk_next(&graph))) {
- if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+ while ((entity = media_entity_graph_walk_next(graph))) {
+ if (is_media_entity_v4l2_io(entity))
use += entity->use_count;
}
@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
{
struct v4l2_subdev *subdev;
- subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
+ subdev = is_media_entity_v4l2_subdev(entity)
? media_entity_to_v4l2_subdev(entity) : NULL;
if (entity->use_count == 0 && change > 0 && subdev) {
@@ -449,29 +449,29 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
*
* Return 0 on success or a negative error code on failure.
*/
-static int iss_pipeline_pm_power(struct media_entity *entity, int change)
+static int iss_pipeline_pm_power(struct media_entity *entity, int change,
+ struct media_entity_graph *graph)
{
- struct media_entity_graph graph;
struct media_entity *first = entity;
int ret = 0;
if (!change)
return 0;
- media_entity_graph_walk_start(&graph, entity);
+ media_entity_graph_walk_start(graph, entity);
- while (!ret && (entity = media_entity_graph_walk_next(&graph)))
- if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+ while (!ret && (entity = media_entity_graph_walk_next(graph)))
+ if (is_media_entity_v4l2_subdev(entity))
ret = iss_pipeline_pm_power_one(entity, change);
if (!ret)
return 0;
- media_entity_graph_walk_start(&graph, first);
+ media_entity_graph_walk_start(graph, first);
- while ((first = media_entity_graph_walk_next(&graph)) &&
+ while ((first = media_entity_graph_walk_next(graph)) &&
first != entity)
- if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
+ if (is_media_entity_v4l2_subdev(first))
iss_pipeline_pm_power_one(first, -change);
return ret;
@@ -489,23 +489,24 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)
* off is assumed to never fail. No failure can occur when the use parameter is
* set to 0.
*/
-int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
+int omap4iss_pipeline_pm_use(struct media_entity *entity, int use,
+ struct media_entity_graph *graph)
{
int change = use ? 1 : -1;
int ret;
- mutex_lock(&entity->parent->graph_mutex);
+ mutex_lock(&entity->graph_obj.mdev->graph_mutex);
/* Apply use count to node. */
entity->use_count += change;
WARN_ON(entity->use_count < 0);
/* Apply power change to connected non-nodes. */
- ret = iss_pipeline_pm_power(entity, change);
+ ret = iss_pipeline_pm_power(entity, change, graph);
if (ret < 0)
entity->use_count -= change;
- mutex_unlock(&entity->parent->graph_mutex);
+ mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
return ret;
}
@@ -526,34 +527,48 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
unsigned int notification)
{
+ struct media_entity_graph *graph =
+ &container_of(link->graph_obj.mdev, struct iss_device,
+ media_dev)->pm_count_graph;
struct media_entity *source = link->source->entity;
struct media_entity *sink = link->sink->entity;
- int source_use = iss_pipeline_pm_use_count(source);
- int sink_use = iss_pipeline_pm_use_count(sink);
+ int source_use;
+ int sink_use;
int ret;
+ if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
+ ret = media_entity_graph_walk_init(graph,
+ link->graph_obj.mdev);
+ if (ret)
+ return ret;
+ }
+
+ source_use = iss_pipeline_pm_use_count(source, graph);
+ sink_use = iss_pipeline_pm_use_count(sink, graph);
+
if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
- !(link->flags & MEDIA_LNK_FL_ENABLED)) {
+ !(flags & MEDIA_LNK_FL_ENABLED)) {
/* Powering off entities is assumed to never fail. */
- iss_pipeline_pm_power(source, -sink_use);
- iss_pipeline_pm_power(sink, -source_use);
+ iss_pipeline_pm_power(source, -sink_use, graph);
+ iss_pipeline_pm_power(sink, -source_use, graph);
return 0;
}
- if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+ if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
(flags & MEDIA_LNK_FL_ENABLED)) {
- ret = iss_pipeline_pm_power(source, sink_use);
+ ret = iss_pipeline_pm_power(source, sink_use, graph);
if (ret < 0)
return ret;
- ret = iss_pipeline_pm_power(sink, source_use);
+ ret = iss_pipeline_pm_power(sink, source_use, graph);
if (ret < 0)
- iss_pipeline_pm_power(source, -sink_use);
-
- return ret;
+ iss_pipeline_pm_power(source, -sink_use, graph);
}
- return 0;
+ if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH)
+ media_entity_graph_walk_cleanup(graph);
+
+ return ret;
}
/* -----------------------------------------------------------------------------
@@ -590,8 +605,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,
break;
pad = media_entity_remote_pad(pad);
- if (!pad ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
break;
entity = pad->entity;
@@ -607,7 +621,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,
* crashed. Mark it as such, the ISS will be reset when
* applications will release it.
*/
- iss->crashed |= 1U << subdev->entity.id;
+ media_entity_enum_set(&iss->crashed, &subdev->entity);
failure = -ETIMEDOUT;
}
}
@@ -642,7 +656,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
* pipeline won't start anyway (those entities would then likely fail to
* stop, making the problem worse).
*/
- if (pipe->entities & iss->crashed)
+ if (media_entity_enum_intersects(&pipe->ent_enum, &iss->crashed))
return -EIO;
spin_lock_irqsave(&pipe->lock, flags);
@@ -658,8 +672,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
break;
pad = media_entity_remote_pad(pad);
- if (!pad ||
- media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
break;
entity = pad->entity;
@@ -763,7 +776,8 @@ static int iss_reset(struct iss_device *iss)
return -ETIMEDOUT;
}
- iss->crashed = 0;
+ media_entity_enum_zero(&iss->crashed);
+
return 0;
}
@@ -1092,7 +1106,7 @@ void omap4iss_put(struct iss_device *iss)
* be worth investigating whether resetting the ISP only can't
* fix the problem in some cases.
*/
- if (iss->crashed)
+ if (!media_entity_enum_empty(&iss->crashed))
iss_reset(iss);
iss_disable_clocks(iss);
}
@@ -1259,7 +1273,7 @@ static int iss_register_entities(struct iss_device *iss)
goto done;
}
- ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+ ret = media_create_pad_link(&sensor->entity, 0, input, pad,
flags);
if (ret < 0)
goto done;
@@ -1274,6 +1288,68 @@ done:
return ret;
}
+/*
+ * iss_create_links() - Pads links creation for the subdevices
+ * @iss : Pointer to ISS device
+ *
+ * return negative error code or zero on success
+ */
+static int iss_create_links(struct iss_device *iss)
+{
+ int ret;
+
+ ret = omap4iss_csi2_create_links(iss);
+ if (ret < 0) {
+ dev_err(iss->dev, "CSI2 pads links creation failed\n");
+ return ret;
+ }
+
+ ret = omap4iss_ipipeif_create_links(iss);
+ if (ret < 0) {
+ dev_err(iss->dev, "ISP IPIPEIF pads links creation failed\n");
+ return ret;
+ }
+
+ ret = omap4iss_resizer_create_links(iss);
+ if (ret < 0) {
+ dev_err(iss->dev, "ISP RESIZER pads links creation failed\n");
+ return ret;
+ }
+
+ /* Connect the submodules. */
+ ret = media_create_pad_link(
+ &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
+ &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = media_create_pad_link(
+ &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
+ &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = media_create_pad_link(
+ &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
+ &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = media_create_pad_link(
+ &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
+ &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = media_create_pad_link(
+ &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
+ &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+};
+
static void iss_cleanup_modules(struct iss_device *iss)
{
omap4iss_csi2_cleanup(iss);
@@ -1316,41 +1392,8 @@ static int iss_initialize_modules(struct iss_device *iss)
goto error_resizer;
}
- /* Connect the submodules. */
- ret = media_entity_create_link(
- &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
- &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
- &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
- &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
- &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
- ret = media_entity_create_link(
- &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
- &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
- if (ret < 0)
- goto error_link;
-
return 0;
-error_link:
- omap4iss_resizer_cleanup(iss);
error_resizer:
omap4iss_ipipe_cleanup(iss);
error_ipipe:
@@ -1464,10 +1507,21 @@ static int iss_probe(struct platform_device *pdev)
if (ret < 0)
goto error_modules;
+ ret = media_entity_enum_init(&iss->crashed, &iss->media_dev);
+ if (ret)
+ goto error_entities;
+
+ ret = iss_create_links(iss);
+ if (ret < 0)
+ goto error_entities;
+
omap4iss_put(iss);
return 0;
+error_entities:
+ iss_unregister_entities(iss);
+ media_entity_enum_cleanup(&iss->crashed);
error_modules:
iss_cleanup_modules(iss);
error_iss:
@@ -1485,6 +1539,7 @@ static int iss_remove(struct platform_device *pdev)
struct iss_device *iss = platform_get_drvdata(pdev);
iss_unregister_entities(iss);
+ media_entity_enum_cleanup(&iss->crashed);
iss_cleanup_modules(iss);
return 0;
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
index 5929357fe687..05f08a3caa19 100644
--- a/drivers/staging/media/omap4iss/iss.h
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -82,11 +82,12 @@ struct iss_reg {
/*
* struct iss_device - ISS device structure.
* @syscon: Regmap for the syscon register space
- * @crashed: Bitmask of crashed entities (indexed by entity ID)
+ * @crashed: Crashed entities
*/
struct iss_device {
struct v4l2_device v4l2_dev;
struct media_device media_dev;
+ struct media_entity_graph pm_count_graph;
struct device *dev;
u32 revision;
@@ -101,7 +102,7 @@ struct iss_device {
u64 raw_dmamask;
struct mutex iss_mutex; /* For handling ref_count field */
- unsigned int crashed;
+ struct media_entity_enum crashed;
int has_context;
int ref_count;
@@ -151,7 +152,8 @@ void omap4iss_isp_subclk_enable(struct iss_device *iss,
void omap4iss_isp_subclk_disable(struct iss_device *iss,
enum iss_isp_subclk_resource res);
-int omap4iss_pipeline_pm_use(struct media_entity *entity, int use);
+int omap4iss_pipeline_pm_use(struct media_entity *entity, int use,
+ struct media_entity_graph *graph);
int omap4iss_register_entities(struct platform_device *pdev,
struct v4l2_device *v4l2_dev);
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index b941035139ae..aaca39d751a5 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1170,14 +1170,19 @@ static int csi2_link_setup(struct media_entity *entity,
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
+ unsigned int index = local->index;
+
+ /* FIXME: this is actually a hack! */
+ if (is_media_entity_v4l2_subdev(remote->entity))
+ index |= 2 << 16;
/*
* The ISS core doesn't support pipelines with multiple video outputs.
* Revisit this when it will be implemented, and return -EBUSY for now.
*/
- switch (local->index | media_entity_type(remote->entity)) {
- case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+ switch (index) {
+ case CSI2_PAD_SOURCE:
if (flags & MEDIA_LNK_FL_ENABLED) {
if (csi2->output & ~CSI2_OUTPUT_MEMORY)
return -EBUSY;
@@ -1187,7 +1192,7 @@ static int csi2_link_setup(struct media_entity *entity,
}
break;
- case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+ case CSI2_PAD_SOURCE | 2 << 16:
if (flags & MEDIA_LNK_FL_ENABLED) {
if (csi2->output & ~CSI2_OUTPUT_IPIPEIF)
return -EBUSY;
@@ -1271,7 +1276,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
me->ops = &csi2_media_ops;
- ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads);
if (ret < 0)
return ret;
@@ -1290,16 +1295,8 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
if (ret < 0)
goto error_video;
- /* Connect the CSI2 subdev to the video node. */
- ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
- &csi2->video_out.video.entity, 0, 0);
- if (ret < 0)
- goto error_link;
-
return 0;
-error_link:
- omap4iss_video_cleanup(&csi2->video_out);
error_video:
media_entity_cleanup(&csi2->subdev.entity);
return ret;
@@ -1342,6 +1339,33 @@ int omap4iss_csi2_init(struct iss_device *iss)
}
/*
+ * omap4iss_csi2_create_links() - CSI2 pads links creation
+ * @iss: Pointer to ISS device
+ *
+ * return negative error code or zero on success
+ */
+int omap4iss_csi2_create_links(struct iss_device *iss)
+{
+ struct iss_csi2_device *csi2a = &iss->csi2a;
+ struct iss_csi2_device *csi2b = &iss->csi2b;
+ int ret;
+
+ /* Connect the CSI2a subdev to the video node. */
+ ret = media_create_pad_link(&csi2a->subdev.entity, CSI2_PAD_SOURCE,
+ &csi2a->video_out.video.entity, 0, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Connect the CSI2b subdev to the video node. */
+ ret = media_create_pad_link(&csi2b->subdev.entity, CSI2_PAD_SOURCE,
+ &csi2b->video_out.video.entity, 0, 0);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/*
* omap4iss_csi2_cleanup - Routine for module driver cleanup
*/
void omap4iss_csi2_cleanup(struct iss_device *iss)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.h b/drivers/staging/media/omap4iss/iss_csi2.h
index f2f5343b4a80..24ab378d469f 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.h
+++ b/drivers/staging/media/omap4iss/iss_csi2.h
@@ -151,6 +151,7 @@ struct iss_csi2_device {
void omap4iss_csi2_isr(struct iss_csi2_device *csi2);
int omap4iss_csi2_reset(struct iss_csi2_device *csi2);
int omap4iss_csi2_init(struct iss_device *iss);
+int omap4iss_csi2_create_links(struct iss_device *iss);
void omap4iss_csi2_cleanup(struct iss_device *iss);
void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2);
int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2,
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c
index dd0abeffd893..d38782e8e84c 100644
--- a/drivers/staging/media/omap4iss/iss_ipipe.c
+++ b/drivers/staging/media/omap4iss/iss_ipipe.c
@@ -447,8 +447,11 @@ static int ipipe_link_setup(struct media_entity *entity,
struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
struct iss_device *iss = to_iss_device(ipipe);
- switch (local->index | media_entity_type(remote->entity)) {
- case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ if (!is_media_entity_v4l2_subdev(remote->entity))
+ return -EINVAL;
+
+ switch (local->index) {
+ case IPIPE_PAD_SINK:
/* Read from IPIPEIF. */
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
ipipe->input = IPIPE_INPUT_NONE;
@@ -463,7 +466,7 @@ static int ipipe_link_setup(struct media_entity *entity,
break;
- case IPIPE_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
+ case IPIPE_PAD_SOURCE_VP:
/* Send to RESIZER */
if (flags & MEDIA_LNK_FL_ENABLED) {
if (ipipe->output & ~IPIPE_OUTPUT_VP)
@@ -513,7 +516,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
me->ops = &ipipe_media_ops;
- ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, IPIPE_PADS_NUM, pads);
if (ret < 0)
return ret;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index 5f9e449e7007..23de8330731d 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -662,9 +662,14 @@ static int ipipeif_link_setup(struct media_entity *entity,
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
struct iss_device *iss = to_iss_device(ipipeif);
+ unsigned int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) {
- case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ /* FIXME: this is actually a hack! */
+ if (is_media_entity_v4l2_subdev(remote->entity))
+ index |= 2 << 16;
+
+ switch (index) {
+ case IPIPEIF_PAD_SINK | 2 << 16:
/* Read from the sensor CSI2a or CSI2b. */
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
ipipeif->input = IPIPEIF_INPUT_NONE;
@@ -681,7 +686,7 @@ static int ipipeif_link_setup(struct media_entity *entity,
break;
- case IPIPEIF_PAD_SOURCE_ISIF_SF | MEDIA_ENT_T_DEVNODE:
+ case IPIPEIF_PAD_SOURCE_ISIF_SF:
/* Write to memory */
if (flags & MEDIA_LNK_FL_ENABLED) {
if (ipipeif->output & ~IPIPEIF_OUTPUT_MEMORY)
@@ -692,7 +697,7 @@ static int ipipeif_link_setup(struct media_entity *entity,
}
break;
- case IPIPEIF_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
+ case IPIPEIF_PAD_SOURCE_VP | 2 << 16:
/* Send to IPIPE/RESIZER */
if (flags & MEDIA_LNK_FL_ENABLED) {
if (ipipeif->output & ~IPIPEIF_OUTPUT_VP)
@@ -743,7 +748,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
me->ops = &ipipeif_media_ops;
- ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, IPIPEIF_PADS_NUM, pads);
if (ret < 0)
return ret;
@@ -757,18 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
ipipeif->video_out.bpl_zero_padding = 1;
ipipeif->video_out.bpl_max = 0x1ffe0;
- ret = omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF");
- if (ret < 0)
- return ret;
-
- /* Connect the IPIPEIF subdev to the video node. */
- ret = media_entity_create_link(&ipipeif->subdev.entity,
- IPIPEIF_PAD_SOURCE_ISIF_SF,
- &ipipeif->video_out.video.entity, 0, 0);
- if (ret < 0)
- return ret;
-
- return 0;
+ return omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF");
}
void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif)
@@ -821,6 +815,22 @@ int omap4iss_ipipeif_init(struct iss_device *iss)
}
/*
+ * omap4iss_ipipeif_create_links() - IPIPEIF pads links creation
+ * @iss: Pointer to ISS device
+ *
+ * return negative error code or zero on success
+ */
+int omap4iss_ipipeif_create_links(struct iss_device *iss)
+{
+ struct iss_ipipeif_device *ipipeif = &iss->ipipeif;
+
+ /* Connect the IPIPEIF subdev to the video node. */
+ return media_create_pad_link(&ipipeif->subdev.entity,
+ IPIPEIF_PAD_SOURCE_ISIF_SF,
+ &ipipeif->video_out.video.entity, 0, 0);
+}
+
+/*
* omap4iss_ipipeif_cleanup - IPIPEIF module cleanup.
* @iss: Device pointer specific to the OMAP4 ISS.
*/
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.h b/drivers/staging/media/omap4iss/iss_ipipeif.h
index c6bd96d9656c..bad32b1d6ad8 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.h
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.h
@@ -78,6 +78,7 @@ struct iss_ipipeif_device {
struct iss_device;
int omap4iss_ipipeif_init(struct iss_device *iss);
+int omap4iss_ipipeif_create_links(struct iss_device *iss);
void omap4iss_ipipeif_cleanup(struct iss_device *iss);
int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif,
struct v4l2_device *vdev);
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 108961e05f53..f1d352c711d5 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -716,9 +716,14 @@ static int resizer_link_setup(struct media_entity *entity,
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
struct iss_device *iss = to_iss_device(resizer);
+ unsigned int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) {
- case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+ /* FIXME: this is actually a hack! */
+ if (is_media_entity_v4l2_subdev(remote->entity))
+ index |= 2 << 16;
+
+ switch (index) {
+ case RESIZER_PAD_SINK | 2 << 16:
/* Read from IPIPE or IPIPEIF. */
if (!(flags & MEDIA_LNK_FL_ENABLED)) {
resizer->input = RESIZER_INPUT_NONE;
@@ -735,7 +740,7 @@ static int resizer_link_setup(struct media_entity *entity,
break;
- case RESIZER_PAD_SOURCE_MEM | MEDIA_ENT_T_DEVNODE:
+ case RESIZER_PAD_SOURCE_MEM:
/* Write to memory */
if (flags & MEDIA_LNK_FL_ENABLED) {
if (resizer->output & ~RESIZER_OUTPUT_MEMORY)
@@ -785,7 +790,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
me->ops = &resizer_media_ops;
- ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+ ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
if (ret < 0)
return ret;
@@ -799,18 +804,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
resizer->video_out.bpl_zero_padding = 1;
resizer->video_out.bpl_max = 0x1ffe0;
- ret = omap4iss_video_init(&resizer->video_out, "ISP resizer a");
- if (ret < 0)
- return ret;
-
- /* Connect the RESIZER subdev to the video node. */
- ret = media_entity_create_link(&resizer->subdev.entity,
- RESIZER_PAD_SOURCE_MEM,
- &resizer->video_out.video.entity, 0, 0);
- if (ret < 0)
- return ret;
-
- return 0;
+ return omap4iss_video_init(&resizer->video_out, "ISP resizer a");
}
void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer)
@@ -863,6 +857,22 @@ int omap4iss_resizer_init(struct iss_device *iss)
}
/*
+ * omap4iss_resizer_create_links() - RESIZER pads links creation
+ * @iss: Pointer to ISS device
+ *
+ * return negative error code or zero on success
+ */
+int omap4iss_resizer_create_links(struct iss_device *iss)
+{
+ struct iss_resizer_device *resizer = &iss->resizer;
+
+ /* Connect the RESIZER subdev to the video node. */
+ return media_create_pad_link(&resizer->subdev.entity,
+ RESIZER_PAD_SOURCE_MEM,
+ &resizer->video_out.video.entity, 0, 0);
+}
+
+/*
* omap4iss_resizer_cleanup - RESIZER module cleanup.
* @iss: Device pointer specific to the OMAP4 ISS.
*/
diff --git a/drivers/staging/media/omap4iss/iss_resizer.h b/drivers/staging/media/omap4iss/iss_resizer.h
index 1e145abafc65..8b7c5fe9ffed 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.h
+++ b/drivers/staging/media/omap4iss/iss_resizer.h
@@ -61,6 +61,7 @@ struct iss_resizer_device {
struct iss_device;
int omap4iss_resizer_init(struct iss_device *iss);
+int omap4iss_resizer_create_links(struct iss_device *iss);
void omap4iss_resizer_cleanup(struct iss_device *iss);
int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer,
struct v4l2_device *vdev);
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index e9aeca08986f..058233a9de67 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -190,8 +190,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad)
remote = media_entity_remote_pad(&video->pad);
- if (!remote ||
- media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
return NULL;
if (pad)
@@ -206,17 +205,23 @@ iss_video_far_end(struct iss_video *video)
{
struct media_entity_graph graph;
struct media_entity *entity = &video->video.entity;
- struct media_device *mdev = entity->parent;
+ struct media_device *mdev = entity->graph_obj.mdev;
struct iss_video *far_end = NULL;
mutex_lock(&mdev->graph_mutex);
+
+ if (media_entity_graph_walk_init(&graph, mdev)) {
+ mutex_unlock(&mdev->graph_mutex);
+ return NULL;
+ }
+
media_entity_graph_walk_start(&graph, entity);
while ((entity = media_entity_graph_walk_next(&graph))) {
if (entity == &video->video.entity)
continue;
- if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+ if (!is_media_entity_v4l2_io(entity))
continue;
far_end = to_iss_video(media_entity_to_video_device(entity));
@@ -227,6 +232,9 @@ iss_video_far_end(struct iss_video *video)
}
mutex_unlock(&mdev->graph_mutex);
+
+ media_entity_graph_walk_cleanup(&graph);
+
return far_end;
}
@@ -750,7 +758,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
struct iss_video_fh *vfh = to_iss_video_fh(fh);
struct iss_video *video = video_drvdata(file);
struct media_entity_graph graph;
- struct media_entity *entity;
+ struct media_entity *entity = &video->video.entity;
enum iss_pipeline_state state;
struct iss_pipeline *pipe;
struct iss_video *far_end;
@@ -765,24 +773,30 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
/* Start streaming on the pipeline. No link touching an entity in the
* pipeline can be activated or deactivated once streaming is started.
*/
- pipe = video->video.entity.pipe
- ? to_iss_pipeline(&video->video.entity) : &video->pipe;
+ pipe = entity->pipe
+ ? to_iss_pipeline(entity) : &video->pipe;
pipe->external = NULL;
pipe->external_rate = 0;
pipe->external_bpp = 0;
- pipe->entities = 0;
+
+ ret = media_entity_enum_init(&pipe->ent_enum, entity->graph_obj.mdev);
+ if (ret)
+ goto err_graph_walk_init;
+
+ ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
+ if (ret)
+ goto err_graph_walk_init;
if (video->iss->pdata->set_constraints)
video->iss->pdata->set_constraints(video->iss, true);
- ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
+ ret = media_entity_pipeline_start(entity, &pipe->pipe);
if (ret < 0)
goto err_media_entity_pipeline_start;
- entity = &video->video.entity;
media_entity_graph_walk_start(&graph, entity);
while ((entity = media_entity_graph_walk_next(&graph)))
- pipe->entities |= 1 << entity->id;
+ media_entity_enum_set(&pipe->ent_enum, entity);
/* Verify that the currently configured format matches the output of
* the connected subdev.
@@ -852,7 +866,10 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
spin_unlock_irqrestore(&video->qlock, flags);
}
+ media_entity_graph_walk_cleanup(&graph);
+
mutex_unlock(&video->stream_lock);
+
return 0;
err_omap4iss_set_stream:
@@ -864,7 +881,13 @@ err_media_entity_pipeline_start:
video->iss->pdata->set_constraints(video->iss, false);
video->queue = NULL;
+ media_entity_graph_walk_cleanup(&graph);
+
+err_graph_walk_init:
+ media_entity_enum_cleanup(&pipe->ent_enum);
+
mutex_unlock(&video->stream_lock);
+
return ret;
}
@@ -902,6 +925,8 @@ iss_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
vb2_streamoff(&vfh->queue, type);
video->queue = NULL;
+ media_entity_enum_cleanup(&pipe->ent_enum);
+
if (video->iss->pdata->set_constraints)
video->iss->pdata->set_constraints(video->iss, false);
media_entity_pipeline_stop(&video->video.entity);
@@ -984,7 +1009,13 @@ static int iss_video_open(struct file *file)
goto done;
}
- ret = omap4iss_pipeline_pm_use(&video->video.entity, 1);
+ ret = media_entity_graph_walk_init(&handle->graph,
+ &video->iss->media_dev);
+ if (ret)
+ goto done;
+
+ ret = omap4iss_pipeline_pm_use(&video->video.entity, 1,
+ &handle->graph);
if (ret < 0) {
omap4iss_put(video->iss);
goto done;
@@ -1023,6 +1054,7 @@ static int iss_video_open(struct file *file)
done:
if (ret < 0) {
v4l2_fh_del(&handle->vfh);
+ media_entity_graph_walk_cleanup(&handle->graph);
kfree(handle);
}
@@ -1038,12 +1070,13 @@ static int iss_video_release(struct file *file)
/* Disable streaming and free the buffers queue resources. */
iss_video_streamoff(file, vfh, video->type);
- omap4iss_pipeline_pm_use(&video->video.entity, 0);
+ omap4iss_pipeline_pm_use(&video->video.entity, 0, &handle->graph);
/* Release the videobuf2 queue */
vb2_queue_release(&handle->queue);
/* Release the file handle. */
+ media_entity_graph_walk_cleanup(&handle->graph);
v4l2_fh_del(vfh);
kfree(handle);
file->private_data = NULL;
@@ -1102,7 +1135,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
return -EINVAL;
}
- ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+ ret = media_entity_pads_init(&video->video.entity, 1, &video->pad);
if (ret < 0)
return ret;
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h
index 41532eda1277..34588b7176ca 100644
--- a/drivers/staging/media/omap4iss/iss_video.h
+++ b/drivers/staging/media/omap4iss/iss_video.h
@@ -77,7 +77,7 @@ enum iss_pipeline_state {
/*
* struct iss_pipeline - An OMAP4 ISS hardware pipeline
- * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
+ * @ent_enum: Entities in the pipeline
* @error: A hardware error occurred during capture
*/
struct iss_pipeline {
@@ -87,7 +87,7 @@ struct iss_pipeline {
enum iss_pipeline_stream_state stream_state;
struct iss_video *input;
struct iss_video *output;
- unsigned int entities;
+ struct media_entity_enum ent_enum;
atomic_t frame_number;
bool do_propagation; /* of frame number */
bool error;
@@ -183,6 +183,7 @@ struct iss_video_fh {
struct vb2_queue queue;
struct v4l2_format format;
struct v4l2_fract timeperframe;
+ struct media_entity_graph graph;
};
#define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh)