Skip to contentSkip to conversation

MC next generation patches

PATCH In review Mauro Carvalho Chehab 12 participants 247 messages Aug 30, 2015 – Feb 16, 2016 13 messages not in the archive Page 3 of 3

Subsystems (15)
lore
Share & tools
lore
maintainer
#194 lore raw

PATCH v8 32/55 media: use macros to check for V4L2 subdev entities

In reply to Mauro Carvalho Chehab

Hi Mauro,

Thank you for the patch.

Quoted 364 lines · On Sunday 30 August 2015 00:06:43 Mauro Carvalho Chehab wrote:

Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.

Please note that most drivers assume that there's just AV_DMA or V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.

Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the AV_DMA stuff.

(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/common.c index 0eb34ecb8ee4..8c9a29e0e294 100644

drivers/media/platform/exynos4-is/common.c +1 -2
@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct
 media_entity *entity) while (pad->flags & MEDIA_PAD_FL_SINK) {
 		/* source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/fimc-capture.c index 0627a93b2f3b..e9810fee4c30 100644

drivers/media/platform/exynos4-is/fimc-capture.c +2 -3
@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev
 *fimc) }
 		}
 
-		if (src_pad == NULL ||
-		    media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity))
 			break;
 
 		/* Don't call FIMC subdev operation to avoid nested locking */
@@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity
 *entity, struct fimc_vid_cap *vc = &fimc->vid_cap;
 	struct v4l2_subdev *sensor;
 
-	if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return -EINVAL;
 
 	if (WARN_ON(fimc == NULL))
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 3d9ccbf5f10f..5fbaf5e39903 100644

drivers/media/platform/exynos4-is/fimc-isp-video.c +1 -2
@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp
 *isp)
 
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
drivers/media/platform/exynos4-is/fimc-isp-video.c +0 -0
 		sd = media_entity_to_v4l2_subdev(pad->entity);
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/fimc-lite.c index b2607da4ad14..c2327147b360 100644

drivers/media/platform/exynos4-is/fimc-lite.c +2 -4
@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite
 *fimc) }
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity
 *entity, {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-	unsigned int remote_ent_type = media_entity_type(remote->entity);
 	int ret = 0;
 
 	if (WARN_ON(fimc == NULL))
@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity
 *entity,
 
 	switch (local->index) {
 	case FLITE_SD_PAD_SINK:
-		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (!is_media_entity_v4l2_subdev(remote->entity)) {
 			ret = -EINVAL;
 			break;
drivers/media/platform/exynos4-is/fimc-lite.c +2 -2
 		}
@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity
 *entity, case FLITE_SD_PAD_SOURCE_DMA:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_DEVNODE)
+		else if (is_media_entity_v4l2_io(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_DMA);
 		else
 			ret = -EINVAL;
@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity
 *entity, case FLITE_SD_PAD_SOURCE_ISP:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
+		else if (is_media_entity_v4l2_subdev(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_ISP);
 		else
 			ret = -EINVAL;
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/media-dev.c index 92dbade2fffc..4a25df9dd869 100644

drivers/media/platform/exynos4-is/media-dev.c +2 -3
@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
 break;
 		}
 
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 		sd = media_entity_to_v4l2_subdev(pad->entity);
 
@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct
 media_entity *entity, bool enable) media_entity_graph_walk_start(&graph,
 entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
drivers/media/platform/exynos4-is/media-dev.c +1 -1
 		ret  = __fimc_md_modify_pipeline(entity, enable);
@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct
 media_entity *entity, bool enable) media_entity_graph_walk_start(&graph,
 entity_err);
 
 	while ((entity_err = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity_err))
 			continue;
 
drivers/media/platform/exynos4-is/media-dev.c +0 -0
 		__fimc_md_modify_pipeline(entity_err, !enable);
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/isp.c index 69e7733d36cd..cb8ac90086c1 100644

drivers/media/platform/omap3isp/isp.c +4 -4
@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity
 *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)
+		if (is_media_entity_v4l2_io(entity))
 			use += entity->use_count;
 	}
 
@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity
 *entity, int change) struct v4l2_subdev *subdev;
 	int ret;
 
-	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 != NULL) {
@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity
 *entity, int change) 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)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = isp_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity
 *entity, int change)
 
 	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))
 			isp_pipeline_pm_power_one(first, -change);
 
drivers/media/platform/omap3isp/isp.c +2 -4
 	return ret;
@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline
 *pipe) break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispvideo.c index 4c367352b1f7..52843ac2a9ca 100644

drivers/media/platform/omap3isp/ispvideo.c +1 -2
@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32
 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
drivers/media/platform/omap3isp/ispvideo.c +2 -2
 	if (pad)
@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video
 *video, if (entity == &video->video.entity)
 			continue;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		__video = to_isp_video(media_entity_to_video_device(entity));
@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct
 isp_video *video, return -EINVAL;
 	}
 
-	if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(source))
 		return 0;
 
 	pipe->external = media_entity_to_v4l2_subdev(source);
(quoted diff) +0 -0

b/drivers/media/platform/s3c-camif/camif-capture.c index eae667eab1b9..fb5b016cc0a1 100644

drivers/media/platform/s3c-camif/camif-capture.c +1 -1
@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev
 *camif)
 
 	/* Retrieve format at the sensor subdev source pad */
 	pad = media_entity_remote_pad(&camif->pads[0]);
-	if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 		return -EPIPE;
 
drivers/media/platform/s3c-camif/camif-capture.c +0 -0
 	src_fmt.pad = pad->index;
(quoted diff) +0 -0

b/drivers/media/platform/vsp1/vsp1_video.c index 1f94c1a54e00..f74158224b93 100644

drivers/media/platform/vsp1/vsp1_video.c +4 -5
@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32
 *pad) struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct
 vsp1_pipeline *pipe, return -EPIPE;
 
 		/* We've reached a video node, that shouldn't have happened. */
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			return -EPIPE;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline
 *pipe, struct vsp1_rwpf *rwpf;
 		struct vsp1_entity *e;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (is_media_entity_v4l2_io(entity)) {
 			pipe->num_video++;
 			continue;
 		}
@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline
 *pipe, pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
 
 	while (pad) {
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
(quoted diff) +0 -0

b/drivers/media/platform/xilinx/xilinx-dma.c index 88cd789cdaf7..8e14841bf445 100644

drivers/media/platform/xilinx/xilinx-dma.c +2 -4
@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
 	struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline
 *pipe, bool start) break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
(quoted diff) +0 -0

b/drivers/media/v4l2-core/v4l2-subdev.c index e6e1115d8215..60da43772de9 100644

drivers/media/v4l2-core/v4l2-subdev.c +1 -1
@@ -526,7 +526,7 @@ static int
 v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 				     struct v4l2_subdev_format *fmt)
 {
-	if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
+	if (is_media_entity_v4l2_subdev(pad->entity)) {
 		struct v4l2_subdev *sd =
 			media_entity_to_v4l2_subdev(pad->entity);
 
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 92573fa852a9..16763e0831f2 100644

drivers/staging/media/davinci_vpfe/vpfe_video.c +0 -0
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct

vpfe_video_device *video) while ((entity =
media_entity_graph_walk_next(&graph))) {

drivers/staging/media/davinci_vpfe/vpfe_video.c +1 -1
 		if (entity == &video->video_dev.entity)
 			continue;
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if ((!is_media_entity_v4l2_io(remote->entity))
 			continue;
 		far_end = to_vpfe_video(media_entity_to_video_device(entity));
 		if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)

drivers/staging/media/davinci_vpfe/vpfe_video.c static int vpfe_pipeline_enable(struct vpfe_pipeline · line 296

Quoted 5 lines
drivers/staging/media/davinci_vpfe/vpfe_video.c +1 -1
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline
 *pipe) media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if !is_media_entity_v4l2_subdev(entity))

With these two chunks fixed,

I'm wondering, however, why you replace some occurrences of == MEDIA_ENT_T_DEVNODE with !is_media_entity_v4l2_subdev and some other with is_media_entity_v4l2_io.

Quoted 100 lines
drivers/staging/media/davinci_vpfe/vpfe_video.c +1 -1
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline
 *pipe)
 
 	while ((entity = media_entity_graph_walk_next(&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);
drivers/staging/media/davinci_vpfe/vpfe_video.c +0 -0
 		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss.c index 40591963b42b..44b88ff3ba83 100644

drivers/staging/media/omap4iss/iss.c +4 -4
@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity
 *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)
+		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 != NULL) {
@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity
 *entity, int change) 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)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = iss_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity
 *entity, int change)
 
 	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);
 
drivers/staging/media/omap4iss/iss.c +2 -4
 	return ret;
@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline
 *pipe, break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline
 *pipe, break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_video.c index 45a3f2d778fc..cbe5783735dc 100644

drivers/staging/media/omap4iss/iss_video.c +1 -2
@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32
 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
drivers/staging/media/omap4iss/iss_video.c +1 -1
 	if (pad)
@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)
 		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));
Signature · 3 lines
Regards,

Laurent Pinchart
#195 lore raw

PATCH v8 32/55 media: use macros to check for V4L2 subdev entities

Em Sun, 06 Dec 2015 04:16:15 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 377 lines

Hi Mauro,

Thank you for the patch.

Quoted 364 lines · On Sunday 30 August 2015 00:06:43 Mauro Carvalho Chehab wrote:

Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.

Please note that most drivers assume that there's just AV_DMA or V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.

Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the AV_DMA stuff.

(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/common.c index 0eb34ecb8ee4..8c9a29e0e294 100644

drivers/media/platform/exynos4-is/common.c +1 -2
@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct
 media_entity *entity) while (pad->flags & MEDIA_PAD_FL_SINK) {
 		/* source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/fimc-capture.c index 0627a93b2f3b..e9810fee4c30 100644

drivers/media/platform/exynos4-is/fimc-capture.c +2 -3
@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev
 *fimc) }
 		}
 
-		if (src_pad == NULL ||
-		    media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity))
 			break;
 
 		/* Don't call FIMC subdev operation to avoid nested locking */
@@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity
 *entity, struct fimc_vid_cap *vc = &fimc->vid_cap;
 	struct v4l2_subdev *sensor;
 
-	if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return -EINVAL;
 
 	if (WARN_ON(fimc == NULL))
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 3d9ccbf5f10f..5fbaf5e39903 100644

drivers/media/platform/exynos4-is/fimc-isp-video.c +1 -2
@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp
 *isp)
 
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
drivers/media/platform/exynos4-is/fimc-isp-video.c +0 -0
 		sd = media_entity_to_v4l2_subdev(pad->entity);
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/fimc-lite.c index b2607da4ad14..c2327147b360 100644

drivers/media/platform/exynos4-is/fimc-lite.c +2 -4
@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite
 *fimc) }
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity
 *entity, {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-	unsigned int remote_ent_type = media_entity_type(remote->entity);
 	int ret = 0;
 
 	if (WARN_ON(fimc == NULL))
@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity
 *entity,
 
 	switch (local->index) {
 	case FLITE_SD_PAD_SINK:
-		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (!is_media_entity_v4l2_subdev(remote->entity)) {
 			ret = -EINVAL;
 			break;
drivers/media/platform/exynos4-is/fimc-lite.c +2 -2
 		}
@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity
 *entity, case FLITE_SD_PAD_SOURCE_DMA:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_DEVNODE)
+		else if (is_media_entity_v4l2_io(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_DMA);
 		else
 			ret = -EINVAL;
@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity
 *entity, case FLITE_SD_PAD_SOURCE_ISP:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
+		else if (is_media_entity_v4l2_subdev(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_ISP);
 		else
 			ret = -EINVAL;
(quoted diff) +0 -0

b/drivers/media/platform/exynos4-is/media-dev.c index 92dbade2fffc..4a25df9dd869 100644

drivers/media/platform/exynos4-is/media-dev.c +2 -3
@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
 break;
 		}
 
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 		sd = media_entity_to_v4l2_subdev(pad->entity);
 
@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct
 media_entity *entity, bool enable) media_entity_graph_walk_start(&graph,
 entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
drivers/media/platform/exynos4-is/media-dev.c +1 -1
 		ret  = __fimc_md_modify_pipeline(entity, enable);
@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct
 media_entity *entity, bool enable) media_entity_graph_walk_start(&graph,
 entity_err);
 
 	while ((entity_err = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity_err))
 			continue;
 
drivers/media/platform/exynos4-is/media-dev.c +0 -0
 		__fimc_md_modify_pipeline(entity_err, !enable);
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/isp.c index 69e7733d36cd..cb8ac90086c1 100644

drivers/media/platform/omap3isp/isp.c +4 -4
@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity
 *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)
+		if (is_media_entity_v4l2_io(entity))
 			use += entity->use_count;
 	}
 
@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity
 *entity, int change) struct v4l2_subdev *subdev;
 	int ret;
 
-	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 != NULL) {
@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity
 *entity, int change) 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)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = isp_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity
 *entity, int change)
 
 	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))
 			isp_pipeline_pm_power_one(first, -change);
 
drivers/media/platform/omap3isp/isp.c +2 -4
 	return ret;
@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline
 *pipe) break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispvideo.c index 4c367352b1f7..52843ac2a9ca 100644

drivers/media/platform/omap3isp/ispvideo.c +1 -2
@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32
 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
drivers/media/platform/omap3isp/ispvideo.c +2 -2
 	if (pad)
@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video
 *video, if (entity == &video->video.entity)
 			continue;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		__video = to_isp_video(media_entity_to_video_device(entity));
@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct
 isp_video *video, return -EINVAL;
 	}
 
-	if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(source))
 		return 0;
 
 	pipe->external = media_entity_to_v4l2_subdev(source);
(quoted diff) +0 -0

b/drivers/media/platform/s3c-camif/camif-capture.c index eae667eab1b9..fb5b016cc0a1 100644

drivers/media/platform/s3c-camif/camif-capture.c +1 -1
@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev
 *camif)
 
 	/* Retrieve format at the sensor subdev source pad */
 	pad = media_entity_remote_pad(&camif->pads[0]);
-	if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 		return -EPIPE;
 
drivers/media/platform/s3c-camif/camif-capture.c +0 -0
 	src_fmt.pad = pad->index;
(quoted diff) +0 -0

b/drivers/media/platform/vsp1/vsp1_video.c index 1f94c1a54e00..f74158224b93 100644

drivers/media/platform/vsp1/vsp1_video.c +4 -5
@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32
 *pad) struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct
 vsp1_pipeline *pipe, return -EPIPE;
 
 		/* We've reached a video node, that shouldn't have happened. */
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			return -EPIPE;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline
 *pipe, struct vsp1_rwpf *rwpf;
 		struct vsp1_entity *e;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (is_media_entity_v4l2_io(entity)) {
 			pipe->num_video++;
 			continue;
 		}
@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline
 *pipe, pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
 
 	while (pad) {
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
(quoted diff) +0 -0

b/drivers/media/platform/xilinx/xilinx-dma.c index 88cd789cdaf7..8e14841bf445 100644

drivers/media/platform/xilinx/xilinx-dma.c +2 -4
@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
 	struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline
 *pipe, bool start) break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
(quoted diff) +0 -0

b/drivers/media/v4l2-core/v4l2-subdev.c index e6e1115d8215..60da43772de9 100644

drivers/media/v4l2-core/v4l2-subdev.c +1 -1
@@ -526,7 +526,7 @@ static int
 v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 				     struct v4l2_subdev_format *fmt)
 {
-	if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
+	if (is_media_entity_v4l2_subdev(pad->entity)) {
 		struct v4l2_subdev *sd =
 			media_entity_to_v4l2_subdev(pad->entity);
 
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 92573fa852a9..16763e0831f2 100644

drivers/staging/media/davinci_vpfe/vpfe_video.c +0 -0
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct

vpfe_video_device *video) while ((entity =
media_entity_graph_walk_next(&graph))) {

drivers/staging/media/davinci_vpfe/vpfe_video.c +1 -1
 		if (entity == &video->video_dev.entity)
 			continue;
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if ((!is_media_entity_v4l2_io(remote->entity))
 			continue;
 		far_end = to_vpfe_video(media_entity_to_video_device(entity));
 		if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)

drivers/staging/media/davinci_vpfe/vpfe_video.c static int vpfe_pipeline_enable(struct vpfe_pipeline · line 296

Quoted 5 lines
drivers/staging/media/davinci_vpfe/vpfe_video.c +1 -1
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline
 *pipe) media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if !is_media_entity_v4l2_subdev(entity))

With these two chunks fixed,

Quoted 5 lines

I'm wondering, however, why you replace some occurrences of == MEDIA_ENT_T_DEVNODE with !is_media_entity_v4l2_subdev and some other with is_media_entity_v4l2_io.

For devices that don't have non-V4L2 media controller nodes, this would work, but if we ever add ALSA, DVB, IIO, etc to the media controller, then we may have troubles.

That's why I opted to add a macro for checking for the V4L2 subdev. This is more future-proof, as other patches may be adding other non-V4L2 types of MC entities have the potential of breaking codes like the above.

Quoted 102 lines
Quoted 101 lines
drivers/staging/media/davinci_vpfe/vpfe_video.c +1 -1
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline
 *pipe)
 
 	while ((entity = media_entity_graph_walk_next(&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);
drivers/staging/media/davinci_vpfe/vpfe_video.c +0 -0
 		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss.c index 40591963b42b..44b88ff3ba83 100644

drivers/staging/media/omap4iss/iss.c +4 -4
@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity
 *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)
+		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 != NULL) {
@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity
 *entity, int change) 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)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = iss_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity
 *entity, int change)
 
 	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);
 
drivers/staging/media/omap4iss/iss.c +2 -4
 	return ret;
@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline
 *pipe, break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline
 *pipe, break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_video.c index 45a3f2d778fc..cbe5783735dc 100644

drivers/staging/media/omap4iss/iss_video.c +1 -2
@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32
 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
drivers/staging/media/omap4iss/iss_video.c +1 -1
 	if (pad)
@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)
 		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));
#196 lore raw

PATCH v8 33/55 omap3/omap4/davinci: get rid of MEDIA_ENT_T_V4L2_SUBDEV abuse

In reply to Mauro Carvalho Chehab

On omap3/omap4/davinci drivers, MEDIA_ENT_T_V4L2_SUBDEV macro is abused in order to "simplify" the pad checks.

Basically, it does a logical or of this macro, in order to check for a local index and if the entity is either a subdev or not.

As we'll get rid of MEDIA_ENT_T_V4L2_SUBDEV macro, replace it by 2 << 16 where it occurs, and add a note saying that the code there is actually a hack.

drivers/media/platform/omap3isp/ispccdc.c +10 -5
index 9a811f5741fa..f0e530c98188 100644
@@ -2513,9 +2513,14 @@ static int ccdc_link_setup(struct media_entity *entity,
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
 	struct isp_device *isp = to_isp_device(ccdc);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case CCDC_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 CCDC_PAD_SINK | 2 << 16:
 		/* Read from the sensor (parallel interface), CCP2, CSI2a or
 		 * CSI2c.
 		 */
@@ -2543,7 +2548,7 @@ static int ccdc_link_setup(struct media_entity *entity,
 	 * Revisit this when it will be implemented, and return -EBUSY for now.
 	 */
 
-	case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCDC_PAD_SOURCE_VP | 2 << 16:
 		/* Write to preview engine, histogram and H3A. When none of
 		 * those links are active, the video port can be disabled.
 		 */
@@ -2556,7 +2561,7 @@ static int ccdc_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
+	case CCDC_PAD_SOURCE_OF:
 		/* Write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
@@ -2567,7 +2572,7 @@ static int ccdc_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCDC_PAD_SOURCE_OF | 2 << 16:
 		/* Write to resizer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
drivers/media/platform/omap3isp/ispccp2.c +9 -4
index 6ec7d104ab75..ae3038e643cc 100644
@@ -956,9 +956,14 @@ static int ccp2_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case CCP2_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 CCP2_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccp2->input == CCP2_INPUT_SENSOR)
@@ -970,7 +975,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCP2_PAD_SINK | 2 << 16:
 		/* read from sensor/phy */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccp2->input == CCP2_INPUT_MEMORY)
@@ -981,7 +986,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 				ccp2->input = CCP2_INPUT_NONE;
 		} break;
 
-	case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCP2_PAD_SOURCE | 2 << 16:
 		/* write to video port/ccdc */
 		if (flags & MEDIA_LNK_FL_ENABLED)
 			ccp2->output = CCP2_OUTPUT_CCDC;
drivers/media/platform/omap3isp/ispcsi2.c +8 -3
index 0fb057a74f69..b1617f7efdee 100644
@@ -1144,14 +1144,19 @@ static int csi2_link_setup(struct media_entity *entity,
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
 	struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
+	int index = local->index;
 
 	/*
 	 * The ISP 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:
+	/* FIXME: this is actually a hack! */
+	if (is_media_entity_v4l2_subdev(remote->entity))
+		index |= 2 << 16;
+
+	switch (index) {
+	case CSI2_PAD_SOURCE:
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi2->output & ~CSI2_OUTPUT_MEMORY)
 				return -EBUSY;
@@ -1161,7 +1166,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_CCDC)
 				return -EBUSY;
drivers/media/platform/omap3isp/isppreview.c +10 -5
index 6986d2f65c19..cfb2debb02bf 100644
@@ -2144,9 +2144,14 @@ static int preview_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case PREV_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 PREV_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->input == PREVIEW_INPUT_CCDC)
@@ -2158,7 +2163,7 @@ static int preview_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case PREV_PAD_SINK | 2 << 16:
 		/* read from ccdc */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->input == PREVIEW_INPUT_MEMORY)
@@ -2175,7 +2180,7 @@ static int preview_link_setup(struct media_entity *entity,
 	 * Revisit this when it will be implemented, and return -EBUSY for now.
 	 */
 
-	case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+	case PREV_PAD_SOURCE:
 		/* write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
@@ -2186,7 +2191,7 @@ static int preview_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+	case PREV_PAD_SOURCE | 2 << 16:
 		/* write to resizer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
drivers/media/platform/omap3isp/ispresizer.c +9 -4
index 249af7f524f9..e3ecf1787fc4 100644
@@ -1623,9 +1623,14 @@ static int resizer_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_res_device *res = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case RESZ_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 RESZ_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (res->input == RESIZER_INPUT_VP)
@@ -1637,7 +1642,7 @@ static int resizer_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case RESZ_PAD_SINK | 2 << 16:
 		/* read from ccdc or previewer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (res->input == RESIZER_INPUT_MEMORY)
@@ -1649,7 +1654,7 @@ static int resizer_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+	case RESZ_PAD_SOURCE:
 		/* resizer always write to memory */
 		break;
 
drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +9 -4
index d96bdaaae50e..b66584ecb693 100644
@@ -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);
+	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;
drivers/staging/media/davinci_vpfe/dm365_isif.c +9 -4
index df77288b0ec0..8ca0c1297ec8 100644
@@ -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);
+	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
drivers/staging/media/davinci_vpfe/dm365_resizer.c +15 -10
index ae942de3a23d..8eb6f5fda21c 100644
@@ -1653,10 +1653,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;
+	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;
@@ -1676,7 +1681,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;
@@ -1688,7 +1693,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;
@@ -1704,8 +1709,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;
@@ -1715,7 +1720,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;
@@ -1729,8 +1734,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;
@@ -1740,7 +1745,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;
drivers/staging/media/davinci_vpfe/vpfe_video.c +2 -2
index 16763e0831f2..9eef64e0f0ab 100644
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 		if (entity == &video->video_dev.entity)
 			continue;
-		if ((!is_media_entity_v4l2_io(remote->entity))
+		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)
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if !is_media_entity_v4l2_subdev(entity))
+		if (!is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
drivers/staging/media/omap4iss/iss_csi2.c +8 -3
index 6b4dcbfa9425..50a24e8e8129 100644
@@ -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;
+	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;
drivers/staging/media/omap4iss/iss_ipipeif.c +9 -4
index 44c432ef2ac5..e46b2c07bd5d 100644
@@ -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);
+	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)
drivers/staging/media/omap4iss/iss_resizer.c +8 -3
index b659e465cb56..bc5001002cc5 100644
@@ -717,9 +717,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);
+	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;
@@ -737,7 +742,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)
Signature · 1 line
2.4.3
maintainer
#197 lore raw

Re: [PATCH v8 33/55] [media] omap3/omap4/davinci: get rid of MEDIA_ENT_T_V4L2_SUBDEV abuse

Hi Mauro,

Thank you for the patch.

Quoted 2 lines · On Sunday 30 August 2015 00:06:44 Mauro Carvalho Chehab wrote:

On omap3/omap4/davinci drivers, MEDIA_ENT_T_V4L2_SUBDEV macro is abused in order to "simplify" the pad checks.

As explained in a couple of other replies to similar patches, it's not a hack :-)

Quoted 4 lines

Basically, it does a logical or of this macro, in order to check for a local index and if the entity is either a subdev or not.

As we'll get rid of MEDIA_ENT_T_V4L2_SUBDEV macro,

This is the reason for this patch, and I agree with it.

Quoted 11 lines

replace it by 2 << 16 where it occurs, and add a note saying that the code there is actually a hack.

(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispccdc.c index
9a811f5741fa..f0e530c98188 100644

drivers/media/platform/omap3isp/ispccdc.c static int ccdc_link_setup(struct media_entity · line 2516

Quoted 4 lines
drivers/media/platform/omap3isp/ispccdc.c +1 -0
@@ -2513,9 +2513,14 @@ static int ccdc_link_setup(struct media_entity
 *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
 	struct isp_device *isp = to_isp_device(ccdc);
+	int index = local->index;

The index can never be negative, you can use unsigned int.

drivers/media/platform/omap3isp/ispccdc.c static int ccdc_link_setup(struct media_entity *entity, · line 2518

Quoted 4 lines
drivers/media/platform/omap3isp/ispccdc.c +1 -2
-	switch (local->index | media_entity_type(remote->entity)) {
-	case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	/* FIXME: this is actually a hack! */

Please, let's not introduce a hack to replace valid code. I'm certainly fine with removing usage of MEDIA_ENT_T_V4L2_SUBDEV, but drivers should be modified cleanly.

If you rename the index variable to link and use a macro (I would call it LINK_TO_SUBDEV for instance) instead of 2 << 16 the implementation wouldn't be that bad, as what the switch operates on is the link, not the pad. I would also create a LINK_TO_DEVNODE macro, even if it evaluates to 0, to clearly label each case.

drivers/media/platform/omap3isp/ispccdc.c static int ccdc_link_setup(struct media_entity · line 2519

Quoted 2 lines
drivers/media/platform/omap3isp/ispccdc.c +2 -0
+	if (is_media_entity_v4l2_subdev(remote->entity))
+		index |= 2 << 16;

Why 2 << 16 and not 1 << 16 ?

Same comments for all the other files below (but please see the very end for one last comment).

Quoted 483 lines
drivers/media/platform/omap3isp/ispccdc.c +2 -0
+	switch (index) {
+	case CCDC_PAD_SINK | 2 << 16:
 		/* Read from the sensor (parallel interface), CCP2, CSI2a or
 		 * CSI2c.
 		 */
@@ -2543,7 +2548,7 @@ static int ccdc_link_setup(struct media_entity
 *entity, * Revisit this when it will be implemented, and return -EBUSY for

now. */

drivers/media/platform/omap3isp/ispccdc.c +3 -3
-	case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCDC_PAD_SOURCE_VP | 2 << 16:
 		/* Write to preview engine, histogram and H3A. When none of
 		 * those links are active, the video port can be disabled.
 		 */
@@ -2556,7 +2561,7 @@ static int ccdc_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
+	case CCDC_PAD_SOURCE_OF:
 		/* Write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
@@ -2567,7 +2572,7 @@ static int ccdc_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCDC_PAD_SOURCE_OF | 2 << 16:
 		/* Write to resizer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispccp2.c index
6ec7d104ab75..ae3038e643cc 100644

drivers/media/platform/omap3isp/ispccp2.c +9 -4
@@ -956,9 +956,14 @@ static int ccp2_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case CCP2_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 CCP2_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccp2->input == CCP2_INPUT_SENSOR)
@@ -970,7 +975,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCP2_PAD_SINK | 2 << 16:
 		/* read from sensor/phy */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccp2->input == CCP2_INPUT_MEMORY)
@@ -981,7 +986,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 				ccp2->input = CCP2_INPUT_NONE;
 		} break;
 
-	case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCP2_PAD_SOURCE | 2 << 16:
 		/* write to video port/ccdc */
 		if (flags & MEDIA_LNK_FL_ENABLED)
 			ccp2->output = CCP2_OUTPUT_CCDC;
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispcsi2.c index
0fb057a74f69..b1617f7efdee 100644

drivers/media/platform/omap3isp/ispcsi2.c +8 -3
@@ -1144,14 +1144,19 @@ static int csi2_link_setup(struct media_entity
 *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
 	struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
+	int index = local->index;
 
 	/*
 	 * The ISP 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:
+	/* FIXME: this is actually a hack! */
+	if (is_media_entity_v4l2_subdev(remote->entity))
+		index |= 2 << 16;
+
+	switch (index) {
+	case CSI2_PAD_SOURCE:
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi2->output & ~CSI2_OUTPUT_MEMORY)
 				return -EBUSY;
@@ -1161,7 +1166,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_CCDC)
 				return -EBUSY;
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/isppreview.c index 6986d2f65c19..cfb2debb02bf 100644

drivers/media/platform/omap3isp/isppreview.c +8 -3
@@ -2144,9 +2144,14 @@ static int preview_link_setup(struct media_entity
 *entity, {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case PREV_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 PREV_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->input == PREVIEW_INPUT_CCDC)
@@ -2158,7 +2163,7 @@ static int preview_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case PREV_PAD_SINK | 2 << 16:
 		/* read from ccdc */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->input == PREVIEW_INPUT_MEMORY)
@@ -2175,7 +2180,7 @@ static int preview_link_setup(struct media_entity
 *entity, * Revisit this when it will be implemented, and return -EBUSY for

now. */

drivers/media/platform/omap3isp/isppreview.c +2 -2
-	case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+	case PREV_PAD_SOURCE:
 		/* write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
@@ -2186,7 +2191,7 @@ static int preview_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+	case PREV_PAD_SOURCE | 2 << 16:
 		/* write to resizer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispresizer.c index 249af7f524f9..e3ecf1787fc4 100644

drivers/media/platform/omap3isp/ispresizer.c +9 -4
@@ -1623,9 +1623,14 @@ static int resizer_link_setup(struct media_entity
 *entity, {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_res_device *res = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case RESZ_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 RESZ_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (res->input == RESIZER_INPUT_VP)
@@ -1637,7 +1642,7 @@ static int resizer_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case RESZ_PAD_SINK | 2 << 16:
 		/* read from ccdc or previewer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (res->input == RESIZER_INPUT_MEMORY)
@@ -1649,7 +1654,7 @@ static int resizer_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+	case RESZ_PAD_SOURCE:
 		/* resizer always write to memory */
 		break;
 
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index d96bdaaae50e..b66584ecb693 100644

drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +0 -0
@@ -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);

drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +9 -4
 	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
 	struct vpfe_device *vpfe = to_vpfe_device(ipipeif);
+	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;
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_isif.c index df77288b0ec0..8ca0c1297ec8 100644

drivers/staging/media/davinci_vpfe/dm365_isif.c +9 -4
@@ -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);
+	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
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index ae942de3a23d..8eb6f5fda21c 100644

drivers/staging/media/davinci_vpfe/dm365_resizer.c +15 -10
@@ -1653,10 +1653,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;
+	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;
@@ -1676,7 +1681,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;
@@ -1688,7 +1693,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;
@@ -1704,8 +1709,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;
@@ -1715,7 +1720,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;
@@ -1729,8 +1734,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;
@@ -1740,7 +1745,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;
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 16763e0831f2..9eef64e0f0ab 100644

drivers/staging/media/davinci_vpfe/vpfe_video.c +0 -0
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct

vpfe_video_device *video) while ((entity =
media_entity_graph_walk_next(&graph))) {

drivers/staging/media/davinci_vpfe/vpfe_video.c +2 -2
 		if (entity == &video->video_dev.entity)
 			continue;
-		if ((!is_media_entity_v4l2_io(remote->entity))
+		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)
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline
 *pipe) media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if !is_media_entity_v4l2_subdev(entity))
+		if (!is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_csi2.c index
6b4dcbfa9425..50a24e8e8129 100644

drivers/staging/media/omap4iss/iss_csi2.c +8 -3
@@ -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;
+	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;
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_ipipeif.c index 44c432ef2ac5..e46b2c07bd5d 100644

drivers/staging/media/omap4iss/iss_ipipeif.c +8 -3
@@ -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);
+	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) {
drivers/staging/media/omap4iss/iss_ipipeif.c +1 -1
 			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)
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_resizer.c index b659e465cb56..bc5001002cc5 100644

drivers/staging/media/omap4iss/iss_resizer.c +7 -2
@@ -717,9 +717,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);
+	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;

drivers/staging/media/omap4iss/iss_resizer.c static int resizer_link_setup(struct media_entity · line 746

Quoted 6 lines
drivers/staging/media/omap4iss/iss_resizer.c +1 -1
@@ -737,7 +742,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 :

There's an unneeded space before the :.

Quoted 3 lines
drivers/staging/media/omap4iss/iss_resizer.c +0 -0
 		/* Write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {

if (resizer->output & ~RESIZER_OUTPUT_MEMORY)

Signature · 3 lines
Regards,

Laurent Pinchart
#198 lore raw

Re: [PATCH v8 33/55] [media] omap3/omap4/davinci: get rid of MEDIA_ENT_T_V4L2_SUBDEV abuse

Em Sun, 06 Dec 2015 04:08:17 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 10 lines

Hi Mauro,

Thank you for the patch.

Quoted 2 lines · On Sunday 30 August 2015 00:06:44 Mauro Carvalho Chehab wrote:

On omap3/omap4/davinci drivers, MEDIA_ENT_T_V4L2_SUBDEV macro is abused in order to "simplify" the pad checks.

As explained in a couple of other replies to similar patches, it's not a hack :-)

That's actually the first reply (at least looking at the patches order ;)

This is a hack, since it mixes a global subdev type with a private PAD type, defined only inside the driver, on switch cases like:
CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:

That implicitly consider that:

	local->index | media_entity_type(remote->entity)

will be a number where the local->index bits will never ever be used by media_entity_type() return macro.

With such assumption, any change at the numberspace returned by media_entity_type() would break the driver, and people changing the core won't even be noticing it, as this is a driver-specific thing.

There's absolute nothing inside the core, even before this patchset that would warrant that the bits used by local->index (CCDC_PAD_SINK and CCDC_PAD_SOURCE) won't be used on media_entity_type() return value.

So, for me this is a hack, and a dangerous one, because it adds hidden namespace coupling inside the driver that would break if the core changes.

Quoted 13 lines
Quoted 5 lines

Basically, it does a logical or of this macro, in order to check for a local index and if the entity is either a subdev or not.

As we'll get rid of MEDIA_ENT_T_V4L2_SUBDEV macro,

This is the reason for this patch, and I agree with it.

Quoted 5 lines

replace it by 2 << 16 where it occurs, and add a note saying that the code there is actually a hack.

Quoted 12 lines

drivers/media/platform/omap3isp/ispccdc.c static int ccdc_link_setup(struct media_entity · line 2516

Quoted 10 lines
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispccdc.c index
9a811f5741fa..f0e530c98188 100644

drivers/media/platform/omap3isp/ispccdc.c +1 -0
@@ -2513,9 +2513,14 @@ static int ccdc_link_setup(struct media_entity
 *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
 	struct isp_device *isp = to_isp_device(ccdc);
+	int index = local->index;

The index can never be negative, you can use unsigned int.

Ok. Will address on a later patch.

Quoted 9 lines

drivers/media/platform/omap3isp/ispccdc.c static int ccdc_link_setup(struct media_entity *entity, · line 2518

Quoted 5 lines
drivers/media/platform/omap3isp/ispccdc.c +1 -2
-	switch (local->index | media_entity_type(remote->entity)) {
-	case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	/* FIXME: this is actually a hack! */

Please, let's not introduce a hack to replace valid code. I'm certainly fine with removing usage of MEDIA_ENT_T_V4L2_SUBDEV, but drivers should be modified cleanly.

I just preserved the existing hack, by replacing MEDIA_ENT_T_V4L2_SUBDEV macro that will be removed by its value (2 << 16).

Quoted 5 lines

If you rename the index variable to link and use a macro (I would call it LINK_TO_SUBDEV for instance) instead of 2 << 16 the implementation wouldn't be that bad, as what the switch operates on is the link, not the pad. I would also create a LINK_TO_DEVNODE macro, even if it evaluates to 0, to clearly label each case.

Sorry but I didn't follow you here. Could you please send us a patch or a code example explaining what you're meaning?

Quoted 5 lines

drivers/media/platform/omap3isp/ispccdc.c static int ccdc_link_setup(struct media_entity · line 2519

Quoted 3 lines
drivers/media/platform/omap3isp/ispccdc.c +2 -0
+	if (is_media_entity_v4l2_subdev(remote->entity))
+		index |= 2 << 16;

Why 2 << 16 and not 1 << 16 ?

Because that's the value of MEDIA_ENT_T_V4L2_SUBDEV. This is a hack:
any value here is just a magic number with no physical meaning.

Using 1 << 16 would be as good or as bad as 2 << 16.

Quoted 488 lines

Same comments for all the other files below (but please see the very end for one last comment).

Quoted 485 lines
drivers/media/platform/omap3isp/ispccdc.c +2 -0
+	switch (index) {
+	case CCDC_PAD_SINK | 2 << 16:
 		/* Read from the sensor (parallel interface), CCP2, CSI2a or
 		 * CSI2c.
 		 */
@@ -2543,7 +2548,7 @@ static int ccdc_link_setup(struct media_entity
 *entity, * Revisit this when it will be implemented, and return -EBUSY for

now. */

drivers/media/platform/omap3isp/ispccdc.c +3 -3
-	case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCDC_PAD_SOURCE_VP | 2 << 16:
 		/* Write to preview engine, histogram and H3A. When none of
 		 * those links are active, the video port can be disabled.
 		 */
@@ -2556,7 +2561,7 @@ static int ccdc_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
+	case CCDC_PAD_SOURCE_OF:
 		/* Write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
@@ -2567,7 +2572,7 @@ static int ccdc_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCDC_PAD_SOURCE_OF | 2 << 16:
 		/* Write to resizer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispccp2.c index
6ec7d104ab75..ae3038e643cc 100644

drivers/media/platform/omap3isp/ispccp2.c +9 -4
@@ -956,9 +956,14 @@ static int ccp2_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case CCP2_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 CCP2_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccp2->input == CCP2_INPUT_SENSOR)
@@ -970,7 +975,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 		}
 		break;
 
-	case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCP2_PAD_SINK | 2 << 16:
 		/* read from sensor/phy */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (ccp2->input == CCP2_INPUT_MEMORY)
@@ -981,7 +986,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 				ccp2->input = CCP2_INPUT_NONE;
 		} break;
 
-	case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+	case CCP2_PAD_SOURCE | 2 << 16:
 		/* write to video port/ccdc */
 		if (flags & MEDIA_LNK_FL_ENABLED)
 			ccp2->output = CCP2_OUTPUT_CCDC;
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispcsi2.c index
0fb057a74f69..b1617f7efdee 100644

drivers/media/platform/omap3isp/ispcsi2.c +8 -3
@@ -1144,14 +1144,19 @@ static int csi2_link_setup(struct media_entity
 *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
 	struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
+	int index = local->index;
 
 	/*
 	 * The ISP 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:
+	/* FIXME: this is actually a hack! */
+	if (is_media_entity_v4l2_subdev(remote->entity))
+		index |= 2 << 16;
+
+	switch (index) {
+	case CSI2_PAD_SOURCE:
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi2->output & ~CSI2_OUTPUT_MEMORY)
 				return -EBUSY;
@@ -1161,7 +1166,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_CCDC)
 				return -EBUSY;
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/isppreview.c index 6986d2f65c19..cfb2debb02bf 100644

drivers/media/platform/omap3isp/isppreview.c +8 -3
@@ -2144,9 +2144,14 @@ static int preview_link_setup(struct media_entity
 *entity, {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case PREV_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 PREV_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->input == PREVIEW_INPUT_CCDC)
@@ -2158,7 +2163,7 @@ static int preview_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case PREV_PAD_SINK | 2 << 16:
 		/* read from ccdc */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->input == PREVIEW_INPUT_MEMORY)
@@ -2175,7 +2180,7 @@ static int preview_link_setup(struct media_entity
 *entity, * Revisit this when it will be implemented, and return -EBUSY for

now. */

drivers/media/platform/omap3isp/isppreview.c +2 -2
-	case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+	case PREV_PAD_SOURCE:
 		/* write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
@@ -2186,7 +2191,7 @@ static int preview_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
+	case PREV_PAD_SOURCE | 2 << 16:
 		/* write to resizer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
(quoted diff) +0 -0

b/drivers/media/platform/omap3isp/ispresizer.c index 249af7f524f9..e3ecf1787fc4 100644

drivers/media/platform/omap3isp/ispresizer.c +9 -4
@@ -1623,9 +1623,14 @@ static int resizer_link_setup(struct media_entity
 *entity, {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct isp_res_device *res = v4l2_get_subdevdata(sd);
+	int index = local->index;
 
-	switch (local->index | media_entity_type(remote->entity)) {
-	case RESZ_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 RESZ_PAD_SINK:
 		/* read from memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (res->input == RESIZER_INPUT_VP)
@@ -1637,7 +1642,7 @@ static int resizer_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
+	case RESZ_PAD_SINK | 2 << 16:
 		/* read from ccdc or previewer */
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (res->input == RESIZER_INPUT_MEMORY)
@@ -1649,7 +1654,7 @@ static int resizer_link_setup(struct media_entity
 *entity, }
 		break;
 
-	case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
+	case RESZ_PAD_SOURCE:
 		/* resizer always write to memory */
 		break;
 
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index d96bdaaae50e..b66584ecb693 100644

drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +0 -0
@@ -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);

drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +9 -4
 	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
 	struct vpfe_device *vpfe = to_vpfe_device(ipipeif);
+	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;
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_isif.c index df77288b0ec0..8ca0c1297ec8 100644

drivers/staging/media/davinci_vpfe/dm365_isif.c +9 -4
@@ -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);
+	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
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index ae942de3a23d..8eb6f5fda21c 100644

drivers/staging/media/davinci_vpfe/dm365_resizer.c +15 -10
@@ -1653,10 +1653,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;
+	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;
@@ -1676,7 +1681,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;
@@ -1688,7 +1693,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;
@@ -1704,8 +1709,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;
@@ -1715,7 +1720,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;
@@ -1729,8 +1734,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;
@@ -1740,7 +1745,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;
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 16763e0831f2..9eef64e0f0ab 100644

drivers/staging/media/davinci_vpfe/vpfe_video.c +0 -0
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct

vpfe_video_device *video) while ((entity =
media_entity_graph_walk_next(&graph))) {

drivers/staging/media/davinci_vpfe/vpfe_video.c +2 -2
 		if (entity == &video->video_dev.entity)
 			continue;
-		if ((!is_media_entity_v4l2_io(remote->entity))
+		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)
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline
 *pipe) media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if !is_media_entity_v4l2_subdev(entity))
+		if (!is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_csi2.c index
6b4dcbfa9425..50a24e8e8129 100644

drivers/staging/media/omap4iss/iss_csi2.c +8 -3
@@ -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;
+	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;
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_ipipeif.c index 44c432ef2ac5..e46b2c07bd5d 100644

drivers/staging/media/omap4iss/iss_ipipeif.c +8 -3
@@ -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);
+	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) {
drivers/staging/media/omap4iss/iss_ipipeif.c +1 -1
 			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)
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_resizer.c index b659e465cb56..bc5001002cc5 100644

drivers/staging/media/omap4iss/iss_resizer.c +7 -2
@@ -717,9 +717,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);
+	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;
@@ -737,7 +742,7 @@ static int resizer_link_setup(struct media_entity
 *entity,
 
Quoted 6 lines

drivers/staging/media/omap4iss/iss_resizer.c static int resizer_link_setup(struct media_entity *entity, · line 745

Quoted 4 lines
drivers/staging/media/omap4iss/iss_resizer.c +1 -1
 		break;
 
-	case RESIZER_PAD_SOURCE_MEM | MEDIA_ENT_T_DEVNODE:
+	case RESIZER_PAD_SOURCE_MEM :

There's an unneeded space before the :.

That change is simple enough and very likely won't cause any rebasing conflict or context changes, so, fixed.

Quoted 5 lines
Quoted 4 lines
drivers/staging/media/omap4iss/iss_resizer.c +0 -0
 		/* Write to memory */
 		if (flags & MEDIA_LNK_FL_ENABLED) {

if (resizer->output & ~RESIZER_OUTPUT_MEMORY)

#199 lore raw

PATCH v8 34/55 s5c73m3: fix subdev type

In reply to Mauro Carvalho Chehab

This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.

As this is a sensor driver, the proper type is likely MEDIA_ENT_T_CAM_SENSOR.

drivers/media/i2c/s5c73m3/s5c73m3-core.c +2 -2
index c81bfbfea32f..abae37321c0c 100644
@@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 
 	state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE;
 	state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 
 	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS,
 							state->sensor_pads);
@@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK;
 	state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK;
 	state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
-	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 
 	ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS,
 							state->oif_pads);
Signature · 1 line
2.4.3
maintainer
#200 lore raw

Re: [PATCH v8 34/55] [media] s5c73m3: fix subdev type

Hi Mauro,

Thank you for the patch.

Quoted 14 lines · On Sunday 30 August 2015 00:06:45 Mauro Carvalho Chehab wrote:

This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.

As this is a sensor driver, the proper type is likely MEDIA_ENT_T_CAM_SENSOR.

(quoted diff) +0 -0

b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index c81bfbfea32f..abae37321c0c 100644

drivers/media/i2c/s5c73m3/s5c73m3-core.c static int s5c73m3_probe(struct i2c_client *client, · line 1691

Quoted 5 lines
drivers/media/i2c/s5c73m3/s5c73m3-core.c +1 -1
@@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 
 	state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE;
 	state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

As explained in my review of "s5k5baf: fix subdev type", this is correct...

drivers/media/i2c/s5c73m3/s5c73m3-core.c static int s5c73m3_probe(struct i2c_client *client, · line 1707

Quoted 8 lines
drivers/media/i2c/s5c73m3/s5c73m3-core.c +1 -1
 	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS,
 							state->sensor_pads);
@@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK;
 	state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK;
 	state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
-	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

... but this isn't.

Quoted 2 lines
drivers/media/i2c/s5c73m3/s5c73m3-core.c +0 -0
 	ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS,
 							state->oif_pads);
Signature · 3 lines
Regards,

Laurent Pinchart
#201 lore raw

Re: [PATCH v8 34/55] [media] s5c73m3: fix subdev type

Em Sun, 06 Dec 2015 03:57:56 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 27 lines

Hi Mauro,

Thank you for the patch.

Quoted 14 lines · On Sunday 30 August 2015 00:06:45 Mauro Carvalho Chehab wrote:

This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.

As this is a sensor driver, the proper type is likely MEDIA_ENT_T_CAM_SENSOR.

(quoted diff) +0 -0

b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index c81bfbfea32f..abae37321c0c 100644

drivers/media/i2c/s5c73m3/s5c73m3-core.c static int s5c73m3_probe(struct i2c_client *client, · line 1691

Quoted 5 lines
drivers/media/i2c/s5c73m3/s5c73m3-core.c +1 -1
@@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 
 	state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE;
 	state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

As explained in my review of "s5k5baf: fix subdev type", this is correct...

Quoted 10 lines

drivers/media/i2c/s5c73m3/s5c73m3-core.c static int s5c73m3_probe(struct i2c_client *client, · line 1707

Quoted 8 lines
drivers/media/i2c/s5c73m3/s5c73m3-core.c +1 -1
 	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS,
 							state->sensor_pads);
@@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK;
 	state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK;
 	state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
-	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

... but this isn't.

Ok. Replacing this hunk by:

- oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;

Quoted 4 lines
Quoted 3 lines
drivers/media/i2c/s5c73m3/s5c73m3-core.c +0 -0
 	ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS,
 							state->oif_pads);
#202 lore raw

PATCH v8 35/55 s5k5baf: fix subdev type

In reply to Mauro Carvalho Chehab

X-Patchwork-Delegate: [email protected]
This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.

As this is a sensor driver, the proper type is likely MEDIA_ENT_T_V4L2_SUBDEV_SENSOR.

drivers/media/i2c/s5k5baf.c +1 -1
index d3bff30bcb6f..0513196bd48c 100644
@@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 
 	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
 	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
 
 	if (!ret)
Signature · 1 line
2.4.3
maintainer
#203 lore raw

Re: [PATCH v8 35/55] [media] s5k5baf: fix subdev type

Hi Mauro,

Thank you for the patch.

Quoted 6 lines · On Sunday 30 August 2015 00:06:46 Mauro Carvalho Chehab wrote:

X-Patchwork-Delegate: [email protected]
This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.

As this is a sensor driver, the proper type is likely MEDIA_ENT_T_V4L2_SUBDEV_SENSOR.

That's actually not correct. The driver creates two subdevs, one for the image sensor pixel array (and the related readout logic) and one for an ISP. The first subdev already uses the MEDIA_ENT_T_V4L2_SUBDEV_SENSOR type, but the second subdev isn't a sensor pixel array.

Quoted 16 lines
drivers/media/i2c/s5k5baf.c +1 -1
index d3bff30bcb6f..0513196bd48c 100644
@@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf
 *state,
 
 	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
 	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
 

if (!ret)

Signature · 3 lines
Regards,

Laurent Pinchart
#204 lore raw

Re: [PATCH v8 35/55] [media] s5k5baf: fix subdev type

Em Sun, 06 Dec 2015 03:55:32 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 9 lines

Hi Mauro,

Thank you for the patch.

Quoted 4 lines · On Sunday 30 August 2015 00:06:46 Mauro Carvalho Chehab wrote:

X-Patchwork-Delegate: [email protected]
This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.

Quoted 7 lines
Quoted 2 lines

As this is a sensor driver, the proper type is likely MEDIA_ENT_T_V4L2_SUBDEV_SENSOR.

That's actually not correct. The driver creates two subdevs, one for the image sensor pixel array (and the related readout logic) and one for an ISP. The first subdev already uses the MEDIA_ENT_T_V4L2_SUBDEV_SENSOR type, but the second subdev isn't a sensor pixel array.

OK.

Patch replaced by the one below.

Thanks,
Mauro

Quoted 1 line

From b1acc860aa845e9ea84fa597d540ad34047fe0cc Mon Sep 17 00:00:00 2001

From: Mauro Carvalho Chehab <[email protected]>
Date: Thu, 7 May 2015 22:12:35 -0300
Subject: [media] s5k5baf: fix subdev type
Cc: Linux Media Mailing List <[email protected]>,
Mauro Carvalho Chehab <[email protected]>

The driver creates two subdevs, one for the image sensor pixel array (and the related readout logic) and one for an ISP.

The first subdev already uses the MEDIA_ENT_T_V4L2_SUBDEV_SENSOR type, but the second subdev isn't a sensor pixel array.

So, rename the second subdev as MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN.

---
 drivers/media/i2c/s5k5baf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/i2c/s5k5baf.c +1 -1
index d3bff30bcb6f..0513196bd48c 100644
@@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 
 	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
 	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
 	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
 
 	if (!ret)
Signature · 1 line
2.5.0
#205 lore raw

PATCH v8 36/55 davinci_vbpe: stop MEDIA_ENT_T_V4L2_SUBDEV abuse

In reply to Mauro Carvalho Chehab

This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV:

- it uses a hack to check if the remote entity is a subdev;
- it still uses the legacy entity subtype check macro, that will be removed soon.

drivers/staging/media/davinci_vpfe/dm365_ipipe.c +6 -3
index b89a057b8b7e..7fd78329e3e1 100644
@@ -1711,8 +1711,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;
@@ -1725,7 +1728,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;
drivers/staging/media/davinci_vpfe/vpfe_video.c +2 -3
index 9eef64e0f0ab..2dbf14b9bb5f 100644
@@ -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;
@@ -243,8 +243,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);
Signature · 1 line
2.4.3
maintainer
#206 lore raw

Re: [PATCH v8 36/55] [media] davinci_vbpe: stop MEDIA_ENT_T_V4L2_SUBDEV abuse

Hi Mauro,

Thank you for the patch.

Quoted 3 lines · On Sunday 30 August 2015 00:06:47 Mauro Carvalho Chehab wrote:

This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV:

- it uses a hack to check if the remote entity is a subdev;

Same comment as for "omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse", this isn't a hack.

Quoted 13 lines

- it still uses the legacy entity subtype check macro, that will be removed soon.

(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index b89a057b8b7e..7fd78329e3e1 100644

drivers/staging/media/davinci_vpfe/dm365_ipipe.c +0 -0
@@ -1711,8 +1711,11 @@ ipipe_link_setup(struct media_entity *entity, const

struct media_pad *local, struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);

drivers/staging/media/davinci_vpfe/dm365_ipipe.c ipipe_link_setup(struct media_entity *entity, const struct media_pad *local, · line 1715

Quoted 6 lines
drivers/staging/media/davinci_vpfe/dm365_ipipe.c +2 -2
 	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;

You can drop the check (even though the implementation in the switch looks dubious to me, but that's not your fault).

Quoted 39 lines
drivers/staging/media/davinci_vpfe/dm365_ipipe.c +3 -1
+	switch (local->index) {
+	case IPIPE_PAD_SINK:
 		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
 			ipipe->input = IPIPE_INPUT_NONE;
 			break;
@@ -1725,7 +1728,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;
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 9eef64e0f0ab..2dbf14b9bb5f 100644

drivers/staging/media/davinci_vpfe/vpfe_video.c +2 -3
@@ -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;
@@ -243,8 +243,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);

Signature · 3 lines
Regards,

Laurent Pinchart
#207 lore raw

Re: [PATCH v8 36/55] [media] davinci_vbpe: stop MEDIA_ENT_T_V4L2_SUBDEV abuse

Em Sun, 06 Dec 2015 03:52:01 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 27 lines

Hi Mauro,

Thank you for the patch.

Quoted 3 lines · On Sunday 30 August 2015 00:06:47 Mauro Carvalho Chehab wrote:

This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV:

- it uses a hack to check if the remote entity is a subdev;

Same comment as for "omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse", this isn't a hack.

Quoted 15 lines

- it still uses the legacy entity subtype check macro, that will be removed soon.

(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index b89a057b8b7e..7fd78329e3e1 100644

drivers/staging/media/davinci_vpfe/dm365_ipipe.c +0 -0
@@ -1711,8 +1711,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;

Quoted 7 lines

drivers/staging/media/davinci_vpfe/dm365_ipipe.c ipipe_link_setup(struct media_entity *entity, const struct media_pad *local, · line 1715

Quoted 4 lines
drivers/staging/media/davinci_vpfe/dm365_ipipe.c +2 -2
-	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;

You can drop the check (even though the implementation in the switch looks dubious to me, but that's not your fault).

I prefer to keep the above check, as it shouldn't hurt.

As I said on a previous comment on your reviews, if someone adds later some non-V4L2 entities to the media pipeline where the DaVinci media driver belongs, it could be a problem without the above check.

Quoted 41 lines
Quoted 40 lines
drivers/staging/media/davinci_vpfe/dm365_ipipe.c +3 -1
+	switch (local->index) {
+	case IPIPE_PAD_SINK:
 		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
 			ipipe->input = IPIPE_INPUT_NONE;
 			break;
@@ -1725,7 +1728,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;
(quoted diff) +0 -0

b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 9eef64e0f0ab..2dbf14b9bb5f 100644

drivers/staging/media/davinci_vpfe/vpfe_video.c +2 -3
@@ -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;
@@ -243,8 +243,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);

#208 lore raw

PATCH v8 37/55 omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse

In reply to Mauro Carvalho Chehab

This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, as it uses a hack to check if the remote entity is a subdev. Get rid of it.

drivers/staging/media/omap4iss/iss_ipipe.c +6 -3
index e1a7b7ba7362..eb91ec48a21e 100644
@@ -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)
Signature · 1 line
2.4.3
maintainer
#209 lore raw

Re: [PATCH v8 37/55] [media] omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse

Hi Mauro,

Thank you for the patch.

Quoted 2 lines · On Sunday 30 August 2015 00:06:48 Mauro Carvalho Chehab wrote:

This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, as it uses a hack to check if the remote entity is a subdev. Get rid of it.

While I agree with the idea of the patch I don't think this is a hack, it was a totally valid implementation with the existing API.

Quoted 8 lines
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_ipipe.c index e1a7b7ba7362..eb91ec48a21e 100644

drivers/staging/media/omap4iss/iss_ipipe.c static int ipipe_link_setup(struct media_entity · line 452

Quoted 8 lines
drivers/staging/media/omap4iss/iss_ipipe.c +3 -2
@@ -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;
+

Furthermore the ipipe entity is never connected to anything else than a subdev, so you can remove this check completely.

I'd rewrite the subject line as "omap4iss: ipipe: Don't check entity type needlessly during link setup" and update the commit message accordingly.

Quoted 14 lines
drivers/staging/media/omap4iss/iss_ipipe.c +3 -1
+	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)
Signature · 3 lines
Regards,

Laurent Pinchart
#210 lore raw

Re: [PATCH v8 37/55] [media] omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse

Em Sun, 06 Dec 2015 03:46:28 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 31 lines

Hi Mauro,

Thank you for the patch.

Quoted 2 lines · On Sunday 30 August 2015 00:06:48 Mauro Carvalho Chehab wrote:

This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, as it uses a hack to check if the remote entity is a subdev. Get rid of it.

While I agree with the idea of the patch I don't think this is a hack, it was a totally valid implementation with the existing API.

Quoted 8 lines
(quoted diff) +0 -0

b/drivers/staging/media/omap4iss/iss_ipipe.c index e1a7b7ba7362..eb91ec48a21e 100644

drivers/staging/media/omap4iss/iss_ipipe.c static int ipipe_link_setup(struct media_entity · line 452

Quoted 8 lines
drivers/staging/media/omap4iss/iss_ipipe.c +3 -2
@@ -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;
+

Furthermore the ipipe entity is never connected to anything else than a subdev, so you can remove this check completely.

Quoted 2 lines

I'd rewrite the subject line as "omap4iss: ipipe: Don't check entity type needlessly during link setup" and update the commit message accordingly.

The same rationale as patch 36/55: if one would later add some other subsystem to the pipeline, the check will be needed. So, better to have the check here.

I'm changing the description of this patch to:

[media] omap4iss: change the logic that checks if an entity is a subdev

As we're getting rid of an specific number range for the V4L2 subdev, we need to replace the check for MEDIA_ENT_T_V4L2_SUBDEV by a macro.

Quoted 16 lines
Quoted 15 lines
drivers/staging/media/omap4iss/iss_ipipe.c +3 -1
+	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)
#211 lore raw

PATCH v8 38/55 v4l2-subdev: use MEDIA_ENT_T_UNKNOWN for new subdevs

In reply to Mauro Carvalho Chehab

Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.

drivers/media/media-device.c +6 -0
index 659507bce63f..134fe7510195 100644
@@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 {
 	int i;
 
+	if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
+	    entity->type == MEDIA_ENT_T_UNKNOWN)
+		dev_warn(mdev->dev,
+			 "Entity type for entity %s was not initialized!\n",
+			 entity->name);
+
 	/* Warn if we apparently re-register an entity */
 	WARN_ON(entity->graph_obj.mdev != NULL);
 	entity->graph_obj.mdev = mdev;
drivers/media/v4l2-core/v4l2-subdev.c +1 -1
index 60da43772de9..b3bcc8253182 100644
@@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
 	sd->host_priv = NULL;
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	sd->entity.name = sd->name;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
 #endif
 }
 EXPORT_SYMBOL(v4l2_subdev_init);
include/uapi/linux/media.h +17 -0
index 3bbda409353f..44b84aae8b02 100644
@@ -42,6 +42,14 @@ struct media_device_info {
 
 #define MEDIA_ENT_ID_FLAG_NEXT		(1 << 31)
 
+/* Used values for media_entity_desc::type */
+
+/*
+ * Initial value when an entity is created
+ * Drivers should change it to something useful
+ */
+#define MEDIA_ENT_T_UNKNOWN	0x00000000
+
 /*
  * Base numbers for entity types
  *
@@ -77,6 +85,15 @@ struct media_device_info {
 #define MEDIA_ENT_T_V4L2_SWRADIO	(MEDIA_ENT_T_V4L2_BASE + 7)
 
 /* V4L2 Sub-device entities */
+
+	/*
+	 * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN,
+	 * in order to preserve backward compatibility.
+	 * Drivers should change to the proper subdev type before
+	 * registering the entity.
+	 */
+#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN	MEDIA_ENT_T_V4L2_SUBDEV_BASE
+
 #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR	(MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1)
 #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH	(MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2)
 #define MEDIA_ENT_T_V4L2_SUBDEV_LENS	(MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3)
Signature · 1 line
2.4.3

A message that is not in the archive (sent off-list or not yet received): 662a3bb2bfb02f820f4dafa0033af2cf16d273c5.1440902901.git.mchehab-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org

Acked-by
#213 lore raw

Re: [PATCH v8 38/55] [media] v4l2-subdev: use MEDIA_ENT_T_UNKNOWN for new subdevs

Quoted 4 lines · Mauro Carvalho Chehab

Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.

Quoted 67 lines
drivers/media/media-device.c +6 -0
index 659507bce63f..134fe7510195 100644
@@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 {
 	int i;
 
+	if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
+	    entity->type == MEDIA_ENT_T_UNKNOWN)
+		dev_warn(mdev->dev,
+			 "Entity type for entity %s was not initialized!\n",
+			 entity->name);
+
 	/* Warn if we apparently re-register an entity */
 	WARN_ON(entity->graph_obj.mdev != NULL);
 	entity->graph_obj.mdev = mdev;
drivers/media/v4l2-core/v4l2-subdev.c +1 -1
index 60da43772de9..b3bcc8253182 100644
@@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
 	sd->host_priv = NULL;
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	sd->entity.name = sd->name;
-	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
 #endif
 }
 EXPORT_SYMBOL(v4l2_subdev_init);
include/uapi/linux/media.h +17 -0
index 3bbda409353f..44b84aae8b02 100644
@@ -42,6 +42,14 @@ struct media_device_info {
 
 #define MEDIA_ENT_ID_FLAG_NEXT		(1 << 31)
 
+/* Used values for media_entity_desc::type */
+
+/*
+ * Initial value when an entity is created
+ * Drivers should change it to something useful
+ */
+#define MEDIA_ENT_T_UNKNOWN	0x00000000
+
 /*
  * Base numbers for entity types
  *
@@ -77,6 +85,15 @@ struct media_device_info {
 #define MEDIA_ENT_T_V4L2_SWRADIO	(MEDIA_ENT_T_V4L2_BASE + 7)
 
 /* V4L2 Sub-device entities */
+
+	/*
+	 * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN,
+	 * in order to preserve backward compatibility.
+	 * Drivers should change to the proper subdev type before
+	 * registering the entity.
+	 */
+#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN	MEDIA_ENT_T_V4L2_SUBDEV_BASE
+
 #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR	(MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1)
 #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH	(MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2)
 #define MEDIA_ENT_T_V4L2_SUBDEV_LENS	(MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3)
#214 lore raw

PATCH v8 39/55 media controller: get rid of entity subtype on Kernel

In reply to Mauro Carvalho Chehab

Don't use anymore the type/subtype entity data/macros inside the Kernel.

include/media/media-entity.h +0 -10
index b0cfbc0dffc7..756e1960fd7f 100644
@@ -185,16 +185,6 @@ struct media_intf_devnode {
 	u32				minor;
 };
 
-static inline u32 media_entity_type(struct media_entity *entity)
-{
-	return entity->type & MEDIA_ENT_TYPE_MASK;
-}
-
-static inline u32 media_entity_subtype(struct media_entity *entity)
-{
-	return entity->type & MEDIA_ENT_SUBTYPE_MASK;
-}
-
 static inline u32 media_entity_id(struct media_entity *entity)
 {
 	return entity->graph_obj.id;
include/uapi/linux/media.h +1 -3
index 44b84aae8b02..cd486fc25f1e 100644
@@ -42,10 +42,8 @@ struct media_device_info {
 
 #define MEDIA_ENT_ID_FLAG_NEXT		(1 << 31)
 
-/* Used values for media_entity_desc::type */
-
 /*
- * Initial value when an entity is created
+ * Initial value to be used when a new entity is created
  * Drivers should change it to something useful
  */
 #define MEDIA_ENT_T_UNKNOWN	0x00000000
Signature · 1 line
2.4.3

A message that is not in the archive (sent off-list or not yet received): 8154aa42b993840dfde2d794e7e9e1f0c57c1e82.1440902901.git.mchehab-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org

#216 lore raw

Re: [PATCH v8 39/55] [media] media controller: get rid of entity subtype on Kernel

Quoted 31 lines · Mauro Carvalho Chehab

Don't use anymore the type/subtype entity data/macros inside the Kernel.

include/media/media-entity.h +0 -10
index b0cfbc0dffc7..756e1960fd7f 100644
@@ -185,16 +185,6 @@ struct media_intf_devnode {
 	u32				minor;
 };
 
-static inline u32 media_entity_type(struct media_entity *entity)
-{
-	return entity->type & MEDIA_ENT_TYPE_MASK;
-}
-
-static inline u32 media_entity_subtype(struct media_entity *entity)
-{
-	return entity->type & MEDIA_ENT_SUBTYPE_MASK;
-}
-
 static inline u32 media_entity_id(struct media_entity *entity)
 {
 	return entity->graph_obj.id;
include/uapi/linux/media.h +0 -0
index 44b84aae8b02..cd486fc25f1e 100644

include/uapi/linux/media.h struct media_device_info { · line 46

Quoted 8 lines
include/uapi/linux/media.h +1 -3
@@ -42,10 +42,8 @@ struct media_device_info {
 
 #define MEDIA_ENT_ID_FLAG_NEXT		(1 << 31)
 
-/* Used values for media_entity_desc::type */
-
 /*
- * Initial value when an entity is created
+ * Initial value to be used when a new entity is created

This change should be moved to patch 38.

include/uapi/linux/media.h struct media_device_info { · line 49

Quoted 4 lines
include/uapi/linux/media.h +0 -0
  * Drivers should change it to something useful
  */
 #define MEDIA_ENT_T_UNKNOWN	0x00000000

Regards,

Hans

#217 lore raw

PATCH v8 41/55 DocBook: update descriptions for the media controller entities

In reply to Mauro Carvalho Chehab

Cleanup the media controller entities description:
- remove MEDIA_ENT_T_DEVNODE and MEDIA_ENT_T_V4L2_SUBDEV entity types, as they don't mean anything;
- add MEDIA_ENT_T_UNKNOWN with a proper description;
- remove ALSA and FB entity types. Those should not be used, as the types are deprecated. We'll soon be adidng ALSA, but with a different entity namespace;
- improve the description of some entities.

Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +17 -28
index 32a783635649..bd90dde54416 100644
@@ -179,70 +179,59 @@
         <colspec colname="c2"/>
 	<tbody valign="top">
 	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry>
-	    <entry>Unknown device node</entry>
+	    <entry><constant>MEDIA_ENT_T_UNKNOWN</constant> and <constant>MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN</constant></entry>
+	    <entry>Unknown entity. That generally indicates that
+	    a driver didn't initialize properly the entity, with is a Kernel bug</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
-	    <entry>V4L video, radio or vbi device node</entry>
-	  </row>
-	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry>
-	    <entry>Frame buffer device node</entry>
-	  </row>
-	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry>
-	    <entry>ALSA card</entry>
+	    <entry>V4L video streaming input or output entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry>
-	    <entry>DVB frontend devnode</entry>
+	    <entry>DVB demodulator entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry>
-	    <entry>DVB demux devnode</entry>
+	    <entry>DVB demux entity. Could be implemented on hardware or in Kernelspace</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry>
-	    <entry>DVB DVR devnode</entry>
+	    <entry>DVB Transport Stream output entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry>
-	    <entry>DVB CAM devnode</entry>
+	    <entry>DVB Conditional Access module (CAM) entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry>
-	    <entry>DVB network devnode</entry>
-	  </row>
-	  <row>
-	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
-	    <entry>Unknown V4L sub-device</entry>
+	    <entry>DVB network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry>
-	    <entry>Video sensor</entry>
+	    <entry>Camera video sensor entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry>
-	    <entry>Flash controller</entry>
+	    <entry>Flash controller entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
-	    <entry>Lens controller</entry>
+	    <entry>Lens controller entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry>
-	    <entry>Video decoder, the basic function of the video decoder is to
-	    accept analogue video from a wide variety of sources such as
+	    <entry>Analog video decoder, the basic function of the video decoder
+	    is to accept analogue video from a wide variety of sources such as
 	    broadcast, DVD players, cameras and video cassette recorders, in
-	    either NTSC, PAL or HD format and still occasionally SECAM, separate
-	    it into its component parts, luminance and chrominance, and output
+	    either NTSC, PAL, SECAM or HD format, separating the stream
+	    into its component parts, luminance and chrominance, and output
 	    it in some digital video standard, with appropriate embedded timing
 	    signals.</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry>
-	    <entry>TV and/or radio tuner</entry>
+	    <entry>Digital TV, analog TV, radio and/or software radio tuner</entry>
 	  </row>
 	</tbody>
       </tgroup>
Signature · 1 line
2.4.3
#218 lore raw

Re: [PATCH v8 41/55] [media] DocBook: update descriptions for the media controller entities

Quoted 3 lines · Mauro Carvalho Chehab

Cleanup the media controller entities description:
- remove MEDIA_ENT_T_DEVNODE and MEDIA_ENT_T_V4L2_SUBDEV entity types, as they don't mean anything;

Shouldn't this add MEDIA_ENT_T_V4L2_VBI and _SWRADIO descriptions?

Regards,

Hans

Quoted 101 lines

- add MEDIA_ENT_T_UNKNOWN with a proper description;
- remove ALSA and FB entity types. Those should not be used, as the types are deprecated. We'll soon be adidng ALSA, but with a different entity namespace;
- improve the description of some entities.

Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +17 -28
index 32a783635649..bd90dde54416 100644
@@ -179,70 +179,59 @@
         <colspec colname="c2"/>
 	<tbody valign="top">
 	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry>
-	    <entry>Unknown device node</entry>
+	    <entry><constant>MEDIA_ENT_T_UNKNOWN</constant> and <constant>MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN</constant></entry>
+	    <entry>Unknown entity. That generally indicates that
+	    a driver didn't initialize properly the entity, with is a Kernel bug</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
-	    <entry>V4L video, radio or vbi device node</entry>
-	  </row>
-	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry>
-	    <entry>Frame buffer device node</entry>
-	  </row>
-	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry>
-	    <entry>ALSA card</entry>
+	    <entry>V4L video streaming input or output entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry>
-	    <entry>DVB frontend devnode</entry>
+	    <entry>DVB demodulator entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry>
-	    <entry>DVB demux devnode</entry>
+	    <entry>DVB demux entity. Could be implemented on hardware or in Kernelspace</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry>
-	    <entry>DVB DVR devnode</entry>
+	    <entry>DVB Transport Stream output entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry>
-	    <entry>DVB CAM devnode</entry>
+	    <entry>DVB Conditional Access module (CAM) entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry>
-	    <entry>DVB network devnode</entry>
-	  </row>
-	  <row>
-	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
-	    <entry>Unknown V4L sub-device</entry>
+	    <entry>DVB network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry>
-	    <entry>Video sensor</entry>
+	    <entry>Camera video sensor entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry>
-	    <entry>Flash controller</entry>
+	    <entry>Flash controller entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
-	    <entry>Lens controller</entry>
+	    <entry>Lens controller entity</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry>
-	    <entry>Video decoder, the basic function of the video decoder is to
-	    accept analogue video from a wide variety of sources such as
+	    <entry>Analog video decoder, the basic function of the video decoder
+	    is to accept analogue video from a wide variety of sources such as
 	    broadcast, DVD players, cameras and video cassette recorders, in
-	    either NTSC, PAL or HD format and still occasionally SECAM, separate
-	    it into its component parts, luminance and chrominance, and output
+	    either NTSC, PAL, SECAM or HD format, separating the stream
+	    into its component parts, luminance and chrominance, and output
 	    it in some digital video standard, with appropriate embedded timing
 	    signals.</entry>
 	  </row>
 	  <row>
 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry>
-	    <entry>TV and/or radio tuner</entry>
+	    <entry>Digital TV, analog TV, radio and/or software radio tuner</entry>
 	  </row>
 	</tbody>
       </tgroup>
#219 lore raw

PATCH v8 42/55 dvb: modify core to implement interfaces/entities at MC new gen

In reply to Mauro Carvalho Chehab

The Media Controller New Generation redefines the types for both interfaces and entities to be used on DVB. Make the needed changes at the DVB core for all interfaces, entities and data and interface links to appear in the graph.

drivers/media/dvb-core/dmxdev.c +2 -2
index d0e3f9d85f34..baaed28ee975 100644
@@ -1242,9 +1242,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
 	}
 
 	dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
-			    DVB_DEVICE_DEMUX);
+			    DVB_DEVICE_DEMUX, dmxdev->filternum);
 	dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
-			    dmxdev, DVB_DEVICE_DVR);
+			    dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
 
 	dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
 
drivers/media/dvb-core/dvb_ca_en50221.c +1 -1
index fb66184dc9b6..f82cd1ff4f3a 100644
@@ -1695,7 +1695,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 	pubca->private = ca;
 
 	/* register the DVB device */
-	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
+	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0);
 	if (ret)
 		goto free_slot_info;
 
drivers/media/dvb-core/dvb_frontend.c +1 -1
index 2d06bcff0946..58601bfe0b8d 100644
@@ -2754,7 +2754,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 			fe->dvb->num, fe->id, fe->ops.info.name);
 
 	dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
-			     fe, DVB_DEVICE_FRONTEND);
+			     fe, DVB_DEVICE_FRONTEND, 0);
 
 	/*
 	 * Initialize the cache to the proper values according with the
drivers/media/dvb-core/dvb_net.c +1 -1
index b81e026edab3..14f51b68f4fe 100644
@@ -1503,6 +1503,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
 		dvbnet->state[i] = 0;
 
 	return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net,
-			     dvbnet, DVB_DEVICE_NET);
+			     dvbnet, DVB_DEVICE_NET, 0);
 }
 EXPORT_SYMBOL(dvb_net_init);
drivers/media/dvb-core/dvbdev.c +124 -20

243 lines not on this page · raw message

drivers/media/dvb-core/dvbdev.h +6 -3
index 5f37b4dd1e69..0b140e8595de 100644
@@ -148,9 +148,11 @@ struct dvb_device {
 	const char *name;
 
 	/* Allocated and filled inside dvbdev.c */
-	struct media_entity *entity;
 	struct media_intf_devnode *intf_devnode;
-	struct media_pad *pads;
+
+	unsigned tsout_num_entities;
+	struct media_entity *entity, *tsout_entity;
+	struct media_pad *pads, *tsout_pads;
 #endif
 
 	void *priv;
@@ -197,7 +199,8 @@ int dvb_register_device(struct dvb_adapter *adap,
 			struct dvb_device **pdvbdev,
 			const struct dvb_device *template,
 			void *priv,
-			int type);
+			int type,
+			int demux_sink_pads);
 
 /**
  * dvb_unregister_device - Unregisters a DVB device
drivers/media/firewire/firedtv-ci.c +1 -1
index e63f582378bf..edbb30fdd9d9 100644
@@ -241,7 +241,7 @@ int fdtv_ca_register(struct firedtv *fdtv)
 		return -EFAULT;
 
 	err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
-				  &fdtv_ca, fdtv, DVB_DEVICE_CA);
+				  &fdtv_ca, fdtv, DVB_DEVICE_CA, 0);
 
 	if (stat.ca_application_info == 0)
 		dev_err(fdtv->device, "CaApplicationInfo is not set\n");
drivers/media/pci/bt8xx/dst_ca.c +2 -1
index c5cc14ef8347..0149a9ed6e58 100644
@@ -705,7 +705,8 @@ struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_
 	struct dvb_device *dvbdev;
 
 	dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
-	if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) {
+	if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst,
+			        DVB_DEVICE_CA, 0) == 0) {
 		dst->dst_ca = dvbdev;
 		return dst->dst_ca;
 	}
drivers/media/pci/ddbridge/ddbridge-core.c +1 -1
index 0ac2dd35fe50..4caca5df2931 100644
@@ -1065,7 +1065,7 @@ static int ddb_ci_attach(struct ddb_port *port)
 			    port->en, 0, 1);
 	ret = dvb_register_device(&port->output->adap, &port->output->dev,
 				  &dvbdev_ci, (void *) port->output,
-				  DVB_DEVICE_SEC);
+				  DVB_DEVICE_SEC, 0);
 	return ret;
 }
 
drivers/media/pci/ngene/ngene-core.c +1 -1
index 1b92d836a564..4e924e2d1638 100644
@@ -1513,7 +1513,7 @@ static int init_channel(struct ngene_channel *chan)
 		set_transfer(&chan->dev->channel[2], 1);
 		dvb_register_device(adapter, &chan->ci_dev,
 				    &ngene_dvbdev_ci, (void *) chan,
-				    DVB_DEVICE_SEC);
+				    DVB_DEVICE_SEC, 0);
 		if (!chan->ci_dev)
 			goto err;
 	}
drivers/media/pci/ttpci/av7110.c +1 -1
index 3f24fce74fc1..63f1d56bdfb2 100644
@@ -1361,7 +1361,7 @@ static int av7110_register(struct av7110 *av7110)
 
 #ifdef CONFIG_DVB_AV7110_OSD
 	dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
-			    &dvbdev_osd, av7110, DVB_DEVICE_OSD);
+			    &dvbdev_osd, av7110, DVB_DEVICE_OSD, 0);
 #endif
 
 	dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
drivers/media/pci/ttpci/av7110_av.c +2 -2
index 9544cfc06601..da11501fe5d2 100644
@@ -1589,10 +1589,10 @@ int av7110_av_register(struct av7110 *av7110)
 	memset(&av7110->video_size, 0, sizeof (video_size_t));
 
 	dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
-			    &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
+			    &dvbdev_video, av7110, DVB_DEVICE_VIDEO, 0);
 
 	dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
-			    &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
+			    &dvbdev_audio, av7110, DVB_DEVICE_AUDIO, 0);
 
 	return 0;
 }
drivers/media/pci/ttpci/av7110_ca.c +1 -1
index a6079b90252a..235f0202dc7e 100644
@@ -378,7 +378,7 @@ static struct dvb_device dvbdev_ca = {
 int av7110_ca_register(struct av7110 *av7110)
 {
 	return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
-				   &dvbdev_ca, av7110, DVB_DEVICE_CA);
+				   &dvbdev_ca, av7110, DVB_DEVICE_CA, 0);
 }
 
 void av7110_ca_unregister(struct av7110 *av7110)
Signature · 1 line
2.4.3
#220 lore raw

Re: [PATCH v8 42/55] [media] dvb: modify core to implement interfaces/entities at MC new gen

Quoted 123 lines · Mauro Carvalho Chehab

The Media Controller New Generation redefines the types for both interfaces and entities to be used on DVB. Make the needed changes at the DVB core for all interfaces, entities and data and interface links to appear in the graph.

drivers/media/dvb-core/dmxdev.c +2 -2
index d0e3f9d85f34..baaed28ee975 100644
@@ -1242,9 +1242,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
 	}
 
 	dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
-			    DVB_DEVICE_DEMUX);
+			    DVB_DEVICE_DEMUX, dmxdev->filternum);
 	dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
-			    dmxdev, DVB_DEVICE_DVR);
+			    dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
 
 	dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
 
drivers/media/dvb-core/dvb_ca_en50221.c +1 -1
index fb66184dc9b6..f82cd1ff4f3a 100644
@@ -1695,7 +1695,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
 	pubca->private = ca;
 
 	/* register the DVB device */
-	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA);
+	ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0);
 	if (ret)
 		goto free_slot_info;
 
drivers/media/dvb-core/dvb_frontend.c +1 -1
index 2d06bcff0946..58601bfe0b8d 100644
@@ -2754,7 +2754,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 			fe->dvb->num, fe->id, fe->ops.info.name);
 
 	dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
-			     fe, DVB_DEVICE_FRONTEND);
+			     fe, DVB_DEVICE_FRONTEND, 0);
 
 	/*
 	 * Initialize the cache to the proper values according with the
drivers/media/dvb-core/dvb_net.c +1 -1
index b81e026edab3..14f51b68f4fe 100644
@@ -1503,6 +1503,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
 		dvbnet->state[i] = 0;
 
 	return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net,
-			     dvbnet, DVB_DEVICE_NET);
+			     dvbnet, DVB_DEVICE_NET, 0);
 }
 EXPORT_SYMBOL(dvb_net_init);
drivers/media/dvb-core/dvbdev.c +54 -0
index 88013d1a2c39..f638c67defbe 100644
@@ -180,18 +180,86 @@ skip:
 	return -ENFILE;
 }
 
+static void dvb_create_tsout_entity(struct dvb_device *dvbdev,
+				    const char *name, int npads)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	int i, ret = 0;
+
+	dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
+				     GFP_KERNEL);
+	if (!dvbdev->tsout_pads)
+		return;
+	dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
+				       GFP_KERNEL);
+	if (!dvbdev->tsout_entity) {
+		kfree(dvbdev->tsout_pads);
+		dvbdev->tsout_pads = NULL;
+		return;
+	}
+	for (i = 0; i < npads; i++) {
+		struct media_pad *pads = &dvbdev->tsout_pads[i];
+		struct media_entity *entity = &dvbdev->tsout_entity[i];
+
+		entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
+		if (!entity->name) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		entity->type = MEDIA_ENT_T_DVB_TSOUT;
+		pads->flags = MEDIA_PAD_FL_SINK;
+
+		ret = media_entity_init(entity, 1, pads);
+		if (ret < 0)
+			break;
+
+		ret = media_device_register_entity(dvbdev->adapter->mdev,
+						   entity);
+		if (ret < 0)
+			break;
+	}
+
+	if (!ret) {
+		dvbdev->tsout_num_entities = npads;
+		return;
+	}
+
+	for (i--; i >= 0; i--) {
+		media_device_unregister_entity(&dvbdev->tsout_entity[i]);
+		kfree(dvbdev->tsout_entity[i].name);
+	}
+
+	printk(KERN_ERR
+		"%s: media_device_register_entity failed for %s\n",
+		__func__, name);
+

drivers/media/dvb-core/dvbdev.c skip: · line 246

Quoted 10 lines
drivers/media/dvb-core/dvbdev.c +10 -0
+	kfree(dvbdev->tsout_entity);
+	kfree(dvbdev->tsout_pads);
+	dvbdev->tsout_entity = NULL;
+	dvbdev->tsout_pads = NULL;
+#endif
+}
+
+#define DEMUX_TSOUT	"demux_tsout"
+#define DVR_TSOUT	"dvr_tsout"
+

I have a preference for - instead of _.

Your choice, though.

Regards,

Hans

#221 lore raw

PATCH v8 43/55 media: report if a pad is sink or source at debug msg

In reply to Mauro Carvalho Chehab

Sometimes, it is important to see if the created pad is sink or source. Add info to track that.

drivers/media/dvb-core/dvbdev.c +15 -11
index f638c67defbe..610d2bab1368 100644
@@ -528,8 +528,8 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	struct media_entity *entity, *tuner = NULL, *demod = NULL;
 	struct media_entity *demux = NULL, *ca = NULL;
 	struct media_interface *intf;
-	unsigned demux_pad = 1;
-	unsigned dvr_pad = 1;
+	unsigned demux_pad = 0;
+	unsigned dvr_pad = 0;
 
 	if (!mdev)
 		return;
@@ -561,15 +561,19 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 
 	/* Create demux links for each ringbuffer/pad */
 	if (demux) {
-		if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
-			if (!strncmp(entity->name, DVR_TSOUT,
-				     sizeof(DVR_TSOUT)))
-				media_create_pad_link(demux, ++dvr_pad,
-						      entity, 0, 0);
-			if (!strncmp(entity->name, DEMUX_TSOUT,
-				     sizeof(DEMUX_TSOUT)))
-				media_create_pad_link(demux, ++demux_pad,
-						      entity, 0, 0);
+		media_device_for_each_entity(entity, mdev) {
+			if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
+				if (!strncmp(entity->name, DVR_TSOUT,
+					strlen(DVR_TSOUT)))
+					media_create_pad_link(demux,
+							      ++dvr_pad,
+							entity, 0, 0);
+				if (!strncmp(entity->name, DEMUX_TSOUT,
+					strlen(DEMUX_TSOUT)))
+					media_create_pad_link(demux,
+							      ++demux_pad,
+							entity, 0, 0);
+			}
 		}
 	}
 
drivers/media/media-entity.c +5 -2
index 15bc92d3a648..d62a6ffbc929 100644
@@ -121,8 +121,11 @@ static void dev_dbg_obj(const char *event_name,  struct media_gobj *gobj)
 		struct media_pad *pad = gobj_to_pad(gobj);
 
 		dev_dbg(gobj->mdev->dev,
-			"%s: id 0x%08x pad#%d: '%s':%d\n",
-			event_name, gobj->id, media_localid(gobj),
+			"%s: id 0x%08x %s%spad#%d: '%s':%d\n",
+			event_name, gobj->id,
+			pad->flags & MEDIA_PAD_FL_SINK   ? "  sink " : "",
+			pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "",
+			media_localid(gobj),
 			pad->entity->name, pad->index);
 		break;
 	}
Signature · 1 line
2.4.3
#222 lore raw

Re: [PATCH v8 43/55] [media] media: report if a pad is sink or source at debug msg

Quoted 39 lines · Mauro Carvalho Chehab

Sometimes, it is important to see if the created pad is sink or source. Add info to track that.

drivers/media/dvb-core/dvbdev.c +8 -11
index f638c67defbe..610d2bab1368 100644
@@ -528,8 +528,8 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	struct media_entity *entity, *tuner = NULL, *demod = NULL;
 	struct media_entity *demux = NULL, *ca = NULL;
 	struct media_interface *intf;
-	unsigned demux_pad = 1;
-	unsigned dvr_pad = 1;
+	unsigned demux_pad = 0;
+	unsigned dvr_pad = 0;
 
 	if (!mdev)
 		return;
@@ -561,15 +561,19 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 
 	/* Create demux links for each ringbuffer/pad */
 	if (demux) {
-		if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
-			if (!strncmp(entity->name, DVR_TSOUT,
-				     sizeof(DVR_TSOUT)))
-				media_create_pad_link(demux, ++dvr_pad,
-						      entity, 0, 0);
-			if (!strncmp(entity->name, DEMUX_TSOUT,
-				     sizeof(DEMUX_TSOUT)))
-				media_create_pad_link(demux, ++demux_pad,
-						      entity, 0, 0);
+		media_device_for_each_entity(entity, mdev) {
+			if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
+				if (!strncmp(entity->name, DVR_TSOUT,
+					strlen(DVR_TSOUT)))
+					media_create_pad_link(demux,
+							      ++dvr_pad,

drivers/media/dvb-core/dvbdev.c void dvb_create_media_graph(struct dvb_adapter *adap) · line 579

Quoted 10 lines
drivers/media/dvb-core/dvbdev.c +7 -0
+							entity, 0, 0);
+				if (!strncmp(entity->name, DEMUX_TSOUT,
+					strlen(DEMUX_TSOUT)))
+					media_create_pad_link(demux,
+							      ++demux_pad,
+							entity, 0, 0);
+			}
 		}
 	}
 

Does this chunk belong here? I'd expect this in the previous patch or in a patch on its own.

Quoted 9 lines
drivers/media/media-entity.c +0 -0
index 15bc92d3a648..d62a6ffbc929 100644
@@ -121,8 +121,11 @@ static void dev_dbg_obj(const char *event_name,  struct media_gobj *gobj)
 		struct media_pad *pad = gobj_to_pad(gobj);
 
 		dev_dbg(gobj->mdev->dev,

drivers/media/media-entity.c static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) · line 131

Quoted 10 lines
drivers/media/media-entity.c +5 -2
-			"%s: id 0x%08x pad#%d: '%s':%d\n",
-			event_name, gobj->id, media_localid(gobj),
+			"%s: id 0x%08x %s%spad#%d: '%s':%d\n",
+			event_name, gobj->id,
+			pad->flags & MEDIA_PAD_FL_SINK   ? "  sink " : "",
+			pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "",
+			media_localid(gobj),
 			pad->entity->name, pad->index);
 		break;
 	}

Regards,

Hans

#223 lore raw

PATCH v8 44/55 uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl

In reply to Mauro Carvalho Chehab

Add a new ioctl that will report the entire topology on one go.

include/media/media-entity.h +2 -0
index 756e1960fd7f..358a0c6b1f86 100644
@@ -181,6 +181,8 @@ struct media_interface {
  */
 struct media_intf_devnode {
 	struct media_interface		intf;
+
+	/* Should match the fields at media_v2_intf_devnode */
 	u32				major;
 	u32				minor;
 };
include/uapi/linux/media.h +84 -1

95 lines not on this page · raw message

Signature · 1 line
2.4.3
#224 lore raw

Re: [PATCH v8 44/55] [media] uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl

Quoted 27 lines · Mauro Carvalho Chehab

Add a new ioctl that will report the entire topology on one go.

include/media/media-entity.h +2 -0
index 756e1960fd7f..358a0c6b1f86 100644
@@ -181,6 +181,8 @@ struct media_interface {
  */
 struct media_intf_devnode {
 	struct media_interface		intf;
+
+	/* Should match the fields at media_v2_intf_devnode */
 	u32				major;
 	u32				minor;
 };
include/uapi/linux/media.h +0 -1
index 4186891e5e81..fa0b68e670b0 100644
@@ -251,11 +251,94 @@ struct media_links_enum {
 #define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
 #define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)
 
-/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */

include/uapi/linux/media.h struct media_links_enum { · line 263

Quoted 10 lines
include/uapi/linux/media.h +10 -0
+/*
+ * MC next gen API definitions
+ *
+ * NOTE: The declarations below are close to the MC RFC for the Media
+ *	 Controller, the next generation. Yet, there are a few adjustments
+ *	 to do, as we want to be able to have a functional API before
+ *	 the MC properties change. Those will be properly marked below.
+ *	 Please also notice that I removed "num_pads", "num_links",
+ *	 from the proposal, as a proper userspace application will likely
+ *	 use lists for pads/links, just as we intend todo in Kernelspace.

s/todo/to do/

include/uapi/linux/media.h struct media_links_enum { · line 270

Quoted 7 lines
include/uapi/linux/media.h +7 -0
+ *	 The API definition should be freed from fields that are bound to
+ *	 some specific data structure.
+ *
+ * FIXME: Currently, I opted to name the new types as "media_v2", as this
+ *	  won't cause any conflict with the Kernelspace namespace, nor with
+ *	  the previous kAPI media_*_desc namespace. This can be changed
+ *	  latter, before the adding this API upstream.

s/latter/later/ :-)

I think this comment belongs to the commit log and not in this header.

include/uapi/linux/media.h struct media_links_enum { · line 277

Quoted 7 lines
include/uapi/linux/media.h +7 -0
+ */
+
+
+#define MEDIA_NEW_LNK_FL_ENABLED		MEDIA_LNK_FL_ENABLED
+#define MEDIA_NEW_LNK_FL_IMMUTABLE		MEDIA_LNK_FL_IMMUTABLE
+#define MEDIA_NEW_LNK_FL_DYNAMIC		MEDIA_NEW_FL_DYNAMIC
+#define MEDIA_NEW_LNK_FL_INTERFACE_LINK		(1 << 3)

Shouldn't this be MEDIA_V2_ instead of MEDIA_NEW_?

Do we need the INTERFACE_LINK flag? You can deduce it by checking the ID type.

I don't have a clear preference one way or another, just wondering about the reason for adding it.

Quoted 26 lines
include/uapi/linux/media.h +26 -0
+
+struct media_v2_entity {
+	__u32 id;
+	char name[64];		/* FIXME: move to a property? (RFC says so) */
+	__u16 reserved[14];
+};
+
+/* Should match the specific fields at media_intf_devnode */
+struct media_v2_intf_devnode {
+	__u32 major;
+	__u32 minor;
+};
+
+struct media_v2_interface {
+	__u32 id;
+	__u32 intf_type;
+	__u32 flags;
+	__u32 reserved[9];
+
+	union {
+		struct media_v2_intf_devnode devnode;
+		__u32 raw[16];
+	};
+};
+
+struct media_v2_pad {

include/uapi/linux/media.h struct media_links_enum { · line 313

Quoted 10 lines
include/uapi/linux/media.h +10 -0
+	__u32 id;
+	__u32 entity_id;
+	__u32 flags;
+	__u16 reserved[9];
+};
+
+struct media_v2_link {
+    __u32 id;
+    __u32 source_id;
+    __u32 sink_id;

Like in media_link I would use a union here as well to be able to refer to source/sink_id and entity/interface_id.

Quoted 10 lines
include/uapi/linux/media.h +10 -0
+    __u32 flags;
+    __u32 reserved[5];
+};
+
+struct media_v2_topology {
+	__u32 topology_version;
+
+	__u32 num_entities;
+	struct media_v2_entity *entities;
+

include/uapi/linux/media.h struct media_links_enum { · line 333

Quoted 10 lines
include/uapi/linux/media.h +10 -0
+	__u32 num_interfaces;
+	struct media_v2_interface *interfaces;
+
+	__u32 num_pads;
+	struct media_v2_pad *pads;
+
+	__u32 num_links;
+	struct media_v2_link *links;
+
+	__u32 reserved[64];

As mentioned before: use this instead to prevent horrible 32/64 bit arch compat code:

	struct {
		__u32 reserved_num;
		void *reserved_ptr;
	} reserved_types[16];
	__u32 reserved[8];

Sizes for these arrays are TBD.

include/uapi/linux/media.h struct media_links_enum { · line 344

Quoted 12 lines
include/uapi/linux/media.h +4 -0
+};
+
+/* ioctls */
 
 #define MEDIA_IOC_DEVICE_INFO		_IOWR('|', 0x00, struct media_device_info)
 #define MEDIA_IOC_ENUM_ENTITIES		_IOWR('|', 0x01, struct media_entity_desc)
 #define MEDIA_IOC_ENUM_LINKS		_IOWR('|', 0x02, struct media_links_enum)
 #define MEDIA_IOC_SETUP_LINK		_IOWR('|', 0x03, struct media_link_desc)
+#define MEDIA_IOC_G_TOPOLOGY		_IOWR('|', 0x04, struct media_v2_topology)
 
 #endif /* __LINUX_MEDIA_H */

Regards,

Hans

A message that is not in the archive (sent off-list or not yet received): 55E441EA.4020206-qWit8jRvyhVmR6Xm/[email protected]

#226 lore raw

Re: [PATCH v8 44/55] [media] uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl

Em Mon, 31 Aug 2015 14:00:42 +0200
Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/[email protected]> escreveu:

Quoted 49 lines · Mauro Carvalho Chehab
Quoted 27 lines

Add a new ioctl that will report the entire topology on one go.

include/media/media-entity.h +2 -0
index 756e1960fd7f..358a0c6b1f86 100644
@@ -181,6 +181,8 @@ struct media_interface {
  */
 struct media_intf_devnode {
 	struct media_interface		intf;
+
+	/* Should match the fields at media_v2_intf_devnode */
 	u32				major;
 	u32				minor;
 };
include/uapi/linux/media.h +0 -1
index 4186891e5e81..fa0b68e670b0 100644
@@ -251,11 +251,94 @@ struct media_links_enum {
 #define MEDIA_INTF_T_ALSA_RAWMIDI       (MEDIA_INTF_T_ALSA_BASE + 4)
 #define MEDIA_INTF_T_ALSA_HWDEP         (MEDIA_INTF_T_ALSA_BASE + 5)
 
-/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */

include/uapi/linux/media.h struct media_links_enum { · line 263

Quoted 10 lines
include/uapi/linux/media.h +10 -0
+/*
+ * MC next gen API definitions
+ *
+ * NOTE: The declarations below are close to the MC RFC for the Media
+ *	 Controller, the next generation. Yet, there are a few adjustments
+ *	 to do, as we want to be able to have a functional API before
+ *	 the MC properties change. Those will be properly marked below.
+ *	 Please also notice that I removed "num_pads", "num_links",
+ *	 from the proposal, as a proper userspace application will likely
+ *	 use lists for pads/links, just as we intend todo in Kernelspace.

s/todo/to do/

include/uapi/linux/media.h struct media_links_enum { · line 270

Quoted 7 lines
include/uapi/linux/media.h +7 -0
+ *	 The API definition should be freed from fields that are bound to
+ *	 some specific data structure.
+ *
+ * FIXME: Currently, I opted to name the new types as "media_v2", as this
+ *	  won't cause any conflict with the Kernelspace namespace, nor with
+ *	  the previous kAPI media_*_desc namespace. This can be changed
+ *	  latter, before the adding this API upstream.
Quoted 3 lines

s/latter/later/ :-)

I think this comment belongs to the commit log and not in this header.

True, but I opted to keep it here for now to produce some discussions ;)

I'm actually in doubt if we should rename the flags as proposed below, and use the newer flags only at G_TOPOLOGY or if we should keep the same namespace for them and accept newer flags with legacy ioctls.

Quoted 11 lines

include/uapi/linux/media.h struct media_links_enum { · line 277

Quoted 8 lines
include/uapi/linux/media.h +7 -0
+ */
+
+
+#define MEDIA_NEW_LNK_FL_ENABLED		MEDIA_LNK_FL_ENABLED
+#define MEDIA_NEW_LNK_FL_IMMUTABLE		MEDIA_LNK_FL_IMMUTABLE
+#define MEDIA_NEW_LNK_FL_DYNAMIC		MEDIA_NEW_FL_DYNAMIC
+#define MEDIA_NEW_LNK_FL_INTERFACE_LINK		(1 << 3)

Shouldn't this be MEDIA_V2_ instead of MEDIA_NEW_?

Quoted 2 lines

Do we need the INTERFACE_LINK flag? You can deduce it by checking the ID type.

Yes, this can be deduced from the type of the objects inside the link.

I guess I added it because of some comment from your media.h RFC proposal.

Right now, I'm using it at the application to better represent the graph elements:

	http://git.linuxtv.org/cgit.cgi/mchehab/experimental-v4l-utils.git/tree/contrib/test/mc_nextgen_test.c?h=mc-next-gen&id=fdc16ece9732c94cfa76eee86978158c5976c00a#n438 
	http://git.linuxtv.org/cgit.cgi/mchehab/experimental-v4l-utils.git/tree/contrib/test/mc_nextgen_test.c?h=mc-next-gen&id=fdc16ece9732c94cfa76eee86978158c5976c00a#n444

But it could, instead, be doing something like:

	if media_type(link->gobj1.id == MEDIA_GRAPH_PAD)
		link_is_pad = true;
	else
		link_is_pad = false;

Btw, I'm using the same type for both data and interface links, as I don't see any reason why to differentiate internally: they all share the same linked list at mdev and the same object ID range.

Quoted 35 lines

I don't have a clear preference one way or another, just wondering about the reason for adding it.

Quoted 31 lines
include/uapi/linux/media.h +31 -0
+
+struct media_v2_entity {
+	__u32 id;
+	char name[64];		/* FIXME: move to a property? (RFC says so) */
+	__u16 reserved[14];
+};
+
+/* Should match the specific fields at media_intf_devnode */
+struct media_v2_intf_devnode {
+	__u32 major;
+	__u32 minor;
+};
+
+struct media_v2_interface {
+	__u32 id;
+	__u32 intf_type;
+	__u32 flags;
+	__u32 reserved[9];
+
+	union {
+		struct media_v2_intf_devnode devnode;
+		__u32 raw[16];
+	};
+};
+
+struct media_v2_pad {
+	__u32 id;
+	__u32 entity_id;
+	__u32 flags;
+	__u16 reserved[9];
+};
Quoted 8 lines

include/uapi/linux/media.h struct media_links_enum { · line 313

Quoted 5 lines
include/uapi/linux/media.h +5 -0
+
+struct media_v2_link {
+    __u32 id;
+    __u32 source_id;
+    __u32 sink_id;

Like in media_link I would use a union here as well to be able to refer to source/sink_id and entity/interface_id.

That would be overkill, and won't help.

Unions make the code harder to read and kernel-doc-nano doesn't like unions very much.

Ok, there are some cases where it helps, but there's no good reason for doing it here.

If you don't like the name, let's just rename it to something else.

Quoted 25 lines
Quoted 11 lines
include/uapi/linux/media.h +10 -0
+    __u32 flags;
+    __u32 reserved[5];
+};
+
+struct media_v2_topology {
+	__u32 topology_version;
+
+	__u32 num_entities;
+	struct media_v2_entity *entities;
+

include/uapi/linux/media.h struct media_links_enum { · line 333

Quoted 10 lines
include/uapi/linux/media.h +10 -0
+	__u32 num_interfaces;
+	struct media_v2_interface *interfaces;
+
+	__u32 num_pads;
+	struct media_v2_pad *pads;
+
+	__u32 num_links;
+	struct media_v2_link *links;
+
+	__u32 reserved[64];

As mentioned before: use this instead to prevent horrible 32/64 bit arch compat code:

Quoted 7 lines
	struct {
		__u32 reserved_num;
		void *reserved_ptr;
	} reserved_types[16];
	__u32 reserved[8];

Sizes for these arrays are TBD.

OK. Sorry, I forgot to do this change.

Quoted 21 lines

include/uapi/linux/media.h struct media_links_enum { · line 344

Quoted 13 lines
include/uapi/linux/media.h +4 -0
+};
+
+/* ioctls */
 
 #define MEDIA_IOC_DEVICE_INFO		_IOWR('|', 0x00, struct media_device_info)
 #define MEDIA_IOC_ENUM_ENTITIES		_IOWR('|', 0x01, struct media_entity_desc)
 #define MEDIA_IOC_ENUM_LINKS		_IOWR('|', 0x02, struct media_links_enum)
 #define MEDIA_IOC_SETUP_LINK		_IOWR('|', 0x03, struct media_link_desc)
+#define MEDIA_IOC_G_TOPOLOGY		_IOWR('|', 0x04, struct media_v2_topology)
 
 #endif /* __LINUX_MEDIA_H */

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#227 lore raw

PATCH v8 45/55 media: Use a macro to interate between all interfaces

In reply to Mauro Carvalho Chehab

Just like we do with entities, use a similar macro for the interfaces loop.

drivers/media/dvb-core/dvbdev.c +2 -1
index 610d2bab1368..95b5b4b11230 100644
@@ -578,9 +578,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */
-	list_for_each_entry(intf, &mdev->interfaces, list) {
+	media_device_for_each_intf(intf, mdev) {
 		if (intf->type == MEDIA_INTF_T_DVB_CA && ca)
 			media_create_intf_link(ca, intf, 0);
+
 		if (intf->type == MEDIA_INTF_T_DVB_FE && tuner)
 			media_create_intf_link(tuner, intf, 0);
 
include/media/media-device.h +5 -0
index 51807efa505b..f23d686aaac6 100644
@@ -113,6 +113,11 @@ struct media_device *media_device_find_devres(struct device *dev);
 #define media_device_for_each_entity(entity, mdev)			\
 	list_for_each_entry(entity, &(mdev)->entities, list)
 
+/* Iterate over all interfaces. */
+#define media_device_for_each_intf(intf, mdev)			\
+	list_for_each_entry(intf, &(mdev)->interfaces, list)
+
+
 #else
 static inline int media_device_register(struct media_device *mdev)
 {
Signature · 1 line
2.4.3
Acked-by on v8 45/55
#228 lore raw

Re: [PATCH v8 45/55] [media] media: Use a macro to interate between all interfaces

Quoted 4 lines · Mauro Carvalho Chehab

Just like we do with entities, use a similar macro for the interfaces loop.

Quoted 34 lines
drivers/media/dvb-core/dvbdev.c +2 -1
index 610d2bab1368..95b5b4b11230 100644
@@ -578,9 +578,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */
-	list_for_each_entry(intf, &mdev->interfaces, list) {
+	media_device_for_each_intf(intf, mdev) {
 		if (intf->type == MEDIA_INTF_T_DVB_CA && ca)
 			media_create_intf_link(ca, intf, 0);
+
 		if (intf->type == MEDIA_INTF_T_DVB_FE && tuner)
 			media_create_intf_link(tuner, intf, 0);
 
include/media/media-device.h +5 -0
index 51807efa505b..f23d686aaac6 100644
@@ -113,6 +113,11 @@ struct media_device *media_device_find_devres(struct device *dev);
 #define media_device_for_each_entity(entity, mdev)			\
 	list_for_each_entry(entity, &(mdev)->entities, list)
 
+/* Iterate over all interfaces. */
+#define media_device_for_each_intf(intf, mdev)			\
+	list_for_each_entry(intf, &(mdev)->interfaces, list)
+
+
 #else
 static inline int media_device_register(struct media_device *mdev)
 {
#229 lore raw

PATCH v8 46/55 media: move mdev list init to gobj

In reply to Mauro Carvalho Chehab

Let's control the topology changes inside the graph_object. So, move the removal of interfaces/entities from the mdev lists to media_gobj_init() and media_gobj_remove().

The main reason is that mdev should have lists for all object types, as the new MC api will require to store objects in separate places.

drivers/media/media-device.c +1 -3
index 134fe7510195..ec98595b8a7a 100644
@@ -415,7 +415,7 @@ void media_device_unregister(struct media_device *mdev)
 	struct media_entity *entity;
 	struct media_entity *next;
 
-	list_for_each_entry_safe(entity, next, &mdev->entities, list)
+	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
 		media_device_unregister_entity(entity);
 
 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
@@ -449,7 +449,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	spin_lock(&mdev->lock);
 	/* Initialize media_gobj embedded at the entity */
 	media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
-	list_add_tail(&entity->list, &mdev->entities);
 
 	/* Initialize objects at the pads */
 	for (i = 0; i < entity->num_pads; i++)
@@ -487,7 +486,6 @@ void media_device_unregister_entity(struct media_entity *entity)
 	for (i = 0; i < entity->num_pads; i++)
 		media_gobj_remove(&entity->pads[i].graph_obj);
 	media_gobj_remove(&entity->graph_obj);
-	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
 	entity->graph_obj.mdev = NULL;
 }
drivers/media/media-entity.c +11 -3
index d62a6ffbc929..192af193a394 100644
@@ -170,6 +170,7 @@ void media_gobj_init(struct media_device *mdev,
 	switch (type) {
 	case MEDIA_GRAPH_ENTITY:
 		gobj->id = media_gobj_gen_id(type, ++mdev->entity_id);
+		list_add_tail(&gobj->list, &mdev->entities);
 		break;
 	case MEDIA_GRAPH_PAD:
 		gobj->id = media_gobj_gen_id(type, ++mdev->pad_id);
@@ -178,6 +179,7 @@ void media_gobj_init(struct media_device *mdev,
 		gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
 		break;
 	case MEDIA_GRAPH_INTF_DEVNODE:
+		list_add_tail(&gobj->list, &mdev->interfaces);
 		gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id);
 		break;
 	}
@@ -193,6 +195,15 @@ void media_gobj_init(struct media_device *mdev,
  */
 void media_gobj_remove(struct media_gobj *gobj)
 {
+	/* Remove the object from mdev list */
+	switch (media_type(gobj)) {
+	case MEDIA_GRAPH_ENTITY:
+	case MEDIA_GRAPH_INTF_DEVNODE:
+		list_del(&gobj->list);
+	default:
+		break;
+	}
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -864,8 +875,6 @@ static void media_interface_init(struct media_device *mdev,
 	INIT_LIST_HEAD(&intf->links);
 
 	media_gobj_init(mdev, gobj_type, &intf->graph_obj);
-
-	list_add_tail(&intf->list, &mdev->interfaces);
 }
 
 /* Functions related to the media interface via device nodes */
@@ -894,7 +903,6 @@ EXPORT_SYMBOL_GPL(media_devnode_create);
 void media_devnode_remove(struct media_intf_devnode *devnode)
 {
 	media_gobj_remove(&devnode->intf.graph_obj);
-	list_del(&devnode->intf.list);
 	kfree(devnode);
 }
 EXPORT_SYMBOL_GPL(media_devnode_remove);
include/media/media-device.h +2 -2
index f23d686aaac6..85fa302047bd 100644
@@ -111,11 +111,11 @@ struct media_device *media_device_find_devres(struct device *dev);
 
 /* Iterate over all entities. */
 #define media_device_for_each_entity(entity, mdev)			\
-	list_for_each_entry(entity, &(mdev)->entities, list)
+	list_for_each_entry(entity, &(mdev)->entities, graph_obj.list)
 
 /* Iterate over all interfaces. */
 #define media_device_for_each_intf(intf, mdev)			\
-	list_for_each_entry(intf, &(mdev)->interfaces, list)
+	list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
 
 
 #else
include/media/media-entity.h +1 -2
index 358a0c6b1f86..8c344a07636c 100644
@@ -66,6 +66,7 @@ enum media_gobj_type {
 struct media_gobj {
 	struct media_device	*mdev;
 	u32			id;
+	struct list_head	list;
 };
 
 
@@ -114,7 +115,6 @@ struct media_entity_operations {
 
 struct media_entity {
 	struct media_gobj graph_obj;	/* must be first field in struct */
-	struct list_head list;
 	const char *name;		/* Entity name */
 	u32 type;			/* Entity type (MEDIA_ENT_T_*) */
 	u32 revision;			/* Entity revision, driver specific */
@@ -166,7 +166,6 @@ struct media_entity {
  */
 struct media_interface {
 	struct media_gobj		graph_obj;
-	struct list_head		list;
 	struct list_head		links;
 	u32				type;
 	u32				flags;
Signature · 1 line
2.4.3
#230 lore raw

Re: [PATCH v8 46/55] [media] media: move mdev list init to gobj

Quoted 3 lines · Mauro Carvalho Chehab

Let's control the topology changes inside the graph_object. So, move the removal of interfaces/entities from the mdev lists to media_gobj_init() and media_gobj_remove().

s/removal/addition and removal/

Quoted 57 lines

The main reason is that mdev should have lists for all object types, as the new MC api will require to store objects in separate places.

drivers/media/media-device.c +1 -3
index 134fe7510195..ec98595b8a7a 100644
@@ -415,7 +415,7 @@ void media_device_unregister(struct media_device *mdev)
 	struct media_entity *entity;
 	struct media_entity *next;
 
-	list_for_each_entry_safe(entity, next, &mdev->entities, list)
+	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
 		media_device_unregister_entity(entity);
 
 	device_remove_file(&mdev->devnode.dev, &dev_attr_model);
@@ -449,7 +449,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	spin_lock(&mdev->lock);
 	/* Initialize media_gobj embedded at the entity */
 	media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
-	list_add_tail(&entity->list, &mdev->entities);
 
 	/* Initialize objects at the pads */
 	for (i = 0; i < entity->num_pads; i++)
@@ -487,7 +486,6 @@ void media_device_unregister_entity(struct media_entity *entity)
 	for (i = 0; i < entity->num_pads; i++)
 		media_gobj_remove(&entity->pads[i].graph_obj);
 	media_gobj_remove(&entity->graph_obj);
-	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
 	entity->graph_obj.mdev = NULL;
 }
drivers/media/media-entity.c +2 -0
index d62a6ffbc929..192af193a394 100644
@@ -170,6 +170,7 @@ void media_gobj_init(struct media_device *mdev,
 	switch (type) {
 	case MEDIA_GRAPH_ENTITY:
 		gobj->id = media_gobj_gen_id(type, ++mdev->entity_id);
+		list_add_tail(&gobj->list, &mdev->entities);
 		break;
 	case MEDIA_GRAPH_PAD:
 		gobj->id = media_gobj_gen_id(type, ++mdev->pad_id);
@@ -178,6 +179,7 @@ void media_gobj_init(struct media_device *mdev,
 		gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
 		break;
 	case MEDIA_GRAPH_INTF_DEVNODE:
+		list_add_tail(&gobj->list, &mdev->interfaces);
 		gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id);
 		break;
 	}

drivers/media/media-entity.c void media_gobj_init(struct media_device *mdev, · line 202

Quoted 8 lines
drivers/media/media-entity.c +5 -0
@@ -193,6 +195,15 @@ void media_gobj_init(struct media_device *mdev,
  */
 void media_gobj_remove(struct media_gobj *gobj)
 {
+	/* Remove the object from mdev list */
+	switch (media_type(gobj)) {
+	case MEDIA_GRAPH_ENTITY:
+	case MEDIA_GRAPH_INTF_DEVNODE:
+		list_del(&gobj->list);

Missing break!

Quoted 64 lines
drivers/media/media-entity.c +4 -3
+	default:
+		break;
+	}
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -864,8 +875,6 @@ static void media_interface_init(struct media_device *mdev,
 	INIT_LIST_HEAD(&intf->links);
 
 	media_gobj_init(mdev, gobj_type, &intf->graph_obj);
-
-	list_add_tail(&intf->list, &mdev->interfaces);
 }
 
 /* Functions related to the media interface via device nodes */
@@ -894,7 +903,6 @@ EXPORT_SYMBOL_GPL(media_devnode_create);
 void media_devnode_remove(struct media_intf_devnode *devnode)
 {
 	media_gobj_remove(&devnode->intf.graph_obj);
-	list_del(&devnode->intf.list);
 	kfree(devnode);
 }
 EXPORT_SYMBOL_GPL(media_devnode_remove);
include/media/media-device.h +2 -2
index f23d686aaac6..85fa302047bd 100644
@@ -111,11 +111,11 @@ struct media_device *media_device_find_devres(struct device *dev);
 
 /* Iterate over all entities. */
 #define media_device_for_each_entity(entity, mdev)			\
-	list_for_each_entry(entity, &(mdev)->entities, list)
+	list_for_each_entry(entity, &(mdev)->entities, graph_obj.list)
 
 /* Iterate over all interfaces. */
 #define media_device_for_each_intf(intf, mdev)			\
-	list_for_each_entry(intf, &(mdev)->interfaces, list)
+	list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
 
 
 #else
include/media/media-entity.h +1 -1
index 358a0c6b1f86..8c344a07636c 100644
@@ -66,6 +66,7 @@ enum media_gobj_type {
 struct media_gobj {
 	struct media_device	*mdev;
 	u32			id;
+	struct list_head	list;
 };
 
 
@@ -114,7 +115,6 @@ struct media_entity_operations {
 
 struct media_entity {
 	struct media_gobj graph_obj;	/* must be first field in struct */
-	struct list_head list;
 	const char *name;		/* Entity name */
 	u32 type;			/* Entity type (MEDIA_ENT_T_*) */
 	u32 revision;			/* Entity revision, driver specific */

include/media/media-entity.h struct media_entity { · line 171

Quoted 7 lines
include/media/media-entity.h +0 -1
@@ -166,7 +166,6 @@ struct media_entity {
  */
 struct media_interface {
 	struct media_gobj		graph_obj;
-	struct list_head		list;
 	struct list_head		links;
 	u32				type;
 	u32				flags;

Regards,

Hans

#231 lore raw

PATCH v8 47/55 media-device: add pads and links to media_device

In reply to Mauro Carvalho Chehab

The MC next gen API sends objects to userspace grouped by their types.

In the case of pads and links, in order to improve performance and have a simpler code, the best is to store them also on separate linked lists at MC.

If we don't do that, we would need this kind of interaction to send data to userspace (code is in structured english):

for each entity:
for each pad:
store pads

for each entity:
for each link:
store link

for each interface:
for each link:
store link

With would require one nexted loop for pads and two nested loops for links. By using separate linked lists for them, just one loop would be enough.

drivers/media/media-device.c +2 -0
index ec98595b8a7a..5b2c9f7fcd45 100644
@@ -382,6 +382,8 @@ int __must_check __media_device_register(struct media_device *mdev,
 
 	INIT_LIST_HEAD(&mdev->entities);
 	INIT_LIST_HEAD(&mdev->interfaces);
+	INIT_LIST_HEAD(&mdev->pads);
+	INIT_LIST_HEAD(&mdev->links);
 	spin_lock_init(&mdev->lock);
 	mutex_init(&mdev->graph_mutex);
 
drivers/media/media-entity.c +6 -10
index 192af193a394..c89f51bc688d 100644
@@ -174,13 +174,15 @@ void media_gobj_init(struct media_device *mdev,
 		break;
 	case MEDIA_GRAPH_PAD:
 		gobj->id = media_gobj_gen_id(type, ++mdev->pad_id);
+		list_add_tail(&gobj->list, &mdev->pads);
 		break;
 	case MEDIA_GRAPH_LINK:
 		gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
+		list_add_tail(&gobj->list, &mdev->links);
 		break;
 	case MEDIA_GRAPH_INTF_DEVNODE:
-		list_add_tail(&gobj->list, &mdev->interfaces);
 		gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id);
+		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
 	dev_dbg_obj(__func__, gobj);
@@ -195,16 +197,10 @@ void media_gobj_init(struct media_device *mdev,
  */
 void media_gobj_remove(struct media_gobj *gobj)
 {
+	dev_dbg_obj(__func__, gobj);
+
 	/* Remove the object from mdev list */
-	switch (media_type(gobj)) {
-	case MEDIA_GRAPH_ENTITY:
-	case MEDIA_GRAPH_INTF_DEVNODE:
-		list_del(&gobj->list);
-	default:
-		break;
-	}
-
-	dev_dbg_obj(__func__, gobj);
+	list_del(&gobj->list);
 }
 
 /**
include/media/media-device.h +12 -0
index 85fa302047bd..0d1b9c687454 100644
@@ -47,6 +47,8 @@ struct device;
  * @intf_devnode_id: Unique ID used on the last interface devnode registered
  * @entities:	List of registered entities
  * @interfaces:	List of registered interfaces
+ * @pads:	List of registered pads
+ * @links:	List of registered links
  * @lock:	Entities list lock
  * @graph_mutex: Entities graph operation lock
  * @link_notify: Link state change notification callback
@@ -79,6 +81,8 @@ struct media_device {
 
 	struct list_head entities;
 	struct list_head interfaces;
+	struct list_head pads;
+	struct list_head links;
 
 	/* Protects the entities list */
 	spinlock_t lock;
@@ -117,6 +121,14 @@ struct media_device *media_device_find_devres(struct device *dev);
 #define media_device_for_each_intf(intf, mdev)			\
 	list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
 
+/* Iterate over all pads. */
+#define media_device_for_each_pad(pad, mdev)			\
+	list_for_each_entry(pad, &(mdev)->pads, graph_obj.list)
+
+/* Iterate over all links. */
+#define media_device_for_each_link(link, mdev)			\
+	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
+
 
 #else
 static inline int media_device_register(struct media_device *mdev)
Signature · 1 line
2.4.3
Acked-by on v8 47/55
#232 lore raw

Re: [PATCH v8 47/55] [media] media-device: add pads and links to media_device

Quoted 22 lines · Mauro Carvalho Chehab

The MC next gen API sends objects to userspace grouped by their types.

In the case of pads and links, in order to improve performance and have a simpler code, the best is to store them also on separate linked lists at MC.

If we don't do that, we would need this kind of interaction to send data to userspace (code is in structured english):

for each entity:
for each pad:
store pads

for each entity:
for each link:
store link

for each interface:
for each link:
store link

Quoted 5 lines

With would require one nexted loop for pads and two nested loops for links. By using separate linked lists for them, just one loop would be enough.

Quoted 93 lines
drivers/media/media-device.c +2 -0
index ec98595b8a7a..5b2c9f7fcd45 100644
@@ -382,6 +382,8 @@ int __must_check __media_device_register(struct media_device *mdev,
 
 	INIT_LIST_HEAD(&mdev->entities);
 	INIT_LIST_HEAD(&mdev->interfaces);
+	INIT_LIST_HEAD(&mdev->pads);
+	INIT_LIST_HEAD(&mdev->links);
 	spin_lock_init(&mdev->lock);
 	mutex_init(&mdev->graph_mutex);
 
drivers/media/media-entity.c +6 -10
index 192af193a394..c89f51bc688d 100644
@@ -174,13 +174,15 @@ void media_gobj_init(struct media_device *mdev,
 		break;
 	case MEDIA_GRAPH_PAD:
 		gobj->id = media_gobj_gen_id(type, ++mdev->pad_id);
+		list_add_tail(&gobj->list, &mdev->pads);
 		break;
 	case MEDIA_GRAPH_LINK:
 		gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
+		list_add_tail(&gobj->list, &mdev->links);
 		break;
 	case MEDIA_GRAPH_INTF_DEVNODE:
-		list_add_tail(&gobj->list, &mdev->interfaces);
 		gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id);
+		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
 	dev_dbg_obj(__func__, gobj);
@@ -195,16 +197,10 @@ void media_gobj_init(struct media_device *mdev,
  */
 void media_gobj_remove(struct media_gobj *gobj)
 {
+	dev_dbg_obj(__func__, gobj);
+
 	/* Remove the object from mdev list */
-	switch (media_type(gobj)) {
-	case MEDIA_GRAPH_ENTITY:
-	case MEDIA_GRAPH_INTF_DEVNODE:
-		list_del(&gobj->list);
-	default:
-		break;
-	}
-
-	dev_dbg_obj(__func__, gobj);
+	list_del(&gobj->list);
 }
 
 /**
include/media/media-device.h +12 -0
index 85fa302047bd..0d1b9c687454 100644
@@ -47,6 +47,8 @@ struct device;
  * @intf_devnode_id: Unique ID used on the last interface devnode registered
  * @entities:	List of registered entities
  * @interfaces:	List of registered interfaces
+ * @pads:	List of registered pads
+ * @links:	List of registered links
  * @lock:	Entities list lock
  * @graph_mutex: Entities graph operation lock
  * @link_notify: Link state change notification callback
@@ -79,6 +81,8 @@ struct media_device {
 
 	struct list_head entities;
 	struct list_head interfaces;
+	struct list_head pads;
+	struct list_head links;
 
 	/* Protects the entities list */
 	spinlock_t lock;
@@ -117,6 +121,14 @@ struct media_device *media_device_find_devres(struct device *dev);
 #define media_device_for_each_intf(intf, mdev)			\
 	list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
 
+/* Iterate over all pads. */
+#define media_device_for_each_pad(pad, mdev)			\
+	list_for_each_entry(pad, &(mdev)->pads, graph_obj.list)
+
+/* Iterate over all links. */
+#define media_device_for_each_link(link, mdev)			\
+	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
+
 
 #else
 static inline int media_device_register(struct media_device *mdev)
#233 lore raw

PATCH v8 48/55 media_device: add a topology version field

In reply to Mauro Carvalho Chehab

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

drivers/media/media-entity.c +5 -0
index c89f51bc688d..c18f4af52771 100644
@@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev,
 		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
+
+	mdev->topology_version++;
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj)
 {
 	dev_dbg_obj(__func__, gobj);
 
+	gobj->mdev->topology_version++;
+
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
 }
include/media/media-device.h +4 -0
index 0d1b9c687454..1b12774a9ab4 100644
@@ -41,6 +41,8 @@ struct device;
  * @bus_info:	Unique and stable device location identifier
  * @hw_revision: Hardware device revision
  * @driver_version: Device driver version
+ * @topology_version: Monotonic counter for storing the version of the graph
+ *		topology. Should be incremented each time the topology changes.
  * @entity_id:	Unique ID used on the last entity registered
  * @pad_id:	Unique ID used on the last pad registered
  * @link_id:	Unique ID used on the last link registered
@@ -74,6 +76,8 @@ struct media_device {
 	u32 hw_revision;
 	u32 driver_version;
 
+	u32 topology_version;
+
 	u32 entity_id;
 	u32 pad_id;
 	u32 link_id;
Signature · 1 line
2.4.3
#234 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

Quoted 6 lines · Mauro Carvalho Chehab

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

I think this should be postponed until we actually have dynamic reconfigurable graphs.

I would also like to reserve version 0: if 0 is returned, then the graph is static.

In G_TOPOLOGY we'd return always 0 for now.

Regards,

Hans

Quoted 47 lines
drivers/media/media-entity.c +5 -0
index c89f51bc688d..c18f4af52771 100644
@@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev,
 		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
+
+	mdev->topology_version++;
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj)
 {
 	dev_dbg_obj(__func__, gobj);
 
+	gobj->mdev->topology_version++;
+
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
 }
include/media/media-device.h +4 -0
index 0d1b9c687454..1b12774a9ab4 100644
@@ -41,6 +41,8 @@ struct device;
  * @bus_info:	Unique and stable device location identifier
  * @hw_revision: Hardware device revision
  * @driver_version: Device driver version
+ * @topology_version: Monotonic counter for storing the version of the graph
+ *		topology. Should be incremented each time the topology changes.
  * @entity_id:	Unique ID used on the last entity registered
  * @pad_id:	Unique ID used on the last pad registered
  * @link_id:	Unique ID used on the last link registered
@@ -74,6 +76,8 @@ struct media_device {
 	u32 hw_revision;
 	u32 driver_version;
 
+	u32 topology_version;
+
 	u32 entity_id;
 	u32 pad_id;
 	u32 link_id;
#235 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

Em Mon, 31 Aug 2015 14:29:28 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 6 lines

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

I think this should be postponed until we actually have dynamic reconfigurable graphs.

So far, we're using the term "dynamic" to mean partial graph object removal.

But even today, MC does support "dynamic" in the sense of graph object additions.

You should notice that having a topology_version is something that IMHO, it is needed since the beginning, even without dynamic reconfigurable graphs, because the graph may grow in runtime.

That will happen, for example, if usb-snd-audio is blacklisted at /etc/modprobe*, and someone connects an au0828.

New entities/links will be created (after Shuah patches) if one would modprobe latter snd-usb-audio.

Quoted 3 lines

I would also like to reserve version 0: if 0 is returned, then the graph is static.

Why? Implementing this would be really hard, as that would mean that G_TOPOLOGY would need to be blocked until all drivers and subdevices get probed.

In order to implement that, some logic would be needed at the drivers to identify if everything was set and unlock G_TOPOLOGY.

What would be the gain for that? I fail to see any.

On the other hand, the patch below offers a simple way to detect if topology changes, as, no matter if an object was added or removed, the topology version will be increased.

Btw, I added a logic at the mc_nextgen_test program to identify if the topology changes between the two calls:

	http://git.linuxtv.org/cgit.cgi/mchehab/experimental-v4l-utils.git/tree/contrib/test/mc_nextgen_test.c?h=mc-next-gen&id=fdc16ece9732c94cfa76eee86978158c5976c00a#n504

Regards,
Mauro

Quoted 55 lines

In G_TOPOLOGY we'd return always 0 for now.

Regards,

Hans

Quoted 47 lines
drivers/media/media-entity.c +5 -0
index c89f51bc688d..c18f4af52771 100644
@@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev,
 		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
+
+	mdev->topology_version++;
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj)
 {
 	dev_dbg_obj(__func__, gobj);
 
+	gobj->mdev->topology_version++;
+
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
 }
include/media/media-device.h +4 -0
index 0d1b9c687454..1b12774a9ab4 100644
@@ -41,6 +41,8 @@ struct device;
  * @bus_info:	Unique and stable device location identifier
  * @hw_revision: Hardware device revision
  * @driver_version: Device driver version
+ * @topology_version: Monotonic counter for storing the version of the graph
+ *		topology. Should be incremented each time the topology changes.
  * @entity_id:	Unique ID used on the last entity registered
  * @pad_id:	Unique ID used on the last pad registered
  * @link_id:	Unique ID used on the last link registered
@@ -74,6 +76,8 @@ struct media_device {
 	u32 hw_revision;
 	u32 driver_version;
 
+	u32 topology_version;
+
 	u32 entity_id;
 	u32 pad_id;
 	u32 link_id;
#236 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

Quoted 24 lines · Mauro Carvalho Chehab

Em Mon, 31 Aug 2015 14:29:28 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 6 lines

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

I think this should be postponed until we actually have dynamic reconfigurable graphs.

So far, we're using the term "dynamic" to mean partial graph object removal.

But even today, MC does support "dynamic" in the sense of graph object additions.

You should notice that having a topology_version is something that IMHO, it is needed since the beginning, even without dynamic reconfigurable graphs, because the graph may grow in runtime.

Quoted 5 lines

That will happen, for example, if usb-snd-audio is blacklisted at /etc/modprobe*, and someone connects an au0828.

New entities/links will be created (after Shuah patches) if one would modprobe latter snd-usb-audio.

latter -> later :-)

You are right, this would trigger a topology change. I hadn't thought about that.

Quoted 11 lines
Quoted 4 lines

I would also like to reserve version 0: if 0 is returned, then the graph is static.

Why? Implementing this would be really hard, as that would mean that G_TOPOLOGY would need to be blocked until all drivers and subdevices get probed.

In order to implement that, some logic would be needed at the drivers to identify if everything was set and unlock G_TOPOLOGY.

That wouldn't be needed if the media device node was created last. Which I think is a good idea anyway.

Quoted 2 lines

What would be the gain for that? I fail to see any.

It would tell userspace that it doesn't have to cope with dynamically changing graphs.

Even though with the au0828 example you can expect to see cases like that, I can pretty much guarantee that no generic v4l2 applications will ever support dynamic changes. Those that will support it will be custom-made.

Being able to see that graphs can change dynamically would allow such apps to either refuse to use the device, or warn the user.

Regards,

Hans

Quoted 67 lines

On the other hand, the patch below offers a simple way to detect if topology changes, as, no matter if an object was added or removed, the topology version will be increased.

Btw, I added a logic at the mc_nextgen_test program to identify if the topology changes between the two calls:

	http://git.linuxtv.org/cgit.cgi/mchehab/experimental-v4l-utils.git/tree/contrib/test/mc_nextgen_test.c?h=mc-next-gen&id=fdc16ece9732c94cfa76eee86978158c5976c00a#n504

Regards,
Mauro

Quoted 55 lines

In G_TOPOLOGY we'd return always 0 for now.

Regards,

Hans

Quoted 47 lines
drivers/media/media-entity.c +5 -0
index c89f51bc688d..c18f4af52771 100644
@@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev,
 		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
+
+	mdev->topology_version++;
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj)
 {
 	dev_dbg_obj(__func__, gobj);
 
+	gobj->mdev->topology_version++;
+
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
 }
include/media/media-device.h +4 -0
index 0d1b9c687454..1b12774a9ab4 100644
@@ -41,6 +41,8 @@ struct device;
  * @bus_info:	Unique and stable device location identifier
  * @hw_revision: Hardware device revision
  * @driver_version: Device driver version
+ * @topology_version: Monotonic counter for storing the version of the graph
+ *		topology. Should be incremented each time the topology changes.
  * @entity_id:	Unique ID used on the last entity registered
  * @pad_id:	Unique ID used on the last pad registered
  * @link_id:	Unique ID used on the last link registered
@@ -74,6 +76,8 @@ struct media_device {
 	u32 hw_revision;
 	u32 driver_version;
 
+	u32 topology_version;
+
 	u32 entity_id;
 	u32 pad_id;
 	u32 link_id;
#237 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

Em Mon, 31 Aug 2015 15:35:38 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 45 lines · Mauro Carvalho Chehab
Quoted 24 lines

Em Mon, 31 Aug 2015 14:29:28 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 6 lines

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

I think this should be postponed until we actually have dynamic reconfigurable graphs.

So far, we're using the term "dynamic" to mean partial graph object removal.

But even today, MC does support "dynamic" in the sense of graph object additions.

You should notice that having a topology_version is something that IMHO, it is needed since the beginning, even without dynamic reconfigurable graphs, because the graph may grow in runtime.

Quoted 5 lines

That will happen, for example, if usb-snd-audio is blacklisted at /etc/modprobe*, and someone connects an au0828.

New entities/links will be created (after Shuah patches) if one would modprobe latter snd-usb-audio.

latter -> later :-)

You are right, this would trigger a topology change. I hadn't thought about that.

Quoted 9 lines
Quoted 4 lines

I would also like to reserve version 0: if 0 is returned, then the graph is static.

Why? Implementing this would be really hard, as that would mean that G_TOPOLOGY would need to be blocked until all drivers and subdevices get probed.

Quoted 5 lines
Quoted 2 lines

In order to implement that, some logic would be needed at the drivers to identify if everything was set and unlock G_TOPOLOGY.

That wouldn't be needed if the media device node was created last. Which I think is a good idea anyway.

Creating the media device node last won't work. It should be the first thing to be created, as all objects should be added to media_device linked lists.

Also, the numberspace should be local to a given media_device, as the graph traversal algorithm relies on having the number of entities <= 64, currently, in order to be able to detect loops. We should increase that number, but removing an "as low as possible" entity number limit is not trivial.

Quoted 10 lines
Quoted 3 lines

What would be the gain for that? I fail to see any.

It would tell userspace that it doesn't have to cope with dynamically changing graphs.

Even though with the au0828 example you can expect to see cases like that, I can pretty much guarantee that no generic v4l2 applications will ever support dynamic changes.

Well, my test app supports it and it is generic ;) My plan is to use it as a basis for the library to be used on userspace for generic apps, extending it to be used by other tools like xawtv, qv4l2 and the dvbv5 apps.

I don't think it is hard to handle it on a generic app, and this should be done anyway if we want dynamic support.

The logic seems actually be simple:

at G_TOPOLOGY, if the topology changes, reload the objects;

at SETUP_LINK_V2, the topology will be sent. if the driver detects that topology changed, it returns an error.

The caller will then need to reload the topology and re-apply the transaction to select the links, if the entities affected still exists. In other words, if the user's intent were to change the pipeline to receive the data at /dev/video2, e. g. something like:

	./yavta/yavta -f UYVY -s 720x312 -n 1 --capture=1 -F /dev/video2

What userspace would do is to reload everything, check if /dev/video2 still exists and then redo the function that it is equivalent to the above command, failing otherwise. That doesn't sound hard to implement.

Quoted 4 lines

Those that will support it will be custom-made.

Being able to see that graphs can change dynamically would allow such apps to either refuse to use the device, or warn the user.

The way I see is that applications that will assume that the graph is static will be the custom-made ones. As they know the hardware, they can just either ignore the topology_version or wait for it to stabilize when the hardware is still being probed.

In any case, if we end by needing to have an explicit way for the Kernelspace to tell userspace that a graph is static, that could be done via an extra flag at MEDIA_INFO.

Enabling this flag could be as easy as waiting for all graph elements to be created (where the topology is still dynamic), and raise such flag after finishing the probe sequence.

Regards,
Mauro

maintainer
#238 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

Hi Mauro,

Quoted 34 lines · On Friday 04 September 2015 14:08:27 Mauro Carvalho Chehab wrote:

Em Mon, 31 Aug 2015 15:35:38 +0200 Hans Verkuil escreveu:

Quoted 33 lines · Mauro Carvalho Chehab
Quoted 22 lines

Em Mon, 31 Aug 2015 14:29:28 +0200 Hans Verkuil escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 6 lines

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

I think this should be postponed until we actually have dynamic reconfigurable graphs.

So far, we're using the term "dynamic" to mean partial graph object removal.

But even today, MC does support "dynamic" in the sense of graph object additions.

You should notice that having a topology_version is something that IMHO, it is needed since the beginning, even without dynamic reconfigurable graphs, because the graph may grow in runtime.

Quoted 5 lines

That will happen, for example, if usb-snd-audio is blacklisted at /etc/modprobe*, and someone connects an au0828.

New entities/links will be created (after Shuah patches) if one would modprobe latter snd-usb-audio.

latter -> later :-)

You are right, this would trigger a topology change. I hadn't thought about that.

First of all it won't be very useful without a topology change notification, so until we have them it doesn't matter too much. Then, the code is full of race conditions when it comes to dynamic updates, and I'm afraid Shua's patches can't go in before we fix them.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

I would also like to reserve version 0: if 0 is returned, then the graph is static.

Why? Implementing this would be really hard, as that would mean that G_TOPOLOGY would need to be blocked until all drivers and subdevices get probed.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

In order to implement that, some logic would be needed at the drivers to identify if everything was set and unlock G_TOPOLOGY.

That wouldn't be needed if the media device node was created last. Which I think is a good idea anyway.

Creating the media device node last won't work. It should be the first thing to be created, as all objects should be added to media_device linked lists.

I disagree with that. The media_device needs to be initialized first, but can be registered with userspace last. We don't want to generate a topology update event for every new entity, link or pad during the device probe sequence. Drivers should be in control and tell when they're done with initialization.

Quoted 15 lines

Also, the numberspace should be local to a given media_device, as the graph traversal algorithm relies on having the number of entities <= 64, currently, in order to be able to detect loops. We should increase that number, but removing an "as low as possible" entity number limit is not trivial.

Quoted 8 lines
Quoted 1 line

What would be the gain for that? I fail to see any.

It would tell userspace that it doesn't have to cope with dynamically changing graphs.

Even though with the au0828 example you can expect to see cases like that, I can pretty much guarantee that no generic v4l2 applications will ever support dynamic changes.

Quoted 5 lines

Well, my test app supports it and it is generic ;) My plan is to use it as a basis for the library to be used on userspace for generic apps, extending it to be used by other tools like xawtv, qv4l2 and the dvbv5 apps.

I don't think it is hard to handle it on a generic app,

I'll quote you later on that :-)

Quoted 5 lines

and this should be done anyway if we want dynamic support.

The logic seems actually be simple:

at G_TOPOLOGY, if the topology changes, reload the objects;

And update everything in userspace. That's a very hard task if you don't design your applications extremely carefully.

Quoted 13 lines

at SETUP_LINK_V2, the topology will be sent. if the driver detects that topology changed, it returns an error.

The caller will then need to reload the topology and re-apply the transaction to select the links, if the entities affected still exists. In other words, if the user's intent were to change the pipeline to receive the data at /dev/video2, e. g. something like:

	./yavta/yavta -f UYVY -s 720x312 -n 1 --capture=1 -F /dev/video2

What userspace would do is to reload everything, check if /dev/video2 still exists and then redo the function that it is equivalent to the above command, failing otherwise. That doesn't sound hard to implement.

Quoted 7 lines
Quoted 4 lines

Those that will support it will be custom-made.

Being able to see that graphs can change dynamically would allow such apps to either refuse to use the device, or warn the user.

The way I see is that applications that will assume that the graph is static will be the custom-made ones.

Or (some of) the generic ones.

Quoted 6 lines

As they know the hardware, they can just either ignore the topology_version or wait for it to stabilize when the hardware is still being probed.

In any case, if we end by needing to have an explicit way for the Kernelspace to tell userspace that a graph is static, that could be done via an extra flag at MEDIA_INFO.

Why ? I don't see anything wrong with reversing version 0 for that purpose, as Hans proposed.

Quoted 3 lines

Enabling this flag could be as easy as waiting for all graph elements to be created (where the topology is still dynamic), and raise such flag after finishing the probe sequence.

Signature · 3 lines
Regards,

Laurent Pinchart
#239 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

Em Tue, 24 Nov 2015 00:18:07 +0200
Laurent Pinchart <[email protected]> escreveu:

Quoted 33 lines

Hi Mauro,

Quoted 30 lines · On Friday 04 September 2015 14:08:27 Mauro Carvalho Chehab wrote:

Em Mon, 31 Aug 2015 15:35:38 +0200 Hans Verkuil escreveu:

Quoted 29 lines · Mauro Carvalho Chehab
Quoted 27 lines

Em Mon, 31 Aug 2015 14:29:28 +0200 Hans Verkuil escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 6 lines

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

I think this should be postponed until we actually have dynamic reconfigurable graphs.

So far, we're using the term "dynamic" to mean partial graph object removal.

But even today, MC does support "dynamic" in the sense of graph object additions.

You should notice that having a topology_version is something that IMHO, it is needed since the beginning, even without dynamic reconfigurable graphs, because the graph may grow in runtime.

That will happen, for example, if usb-snd-audio is blacklisted at /etc/modprobe*, and someone connects an au0828.

New entities/links will be created (after Shuah patches) if one would modprobe latter snd-usb-audio.

Quoted 7 lines
Quoted 4 lines
Quoted 4 lines

latter -> later :-)

You are right, this would trigger a topology change. I hadn't thought about that.

First of all it won't be very useful without a topology change notification, so until we have them it doesn't matter too much.

I'm not sure if we need an explicit topology change notification. The way I see, we just need to add a topology_version at SET_LINK_V2. The topology should be filled by userspace, based on the last topology from G_TOPOLOGY.

If topology_version is different than the one at Kernelspace, Kernel will return an error that would cause userspace to call G_TOPOLOGY again.

Ok, a topology notification could be added in order to help userspace to detect changes, but this is an unrelated.

Quoted 3 lines

Then, the code is full of
race conditions when it comes to dynamic updates, and I'm afraid Shua's patches can't go in before we fix them.

The race conditions are related to dynamic removal. Dynamic creation should be OK.

We'll review the locks to be sure that this would work fine.

Quoted 14 lines
Quoted 14 lines
Quoted 13 lines
Quoted 10 lines
Quoted 3 lines

I would also like to reserve version 0: if 0 is returned, then the graph is static.

Why? Implementing this would be really hard, as that would mean that G_TOPOLOGY would need to be blocked until all drivers and subdevices get probed.

In order to implement that, some logic would be needed at the drivers to identify if everything was set and unlock G_TOPOLOGY.

That wouldn't be needed if the media device node was created last. Which I think is a good idea anyway.

Quoted 7 lines
Quoted 2 lines

Creating the media device node last won't work. It should be the first thing to be created, as all objects should be added to media_device linked lists.

I disagree with that. The media_device needs to be initialized first, but can be registered with userspace last. We don't want to generate a topology update event for every new entity, link or pad during the device probe sequence. Drivers should be in control and tell when they're done with initialization.

This comment is outdated ;)

Javier wrote a patch series already addressing this: it basically splits the internal registration from the userspace API registration.

See:
[PATCH v4 0/2] [media] Fix race between graph enumeration and entities registration

The idea is to postpone the latter to happen after having all entitites/links/subdevices created.

It is unrelated to the MC next gen, so he submitted in separate. I guess Sakari already acked his patches.

I'll be merging his series after finishing the merge of MC next gen.

Quoted 24 lines
Quoted 16 lines

Also, the numberspace should be local to a given media_device, as the graph traversal algorithm relies on having the number of entities <= 64, currently, in order to be able to detect loops. We should increase that number, but removing an "as low as possible" entity number limit is not trivial.

Quoted 8 lines
Quoted 1 line

What would be the gain for that? I fail to see any.

It would tell userspace that it doesn't have to cope with dynamically changing graphs.

Even though with the au0828 example you can expect to see cases like that, I can pretty much guarantee that no generic v4l2 applications will ever support dynamic changes.

Quoted 5 lines

Well, my test app supports it and it is generic ;) My plan is to use it as a basis for the library to be used on userspace for generic apps, extending it to be used by other tools like xawtv, qv4l2 and the dvbv5 apps.

I don't think it is hard to handle it on a generic app,

I'll quote you later on that :-)

Quoted 8 lines
Quoted 5 lines

and this should be done anyway if we want dynamic support.

The logic seems actually be simple:

at G_TOPOLOGY, if the topology changes, reload the objects;

And update everything in userspace. That's a very hard task if you don't design your applications extremely carefully.

True.

Quoted 16 lines
Quoted 16 lines

at SETUP_LINK_V2, the topology will be sent. if the driver detects that topology changed, it returns an error.

The caller will then need to reload the topology and re-apply the transaction to select the links, if the entities affected still exists. In other words, if the user's intent were to change the pipeline to receive the data at /dev/video2, e. g. something like:

	./yavta/yavta -f UYVY -s 720x312 -n 1 --capture=1 -F /dev/video2

What userspace would do is to reload everything, check if /dev/video2 still exists and then redo the function that it is equivalent to the above command, failing otherwise. That doesn't sound hard to implement.

Quoted 2 lines

Those that will support it will be custom-made.

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Being able to see that graphs can change dynamically would allow such apps to either refuse to use the device, or warn the user.

The way I see is that applications that will assume that the graph is static will be the custom-made ones.

Or (some of) the generic ones.

If the app doesn't support dynamic changes, it is not generic, as it will only support simple graphs that are provided by just a single driver.

Quoted 10 lines
Quoted 7 lines

As they know the hardware, they can just either ignore the topology_version or wait for it to stabilize when the hardware is still being probed.

In any case, if we end by needing to have an explicit way for the Kernelspace to tell userspace that a graph is static, that could be done via an extra flag at MEDIA_INFO.

Why ? I don't see anything wrong with reversing version 0 for that purpose, as Hans proposed.

Well, we can do that: we can zero the topology_version at media_device_register() (see Javier's patch "media-device: split media initialization and registration")

This way, topology_version will be zero if the topology never changed after registering the media controller userspace API.

That doesn't warrant that the topology will never change. Such change will happen, for example, during driver (or sub-driver) removal or unbind. Taking this into account, I doubt that we have any driver that has a static topology, because the driver can be removed and/or unbind from the hardware.

Quoted 5 lines
Quoted 4 lines

Enabling this flag could be as easy as waiting for all graph elements to be created (where the topology is still dynamic), and raise such flag after finishing the probe sequence.

maintainer
#240 lore raw

Re: [PATCH v8 48/55] [media] media_device: add a topology version field

In reply to Hans Verkuil

Hi Mauro and Hans,

Quoted 8 lines · On Monday 31 August 2015 14:29:28 Hans Verkuil wrote:
Quoted 6 lines · Mauro Carvalho Chehab

Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.

Quoted 7 lines

I think this should be postponed until we actually have dynamic reconfigurable graphs.

I would also like to reserve version 0: if 0 is returned, then the graph is static.

In G_TOPOLOGY we'd return always 0 for now.

So would I. We need a way to group graph modifications to avoid incrementing the version number and generating an event for every entity, link or pad added or removed. As this patch doesn't address that I don't see a use for the version number now other than making our life more difficult when we'll implement dynamic updates by forcing us to consider backward compatibility with something that we know won't do the job.

Quoted 46 lines
Quoted 46 lines
drivers/media/media-entity.c +5 -0
index c89f51bc688d..c18f4af52771 100644
@@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev,
 		list_add_tail(&gobj->list, &mdev->interfaces);
 		break;
 	}
+
+	mdev->topology_version++;
+
 	dev_dbg_obj(__func__, gobj);
 }
 
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj)
 {
 	dev_dbg_obj(__func__, gobj);
 
+	gobj->mdev->topology_version++;
+
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
 }
include/media/media-device.h +1 -0
index 0d1b9c687454..1b12774a9ab4 100644
@@ -41,6 +41,8 @@ struct device;
  * @bus_info:	Unique and stable device location identifier
  * @hw_revision: Hardware device revision
  * @driver_version: Device driver version
+ * @topology_version: Monotonic counter for storing the version of the

graph
+ * topology. Should be incremented each time the topology changes.
* @entity_id: Unique ID used on the last entity registered
* @pad_id: Unique ID used on the last pad registered
* @link_id: Unique ID used on the last link registered

include/media/media-device.h +2 -0
@@ -74,6 +76,8 @@ struct media_device {
 	u32 hw_revision;
 	u32 driver_version;
 
+	u32 topology_version;
+
 	u32 entity_id;
 	u32 pad_id;
 	u32 link_id;
Signature · 3 lines
Regards,

Laurent Pinchart
#241 lore raw

PATCH v8 49/55 media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl

In reply to Mauro Carvalho Chehab

Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation.

drivers/media/media-device.c +138 -0
index 5b2c9f7fcd45..a91e1ec076a6 100644
@@ -232,6 +232,136 @@ static long media_device_setup_link(struct media_device *mdev,
 	return ret;
 }
 
+static long __media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology *topo)
+{
+	struct media_entity *entity;
+	struct media_interface *intf;
+	struct media_pad *pad;
+	struct media_link *link;
+	struct media_v2_entity uentity;
+	struct media_v2_interface uintf;
+	struct media_v2_pad upad;
+	struct media_v2_link ulink;
+	int ret = 0, i;
+
+	topo->topology_version = mdev->topology_version;
+
+	/* Get entities and number of entities */
+	i = 0;
+	media_device_for_each_entity(entity, mdev) {
+		i++;
+
+		if (ret || !topo->entities)
+			continue;
+
+		/* Copy fields to userspace struct if not error */
+		memset(&uentity, 0, sizeof(uentity));
+		uentity.id = entity->graph_obj.id;
+		strncpy(uentity.name, entity->name,
+			sizeof(uentity.name));
+
+		if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity)))
+			ret = -EFAULT;
+	}
+	topo->num_entities = i;
+
+	/* Get interfaces and number of interfaces */
+	i = 0;
+	media_device_for_each_intf(intf, mdev) {
+		i++;
+
+		if (ret || !topo->interfaces)
+			continue;
+
+		memset(&uintf, 0, sizeof(uintf));
+
+		/* Copy intf fields to userspace struct */
+		uintf.id = intf->graph_obj.id;
+		uintf.intf_type = intf->type;
+		uintf.flags = intf->flags;
+
+		if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
+			struct media_intf_devnode *devnode;
+
+			devnode = intf_to_devnode(intf);
+
+			uintf.devnode.major = devnode->major;
+			uintf.devnode.minor = devnode->minor;
+		}
+
+		if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf)))
+			ret = -EFAULT;
+	}
+	topo->num_interfaces = i;
+
+	/* Get pads and number of pads */
+	i = 0;
+	media_device_for_each_pad(pad, mdev) {
+		i++;
+
+		if (ret || !topo->pads)
+			continue;
+
+		memset(&upad, 0, sizeof(upad));
+
+		/* Copy pad fields to userspace struct */
+		upad.id = pad->graph_obj.id;
+		upad.entity_id = pad->entity->graph_obj.id;
+		upad.flags = pad->flags;
+
+		if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad)))
+			ret = -EFAULT;
+	}
+	topo->num_pads = i;
+
+	/* Get links and number of links */
+	i = 0;
+	media_device_for_each_link(link, mdev) {
+		i++;
+
+		if (ret || !topo->links)
+			continue;
+
+		memset(&ulink, 0, sizeof(ulink));
+
+		/* Copy link fields to userspace struct */
+		ulink.id = link->graph_obj.id;
+		ulink.source_id = link->gobj0->id;
+		ulink.sink_id = link->gobj1->id;
+		ulink.flags = link->flags;
+
+		if (media_type(link->gobj0) != MEDIA_GRAPH_PAD)
+			ulink.flags |= MEDIA_NEW_LNK_FL_INTERFACE_LINK;
+
+		if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink)))
+			ret = -EFAULT;
+	}
+	topo->num_links = i;
+
+	return ret;
+}
+
+static long media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology __user *utopo)
+{
+	struct media_v2_topology ktopo;
+	int ret;
+
+	ret = copy_from_user(&ktopo, utopo, sizeof(ktopo));
+
+	if (ret < 0)
+		return ret;
+
+	ret = __media_device_get_topology(mdev, &ktopo);
+	if (ret < 0)
+		return ret;
+
+	ret = copy_to_user(utopo, &ktopo, sizeof(*utopo));
+
+	return ret;
+}
+
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
 			       unsigned long arg)
 {
@@ -264,6 +394,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
 		mutex_unlock(&dev->graph_mutex);
 		break;
 
+	case MEDIA_IOC_G_TOPOLOGY:
+		mutex_lock(&dev->graph_mutex);
+		ret = media_device_get_topology(dev,
+				(struct media_v2_topology __user *)arg);
+		mutex_unlock(&dev->graph_mutex);
+		break;
+
 	default:
 		ret = -ENOIOCTLCMD;
 	}
@@ -312,6 +449,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
 	case MEDIA_IOC_DEVICE_INFO:
 	case MEDIA_IOC_ENUM_ENTITIES:
 	case MEDIA_IOC_SETUP_LINK:
+	case MEDIA_IOC_G_TOPOLOGY:
 		return media_device_ioctl(filp, cmd, arg);
 
 	case MEDIA_IOC_ENUM_LINKS32:
Signature · 1 line
2.4.3
#242 lore raw

Re: [PATCH v8 49/55] [media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl

Quoted 25 lines · Mauro Carvalho Chehab

Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation.

drivers/media/media-device.c +12 -0
index 5b2c9f7fcd45..a91e1ec076a6 100644
@@ -232,6 +232,136 @@ static long media_device_setup_link(struct media_device *mdev,
 	return ret;
 }
 
+static long __media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology *topo)
+{
+	struct media_entity *entity;
+	struct media_interface *intf;
+	struct media_pad *pad;
+	struct media_link *link;
+	struct media_v2_entity uentity;
+	struct media_v2_interface uintf;
+	struct media_v2_pad upad;
+	struct media_v2_link ulink;
+	int ret = 0, i;

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 256

Quoted 10 lines
drivers/media/media-device.c +10 -0
+
+	topo->topology_version = mdev->topology_version;
+
+	/* Get entities and number of entities */
+	i = 0;
+	media_device_for_each_entity(entity, mdev) {
+		i++;
+
+		if (ret || !topo->entities)
+			continue;

I would add:

		if (i > topo->num_entities)
			continue;

The copy_to_user can succeed, even if i > num_entities depending on how the memory was allocated. So I would always check num_entities and refuse to go beyond it.

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 265

Quoted 9 lines
drivers/media/media-device.c +9 -0
+
+		/* Copy fields to userspace struct if not error */
+		memset(&uentity, 0, sizeof(uentity));
+		uentity.id = entity->graph_obj.id;
+		strncpy(uentity.name, entity->name,
+			sizeof(uentity.name));
+
+		if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity)))
+			ret = -EFAULT;

I would just return here. If the user gives bogus values for this, then just give up.

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 267

Quoted 2 lines
drivers/media/media-device.c +2 -0
+	}
+	topo->num_entities = i;

What to do if topo->entities != NULL and i > topo->num_entities? Just return 0 or return ENOSPC? I'm in favor of ENOSPC since a partial topology result is useless. But if ENOSPC is returned, then all num_foo values should be updated with the current number of elements.

This behavior would be consistent with e.g. VIDIOC_G_EXT_CTRLS.

Quoted 116 lines
drivers/media/media-device.c +104 -0
+
+	/* Get interfaces and number of interfaces */
+	i = 0;
+	media_device_for_each_intf(intf, mdev) {
+		i++;
+
+		if (ret || !topo->interfaces)
+			continue;
+
+		memset(&uintf, 0, sizeof(uintf));
+
+		/* Copy intf fields to userspace struct */
+		uintf.id = intf->graph_obj.id;
+		uintf.intf_type = intf->type;
+		uintf.flags = intf->flags;
+
+		if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
+			struct media_intf_devnode *devnode;
+
+			devnode = intf_to_devnode(intf);
+
+			uintf.devnode.major = devnode->major;
+			uintf.devnode.minor = devnode->minor;
+		}
+
+		if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf)))
+			ret = -EFAULT;
+	}
+	topo->num_interfaces = i;
+
+	/* Get pads and number of pads */
+	i = 0;
+	media_device_for_each_pad(pad, mdev) {
+		i++;
+
+		if (ret || !topo->pads)
+			continue;
+
+		memset(&upad, 0, sizeof(upad));
+
+		/* Copy pad fields to userspace struct */
+		upad.id = pad->graph_obj.id;
+		upad.entity_id = pad->entity->graph_obj.id;
+		upad.flags = pad->flags;
+
+		if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad)))
+			ret = -EFAULT;
+	}
+	topo->num_pads = i;
+
+	/* Get links and number of links */
+	i = 0;
+	media_device_for_each_link(link, mdev) {
+		i++;
+
+		if (ret || !topo->links)
+			continue;
+
+		memset(&ulink, 0, sizeof(ulink));
+
+		/* Copy link fields to userspace struct */
+		ulink.id = link->graph_obj.id;
+		ulink.source_id = link->gobj0->id;
+		ulink.sink_id = link->gobj1->id;
+		ulink.flags = link->flags;
+
+		if (media_type(link->gobj0) != MEDIA_GRAPH_PAD)
+			ulink.flags |= MEDIA_NEW_LNK_FL_INTERFACE_LINK;
+
+		if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink)))
+			ret = -EFAULT;
+	}
+	topo->num_links = i;
+
+	return ret;
+}
+
+static long media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology __user *utopo)
+{
+	struct media_v2_topology ktopo;
+	int ret;
+
+	ret = copy_from_user(&ktopo, utopo, sizeof(ktopo));
+
+	if (ret < 0)
+		return ret;
+
+	ret = __media_device_get_topology(mdev, &ktopo);
+	if (ret < 0)
+		return ret;
+
+	ret = copy_to_user(utopo, &ktopo, sizeof(*utopo));
+
+	return ret;
+}
+
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
 			       unsigned long arg)
 {
@@ -264,6 +394,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
 		mutex_unlock(&dev->graph_mutex);
 		break;
 
+	case MEDIA_IOC_G_TOPOLOGY:
+		mutex_lock(&dev->graph_mutex);
+		ret = media_device_get_topology(dev,
+				(struct media_v2_topology __user *)arg);
+		mutex_unlock(&dev->graph_mutex);
+		break;
+
 	default:
 		ret = -ENOIOCTLCMD;
 	}

drivers/media/media-device.c static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, · line 455

Quoted 7 lines
drivers/media/media-device.c +1 -0
@@ -312,6 +449,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
 	case MEDIA_IOC_DEVICE_INFO:
 	case MEDIA_IOC_ENUM_ENTITIES:
 	case MEDIA_IOC_SETUP_LINK:
+	case MEDIA_IOC_G_TOPOLOGY:
 		return media_device_ioctl(filp, cmd, arg);
 
 	case MEDIA_IOC_ENUM_LINKS32:

Note that this will need compat32 code eventually. Should probably be added to the todo list in the cover letter.

Regards,

Hans

#243 lore raw

Re: [PATCH v8 49/55] [media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl

Em Mon, 31 Aug 2015 14:47:03 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 39 lines · Mauro Carvalho Chehab
Quoted 25 lines

Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation.

drivers/media/media-device.c +12 -0
index 5b2c9f7fcd45..a91e1ec076a6 100644
@@ -232,6 +232,136 @@ static long media_device_setup_link(struct media_device *mdev,
 	return ret;
 }
 
+static long __media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology *topo)
+{
+	struct media_entity *entity;
+	struct media_interface *intf;
+	struct media_pad *pad;
+	struct media_link *link;
+	struct media_v2_entity uentity;
+	struct media_v2_interface uintf;
+	struct media_v2_pad upad;
+	struct media_v2_link ulink;
+	int ret = 0, i;

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 256

Quoted 10 lines
drivers/media/media-device.c +10 -0
+
+	topo->topology_version = mdev->topology_version;
+
+	/* Get entities and number of entities */
+	i = 0;
+	media_device_for_each_entity(entity, mdev) {
+		i++;
+
+		if (ret || !topo->entities)
+			continue;

I would add:

Quoted 6 lines
		if (i > topo->num_entities)
			continue;

The copy_to_user can succeed, even if i > num_entities depending on how the memory was allocated. So I would always check num_entities and refuse to go beyond it.

I think that the best is:

	if (i > topo->num_entities) {
		ret = -ENOSPC;
		continue;
	}
Quoted 13 lines

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 265

Quoted 10 lines
drivers/media/media-device.c +9 -0
+
+		/* Copy fields to userspace struct if not error */
+		memset(&uentity, 0, sizeof(uentity));
+		uentity.id = entity->graph_obj.id;
+		strncpy(uentity.name, entity->name,
+			sizeof(uentity.name));
+
+		if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity)))
+			ret = -EFAULT;

I would just return here. If the user gives bogus values for this, then just give up.

With the above change, yes, we can just return -EFAULT here.

Quoted 10 lines

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 267

Quoted 3 lines
drivers/media/media-device.c +2 -0
+	}
+	topo->num_entities = i;

What to do if topo->entities != NULL and i > topo->num_entities? Just return 0 or return ENOSPC? I'm in favor of ENOSPC since a partial topology result is useless. But if ENOSPC is returned, then all num_foo values should be updated with the current number of elements.

This behavior would be consistent with e.g. VIDIOC_G_EXT_CTRLS.

Ok. See above.

Quoted 121 lines
Quoted 121 lines
drivers/media/media-device.c +105 -0
+
+	/* Get interfaces and number of interfaces */
+	i = 0;
+	media_device_for_each_intf(intf, mdev) {
+		i++;
+
+		if (ret || !topo->interfaces)
+			continue;
+
+		memset(&uintf, 0, sizeof(uintf));
+
+		/* Copy intf fields to userspace struct */
+		uintf.id = intf->graph_obj.id;
+		uintf.intf_type = intf->type;
+		uintf.flags = intf->flags;
+
+		if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
+			struct media_intf_devnode *devnode;
+
+			devnode = intf_to_devnode(intf);
+
+			uintf.devnode.major = devnode->major;
+			uintf.devnode.minor = devnode->minor;
+		}
+
+		if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf)))
+			ret = -EFAULT;
+	}
+	topo->num_interfaces = i;
+
+	/* Get pads and number of pads */
+	i = 0;
+	media_device_for_each_pad(pad, mdev) {
+		i++;
+
+		if (ret || !topo->pads)
+			continue;
+
+		memset(&upad, 0, sizeof(upad));
+
+		/* Copy pad fields to userspace struct */
+		upad.id = pad->graph_obj.id;
+		upad.entity_id = pad->entity->graph_obj.id;
+		upad.flags = pad->flags;
+
+		if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad)))
+			ret = -EFAULT;
+	}
+	topo->num_pads = i;
+
+	/* Get links and number of links */
+	i = 0;
+	media_device_for_each_link(link, mdev) {
+		i++;
+
+		if (ret || !topo->links)
+			continue;
+
+		memset(&ulink, 0, sizeof(ulink));
+
+		/* Copy link fields to userspace struct */
+		ulink.id = link->graph_obj.id;
+		ulink.source_id = link->gobj0->id;
+		ulink.sink_id = link->gobj1->id;
+		ulink.flags = link->flags;
+
+		if (media_type(link->gobj0) != MEDIA_GRAPH_PAD)
+			ulink.flags |= MEDIA_NEW_LNK_FL_INTERFACE_LINK;
+
+		if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink)))
+			ret = -EFAULT;
+	}
+	topo->num_links = i;
+
+	return ret;
+}
+
+static long media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology __user *utopo)
+{
+	struct media_v2_topology ktopo;
+	int ret;
+
+	ret = copy_from_user(&ktopo, utopo, sizeof(ktopo));
+
+	if (ret < 0)
+		return ret;
+
+	ret = __media_device_get_topology(mdev, &ktopo);
+	if (ret < 0)
+		return ret;
+
+	ret = copy_to_user(utopo, &ktopo, sizeof(*utopo));
+
+	return ret;
+}
+
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
 			       unsigned long arg)
 {
@@ -264,6 +394,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
 		mutex_unlock(&dev->graph_mutex);
 		break;
 
+	case MEDIA_IOC_G_TOPOLOGY:
+		mutex_lock(&dev->graph_mutex);
+		ret = media_device_get_topology(dev,
+				(struct media_v2_topology __user *)arg);
+		mutex_unlock(&dev->graph_mutex);
+		break;
+
 	default:
 		ret = -ENOIOCTLCMD;
 	}
@@ -312,6 +449,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
 	case MEDIA_IOC_DEVICE_INFO:
 	case MEDIA_IOC_ENUM_ENTITIES:
 	case MEDIA_IOC_SETUP_LINK:
+	case MEDIA_IOC_G_TOPOLOGY:
 		return media_device_ioctl(filp, cmd, arg);
 
Quoted 5 lines

drivers/media/media-device.c static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, · line 455

Quoted 2 lines
drivers/media/media-device.c +0 -0
 	case MEDIA_IOC_ENUM_LINKS32:

Note that this will need compat32 code eventually. Should probably be added to the todo list in the cover letter.

Ok.

Quoted 8 lines

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#244 lore raw

Re: [PATCH v8 49/55] [media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl

Quoted 49 lines · Mauro Carvalho Chehab

Em Mon, 31 Aug 2015 14:47:03 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 39 lines · Mauro Carvalho Chehab
Quoted 25 lines

Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation.

drivers/media/media-device.c +12 -0
index 5b2c9f7fcd45..a91e1ec076a6 100644
@@ -232,6 +232,136 @@ static long media_device_setup_link(struct media_device *mdev,
 	return ret;
 }
 
+static long __media_device_get_topology(struct media_device *mdev,
+				      struct media_v2_topology *topo)
+{
+	struct media_entity *entity;
+	struct media_interface *intf;
+	struct media_pad *pad;
+	struct media_link *link;
+	struct media_v2_entity uentity;
+	struct media_v2_interface uintf;
+	struct media_v2_pad upad;
+	struct media_v2_link ulink;
+	int ret = 0, i;

drivers/media/media-device.c static long media_device_setup_link(struct media_device *mdev, · line 256

Quoted 10 lines
drivers/media/media-device.c +10 -0
+
+	topo->topology_version = mdev->topology_version;
+
+	/* Get entities and number of entities */
+	i = 0;
+	media_device_for_each_entity(entity, mdev) {
+		i++;
+
+		if (ret || !topo->entities)
+			continue;

I would add:

Quoted 6 lines
		if (i > topo->num_entities)
			continue;

The copy_to_user can succeed, even if i > num_entities depending on how the memory was allocated. So I would always check num_entities and refuse to go beyond it.

Quoted 6 lines

I think that the best is:

	if (i > topo->num_entities) {
		ret = -ENOSPC;
		continue;
	}

Agreed.

Regards,

Hans

#245 lore raw

PATCH v8 50/55 media-entity: unregister entity links

In reply to Mauro Carvalho Chehab

Add functions to explicitly unregister all entity links. This function is called automatically when an entity link is destroyed.

drivers/media/media-entity.c +23 -0
index c18f4af52771..96303a0ade59 100644
@@ -903,6 +903,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create);
 
 void media_devnode_remove(struct media_intf_devnode *devnode)
 {
+	media_remove_intf_links(&devnode->intf);
 	media_gobj_remove(&devnode->intf.graph_obj);
 	kfree(devnode);
 }
@@ -944,3 +945,25 @@ void media_remove_intf_link(struct media_link *link)
 	mutex_unlock(&link->graph_obj.mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_remove_intf_link);
+
+void __media_remove_intf_links(struct media_interface *intf)
+{
+	struct media_link *link, *tmp;
+
+	list_for_each_entry_safe(link, tmp, &intf->links, list)
+		__media_remove_intf_link(link);
+
+}
+EXPORT_SYMBOL_GPL(__media_remove_intf_links);
+
+void media_remove_intf_links(struct media_interface *intf)
+{
+	/* Do nothing if the intf is not registered. */
+	if (intf->graph_obj.mdev == NULL)
+		return;
+
+	mutex_lock(&intf->graph_obj.mdev->graph_mutex);
+	__media_remove_intf_links(intf);
+	mutex_unlock(&intf->graph_obj.mdev->graph_mutex);
+}
+EXPORT_SYMBOL_GPL(media_remove_intf_links);
include/media/media-entity.h +3 -0
index 8c344a07636c..0e7e193a6736 100644
@@ -318,6 +318,9 @@ struct media_link *media_create_intf_link(struct media_entity *entity,
 					    struct media_interface *intf,
 					    u32 flags);
 void media_remove_intf_link(struct media_link *link);
+void __media_remove_intf_links(struct media_interface *intf);
+void media_remove_intf_links(struct media_interface *intf);
+
 
 #define media_entity_call(entity, operation, args...)			\
 	(((entity)->ops && (entity)->ops->operation) ?			\
Signature · 1 line
2.4.3
Acked-by on v8 50/55
#246 lore raw

Re: [PATCH v8 50/55] [media] media-entity: unregister entity links

Quoted 5 lines · Mauro Carvalho Chehab

Add functions to explicitly unregister all entity links. This function is called automatically when an entity link is destroyed.

Quoted 54 lines
drivers/media/media-entity.c +23 -0
index c18f4af52771..96303a0ade59 100644
@@ -903,6 +903,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create);
 
 void media_devnode_remove(struct media_intf_devnode *devnode)
 {
+	media_remove_intf_links(&devnode->intf);
 	media_gobj_remove(&devnode->intf.graph_obj);
 	kfree(devnode);
 }
@@ -944,3 +945,25 @@ void media_remove_intf_link(struct media_link *link)
 	mutex_unlock(&link->graph_obj.mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_remove_intf_link);
+
+void __media_remove_intf_links(struct media_interface *intf)
+{
+	struct media_link *link, *tmp;
+
+	list_for_each_entry_safe(link, tmp, &intf->links, list)
+		__media_remove_intf_link(link);
+
+}
+EXPORT_SYMBOL_GPL(__media_remove_intf_links);
+
+void media_remove_intf_links(struct media_interface *intf)
+{
+	/* Do nothing if the intf is not registered. */
+	if (intf->graph_obj.mdev == NULL)
+		return;
+
+	mutex_lock(&intf->graph_obj.mdev->graph_mutex);
+	__media_remove_intf_links(intf);
+	mutex_unlock(&intf->graph_obj.mdev->graph_mutex);
+}
+EXPORT_SYMBOL_GPL(media_remove_intf_links);
include/media/media-entity.h +3 -0
index 8c344a07636c..0e7e193a6736 100644
@@ -318,6 +318,9 @@ struct media_link *media_create_intf_link(struct media_entity *entity,
 					    struct media_interface *intf,
 					    u32 flags);
 void media_remove_intf_link(struct media_link *link);
+void __media_remove_intf_links(struct media_interface *intf);
+void media_remove_intf_links(struct media_interface *intf);
+
 
 #define media_entity_call(entity, operation, args...)			\
 	(((entity)->ops && (entity)->ops->operation) ?			\
#247 lore raw

PATCH v8 51/55 remove interface links at media_entity_unregister()

In reply to Mauro Carvalho Chehab

Interface links connected to an entity should be removed before being able of removing the entity.

drivers/media/media-device.c +16 -0
index a91e1ec076a6..638c682b79c4 100644
@@ -618,14 +618,30 @@ void media_device_unregister_entity(struct media_entity *entity)
 		return;
 
 	spin_lock(&mdev->lock);
+
+	/* Remove interface links with this entity on it */
+	list_for_each_entry_safe(link, tmp, &mdev->links, graph_obj.list) {
+		if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY
+		    && link->entity == entity) {
+			media_gobj_remove(&link->graph_obj);
+			kfree(link);
+		}
+	}
+
+	/* Remove all data links that belong to this entity */
 	list_for_each_entry_safe(link, tmp, &entity->links, list) {
 		media_gobj_remove(&link->graph_obj);
 		list_del(&link->list);
 		kfree(link);
 	}
+
+	/* Remove all pads that belong to this entity */
 	for (i = 0; i < entity->num_pads; i++)
 		media_gobj_remove(&entity->pads[i].graph_obj);
+
+	/* Remove the entity */
 	media_gobj_remove(&entity->graph_obj);
+
 	spin_unlock(&mdev->lock);
 	entity->graph_obj.mdev = NULL;
 }
Signature · 1 line
2.4.3
#248 lore raw

Re: [PATCH v8 51/55] [media] remove interface links at media_entity_unregister()

Quoted 10 lines · Mauro Carvalho Chehab

Interface links connected to an entity should be removed before being able of removing the entity.

drivers/media/media-device.c +0 -0
index a91e1ec076a6..638c682b79c4 100644

drivers/media/media-device.c void media_device_unregister_entity(struct media_entity *entity) · line 625

Quoted 8 lines
drivers/media/media-device.c +5 -0
@@ -618,14 +618,30 @@ void media_device_unregister_entity(struct media_entity *entity)
 		return;
 
 	spin_lock(&mdev->lock);
+
+	/* Remove interface links with this entity on it */
+	list_for_each_entry_safe(link, tmp, &mdev->links, graph_obj.list) {
+		if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY
+		    && link->entity == entity) {

I don't think you need the == MEDIA_GRAPH_ENTITY check here. That should always be true if link->entity == entity.

Quoted 13 lines
drivers/media/media-device.c +7 -0
+			media_gobj_remove(&link->graph_obj);
+			kfree(link);
+		}
+	}
+
+	/* Remove all data links that belong to this entity */
 	list_for_each_entry_safe(link, tmp, &entity->links, list) {
 		media_gobj_remove(&link->graph_obj);
 		list_del(&link->list);
 		kfree(link);
 	}
+

drivers/media/media-device.c void media_device_unregister_entity(struct media_entity *entity) · line 647

Quoted 10 lines
drivers/media/media-device.c +4 -0
+	/* Remove all pads that belong to this entity */
 	for (i = 0; i < entity->num_pads; i++)
 		media_gobj_remove(&entity->pads[i].graph_obj);
+
+	/* Remove the entity */
 	media_gobj_remove(&entity->graph_obj);
+
 	spin_unlock(&mdev->lock);
 	entity->graph_obj.mdev = NULL;
 }

Regards,

Hans

#249 lore raw

Re: [PATCH v8 51/55] [media] remove interface links at media_entity_unregister()

Em Mon, 31 Aug 2015 14:53:45 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 13 lines · Mauro Carvalho Chehab
Quoted 12 lines

Interface links connected to an entity should be removed before being able of removing the entity.

drivers/media/media-device.c +0 -0
index a91e1ec076a6..638c682b79c4 100644
@@ -618,14 +618,30 @@ void media_device_unregister_entity(struct media_entity *entity)
 		return;
 
Quoted 9 lines

drivers/media/media-device.c void media_device_unregister_entity(struct media_entity *entity) · line 625

Quoted 6 lines
drivers/media/media-device.c +5 -0
 	spin_lock(&mdev->lock);
+
+	/* Remove interface links with this entity on it */
+	list_for_each_entry_safe(link, tmp, &mdev->links, graph_obj.list) {
+		if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY
+		    && link->entity == entity) {

I don't think you need the == MEDIA_GRAPH_ENTITY check here. That should always be true if link->entity == entity.

Yes, I know. Actually, I coded it as just if (link->entity == entity). Latter, when reviewing my own patch, I decided to add the extra check, as it sounded me a little better.

Not sure really what would be the better.

Quoted 32 lines
Quoted 14 lines
drivers/media/media-device.c +7 -0
+			media_gobj_remove(&link->graph_obj);
+			kfree(link);
+		}
+	}
+
+	/* Remove all data links that belong to this entity */
 	list_for_each_entry_safe(link, tmp, &entity->links, list) {
 		media_gobj_remove(&link->graph_obj);
 		list_del(&link->list);
 		kfree(link);
 	}
+

drivers/media/media-device.c void media_device_unregister_entity(struct media_entity *entity) · line 647

Quoted 10 lines
drivers/media/media-device.c +4 -0
+	/* Remove all pads that belong to this entity */
 	for (i = 0; i < entity->num_pads; i++)
 		media_gobj_remove(&entity->pads[i].graph_obj);
+
+	/* Remove the entity */
 	media_gobj_remove(&entity->graph_obj);
+
 	spin_unlock(&mdev->lock);
 	entity->graph_obj.mdev = NULL;
 }

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#250 lore raw

PATCH v8 52/55 media-device: remove interfaces and interface links

In reply to Mauro Carvalho Chehab

Just like what's done with entities, when the media controller is unregistered, release and interface and interface links that might still be there.

drivers/media/media-device.c +16 -1
index 638c682b79c4..2c16a46ea530 100644
@@ -554,6 +554,22 @@ void media_device_unregister(struct media_device *mdev)
 {
 	struct media_entity *entity;
 	struct media_entity *next;
+	struct media_link *link, *tmp_link;
+	struct media_interface *intf, *tmp_intf;
+
+	/* Remove interface links from the media device */
+	list_for_each_entry_safe(link, tmp_link, &mdev->links,
+				 graph_obj.list) {
+		media_gobj_remove(&link->graph_obj);
+		kfree(link);
+	}
+
+	/* Remove all interfaces from the media device */
+	list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
+				 graph_obj.list) {
+		media_gobj_remove(&intf->graph_obj);
+		kfree(intf);
+	}
 
 	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
 		media_device_unregister_entity(entity);
@@ -631,7 +647,6 @@ void media_device_unregister_entity(struct media_entity *entity)
 	/* Remove all data links that belong to this entity */
 	list_for_each_entry_safe(link, tmp, &entity->links, list) {
 		media_gobj_remove(&link->graph_obj);
-		list_del(&link->list);
 		kfree(link);
 	}
 
drivers/media/media-entity.c +4 -0
index 96303a0ade59..1cdda9cb0512 100644
@@ -206,6 +206,10 @@ void media_gobj_remove(struct media_gobj *gobj)
 
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
+
+	/* Links have their own list - we need to drop them there too */
+	if (media_type(gobj) == MEDIA_GRAPH_LINK)
+		list_del(&gobj_to_link(gobj)->list);
 }
 
 /**
include/media/media-entity.h +9 -4
index 0e7e193a6736..7fd6265f0bcb 100644
@@ -153,7 +153,7 @@ struct media_entity {
 };
 
 /**
- * struct media_intf_devnode - Define a Kernel API interface
+ * struct media_interface - Define a Kernel API interface
  *
  * @graph_obj:		embedded graph object
  * @list:		Linked list used to find other interfaces that belong
@@ -163,6 +163,11 @@ struct media_entity {
  *			uapi/media/media.h header, e. g.
  *			MEDIA_INTF_T_*
  * @flags:		Interface flags as defined at uapi/media/media.h
+ *
+ * NOTE: As media_device_unregister() will free the address of the
+ *	 media_interface, this structure should be embedded as the first
+ *	 element of the derivated functions, in order for the address to be
+ *	 the same.
  */
 struct media_interface {
 	struct media_gobj		graph_obj;
@@ -179,11 +184,11 @@ struct media_interface {
  * @minor:	Minor number of a device node
  */
 struct media_intf_devnode {
-	struct media_interface		intf;
+	struct media_interface	intf; /* must be first field in struct */
 
 	/* Should match the fields at media_v2_intf_devnode */
-	u32				major;
-	u32				minor;
+	u32			major;
+	u32			minor;
 };
 
 static inline u32 media_entity_id(struct media_entity *entity)
Signature · 1 line
2.4.3
#251 lore raw

Re: [PATCH v8 52/55] [media] media-device: remove interfaces and interface links

Quoted 2 lines · Mauro Carvalho Chehab

Just like what's done with entities, when the media controller is unregistered, release and interface and interface links that

s/release and/release any/

Quoted 68 lines

might still be there.

drivers/media/media-device.c +16 -1
index 638c682b79c4..2c16a46ea530 100644
@@ -554,6 +554,22 @@ void media_device_unregister(struct media_device *mdev)
 {
 	struct media_entity *entity;
 	struct media_entity *next;
+	struct media_link *link, *tmp_link;
+	struct media_interface *intf, *tmp_intf;
+
+	/* Remove interface links from the media device */
+	list_for_each_entry_safe(link, tmp_link, &mdev->links,
+				 graph_obj.list) {
+		media_gobj_remove(&link->graph_obj);
+		kfree(link);
+	}
+
+	/* Remove all interfaces from the media device */
+	list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
+				 graph_obj.list) {
+		media_gobj_remove(&intf->graph_obj);
+		kfree(intf);
+	}
 
 	list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
 		media_device_unregister_entity(entity);
@@ -631,7 +647,6 @@ void media_device_unregister_entity(struct media_entity *entity)
 	/* Remove all data links that belong to this entity */
 	list_for_each_entry_safe(link, tmp, &entity->links, list) {
 		media_gobj_remove(&link->graph_obj);
-		list_del(&link->list);
 		kfree(link);
 	}
 
drivers/media/media-entity.c +4 -0
index 96303a0ade59..1cdda9cb0512 100644
@@ -206,6 +206,10 @@ void media_gobj_remove(struct media_gobj *gobj)
 
 	/* Remove the object from mdev list */
 	list_del(&gobj->list);
+
+	/* Links have their own list - we need to drop them there too */
+	if (media_type(gobj) == MEDIA_GRAPH_LINK)
+		list_del(&gobj_to_link(gobj)->list);
 }
 
 /**
include/media/media-entity.h +1 -1
index 0e7e193a6736..7fd6265f0bcb 100644
@@ -153,7 +153,7 @@ struct media_entity {
 };
 
 /**
- * struct media_intf_devnode - Define a Kernel API interface
+ * struct media_interface - Define a Kernel API interface
  *
  * @graph_obj:		embedded graph object
  * @list:		Linked list used to find other interfaces that belong

include/media/media-entity.h struct media_entity { · line 169

Quoted 7 lines
include/media/media-entity.h +4 -0
@@ -163,6 +163,11 @@ struct media_entity {
  *			uapi/media/media.h header, e. g.
  *			MEDIA_INTF_T_*
  * @flags:		Interface flags as defined at uapi/media/media.h
+ *
+ * NOTE: As media_device_unregister() will free the address of the
+ *	 media_interface, this structure should be embedded as the first
+ *	 element of the derivated functions, in order for the address to be

s/derivated/derived/

Quoted 20 lines
include/media/media-entity.h +4 -3
+ *	 the same.
  */
 struct media_interface {
 	struct media_gobj		graph_obj;
@@ -179,11 +184,11 @@ struct media_interface {
  * @minor:	Minor number of a device node
  */
 struct media_intf_devnode {
-	struct media_interface		intf;
+	struct media_interface	intf; /* must be first field in struct */
 
 	/* Should match the fields at media_v2_intf_devnode */
-	u32				major;
-	u32				minor;
+	u32			major;
+	u32			minor;
 };
 
 static inline u32 media_entity_id(struct media_entity *entity)
#252 lore raw

PATCH v8 53/55 v4l2-core: create MC interfaces for devnodes

In reply to Mauro Carvalho Chehab

V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.

Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.

drivers/media/v4l2-core/v4l2-dev.c +87 -18
index 44b330589787..427a5a32b3de 100644
@@ -194,9 +194,12 @@ static void v4l2_device_release(struct device *cd)
 	mutex_unlock(&videodev_lock);
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-	if (v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV)
-		media_device_unregister_entity(&vdev->entity);
+	if (v4l2_dev->mdev) {
+		/* Remove interfaces and interface links */
+		media_devnode_remove(vdev->intf_devnode);
+		if (vdev->vfl_type != VFL_TYPE_SUBDEV)
+			media_device_unregister_entity(&vdev->entity);
+	}
 #endif
 
 	/* Do not call v4l2_device_put if there is no release callback set.
@@ -713,6 +716,85 @@ static void determine_valid_ioctls(struct video_device *vdev)
 			BASE_VIDIOC_PRIVATE);
 }
 
+
+static int video_register_media_controller(struct video_device *vdev, int type)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	u32 entity_type = MEDIA_ENT_T_UNKNOWN;
+	u32 intf_type;
+	int ret;
+	bool create_entity = true;
+
+	if (!vdev->v4l2_dev->mdev)
+		return 0;
+
+	switch (type) {
+	case VFL_TYPE_GRABBER:
+		intf_type = MEDIA_INTF_T_V4L_VIDEO;
+		entity_type = MEDIA_ENT_T_V4L2_VIDEO;
+		break;
+	case VFL_TYPE_VBI:
+		intf_type = MEDIA_INTF_T_V4L_VBI;
+		entity_type = MEDIA_ENT_T_V4L2_VBI;
+		break;
+	case VFL_TYPE_SDR:
+		intf_type = MEDIA_INTF_T_V4L_SWRADIO;
+		entity_type = MEDIA_ENT_T_V4L2_SWRADIO;
+		break;
+	case VFL_TYPE_RADIO:
+		intf_type = MEDIA_INTF_T_V4L_RADIO;
+		/*
+		 * Radio doesn't have an entity at the V4L2 side to represent
+		 * radio input or output. Instead, the audio input/output goes
+		 * via either physical wires or ALSA.
+		 */
+		create_entity = false;
+		break;
+	case VFL_TYPE_SUBDEV:
+		intf_type = MEDIA_INTF_T_V4L_SUBDEV;
+		/* Entity will be created via v4l2_device_register_subdev() */
+		create_entity = false;
+		break;
+	default:
+		return 0;
+	}
+
+	if (create_entity) {
+		vdev->entity.type = entity_type;
+		vdev->entity.name = vdev->name;
+
+		/* Needed just for backward compatibility with legacy MC API */
+		vdev->entity.info.dev.major = VIDEO_MAJOR;
+		vdev->entity.info.dev.minor = vdev->minor;
+
+		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
+						   &vdev->entity);
+		if (ret < 0) {
+			printk(KERN_WARNING
+				"%s: media_device_register_entity failed\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev,
+						  intf_type,
+						  0, VIDEO_MAJOR,
+						  vdev->minor,
+						  GFP_KERNEL);
+	if (!vdev->intf_devnode)
+		return -ENOMEM;
+
+	if (create_entity)
+		media_create_intf_link(&vdev->entity,
+				       &vdev->intf_devnode->intf, 0);
+
+	/* FIXME: how to create the other interface links? */
+
+#endif
+	return 0;
+}
+
 /**
  *	__video_register_device - register video4linux devices
  *	@vdev: video device structure we want to register
@@ -908,22 +990,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
 	/* Increase v4l2_device refcount */
 	v4l2_device_get(vdev->v4l2_dev);
 
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	/* Part 5: Register the entity. */
-	if (vdev->v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
-		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
-		vdev->entity.name = vdev->name;
-		vdev->entity.info.dev.major = VIDEO_MAJOR;
-		vdev->entity.info.dev.minor = vdev->minor;
-		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
-			&vdev->entity);
-		if (ret < 0)
-			printk(KERN_WARNING
-			       "%s: media_device_register_entity failed\n",
-			       __func__);
-	}
-#endif
+	ret = video_register_media_controller(vdev, type);
+
 	/* Part 6: Activate this minor. The char device can now be used. */
 	set_bit(V4L2_FL_REGISTERED, &vdev->flags);
 
drivers/media/v4l2-core/v4l2-device.c +9 -1
index 5b0a30b9252b..17ec73b1796e 100644
@@ -249,6 +249,11 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
 #if defined(CONFIG_MEDIA_CONTROLLER)
 		sd->entity.info.dev.major = VIDEO_MAJOR;
 		sd->entity.info.dev.minor = vdev->minor;
+
+		/* Interface is created by __video_register_device() */
+		if (vdev->v4l2_dev->mdev)
+			media_create_intf_link(&sd->entity,
+					       &vdev->intf_devnode->intf, 0);
 #endif
 		sd->devnode = vdev;
 	}
@@ -285,7 +290,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	if (v4l2_dev->mdev) {
-		media_entity_remove_links(&sd->entity);
+		/*
+		 * No need to explicitly remove links, as both pads and
+		 * links are removed by the function below, at the right order
+		 */
 		media_device_unregister_entity(&sd->entity);
 	}
 #endif
include/media/v4l2-dev.h +1 -0
index acbcd2f5fe7f..eeabf20e87a6 100644
@@ -86,6 +86,7 @@ struct video_device
 {
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	struct media_entity entity;
+	struct media_intf_devnode *intf_devnode;
 #endif
 	/* device ops */
 	const struct v4l2_file_operations *fops;
Signature · 1 line
2.4.3
#253 lore raw

Re: [PATCH v8 53/55] [media] v4l2-core: create MC interfaces for devnodes

Quoted 6 lines · Mauro Carvalho Chehab

V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.

Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.

A general note: I think this patch (and any prerequisite patches) should come before the patches adding G_TOPOLOGY support.

What the G_TOPOLOGY ioctl returns only makes sense IMHO if this code is present as well, so it is a more logical order for this patch series.

In addition, since G_TOPOLOGY is a userspace API it is likely that that will create more discussions, whereas this is internal to the kernel and could be merged before G_TOPOLOGY.

Quoted 9 lines
drivers/media/v4l2-core/v4l2-dev.c +0 -0
index 44b330589787..427a5a32b3de 100644
@@ -194,9 +194,12 @@ static void v4l2_device_release(struct device *cd)
 	mutex_unlock(&videodev_lock);

drivers/media/v4l2-core/v4l2-dev.c static void v4l2_device_release(struct device *cd) · line 201

Quoted 10 lines
drivers/media/v4l2-core/v4l2-dev.c +5 -3
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-	if (v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV)
-		media_device_unregister_entity(&vdev->entity);
+	if (v4l2_dev->mdev) {
+		/* Remove interfaces and interface links */
+		media_devnode_remove(vdev->intf_devnode);
+		if (vdev->vfl_type != VFL_TYPE_SUBDEV)
+			media_device_unregister_entity(&vdev->entity);

RADIO doesn't have an entity either, so this should probably check for both SUBDEV and RADIO.

I think it is cleaner if video_register_media_controller() sets a new video_device
flag: V4L2_FL_CREATED_ENTITY, and if this release function would just check the flag.

Quoted 70 lines
drivers/media/v4l2-core/v4l2-dev.c +63 -0
+	}
 #endif
 
 	/* Do not call v4l2_device_put if there is no release callback set.
@@ -713,6 +716,85 @@ static void determine_valid_ioctls(struct video_device *vdev)
 			BASE_VIDIOC_PRIVATE);
 }
 
+
+static int video_register_media_controller(struct video_device *vdev, int type)
+{
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	u32 entity_type = MEDIA_ENT_T_UNKNOWN;
+	u32 intf_type;
+	int ret;
+	bool create_entity = true;
+
+	if (!vdev->v4l2_dev->mdev)
+		return 0;
+
+	switch (type) {
+	case VFL_TYPE_GRABBER:
+		intf_type = MEDIA_INTF_T_V4L_VIDEO;
+		entity_type = MEDIA_ENT_T_V4L2_VIDEO;
+		break;
+	case VFL_TYPE_VBI:
+		intf_type = MEDIA_INTF_T_V4L_VBI;
+		entity_type = MEDIA_ENT_T_V4L2_VBI;
+		break;
+	case VFL_TYPE_SDR:
+		intf_type = MEDIA_INTF_T_V4L_SWRADIO;
+		entity_type = MEDIA_ENT_T_V4L2_SWRADIO;
+		break;
+	case VFL_TYPE_RADIO:
+		intf_type = MEDIA_INTF_T_V4L_RADIO;
+		/*
+		 * Radio doesn't have an entity at the V4L2 side to represent
+		 * radio input or output. Instead, the audio input/output goes
+		 * via either physical wires or ALSA.
+		 */
+		create_entity = false;
+		break;
+	case VFL_TYPE_SUBDEV:
+		intf_type = MEDIA_INTF_T_V4L_SUBDEV;
+		/* Entity will be created via v4l2_device_register_subdev() */
+		create_entity = false;
+		break;
+	default:
+		return 0;
+	}
+
+	if (create_entity) {
+		vdev->entity.type = entity_type;
+		vdev->entity.name = vdev->name;
+
+		/* Needed just for backward compatibility with legacy MC API */
+		vdev->entity.info.dev.major = VIDEO_MAJOR;
+		vdev->entity.info.dev.minor = vdev->minor;
+
+		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
+						   &vdev->entity);
+		if (ret < 0) {
+			printk(KERN_WARNING
+				"%s: media_device_register_entity failed\n",
+				__func__);
+			return ret;
+		}
+	}
+
+	vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev,

drivers/media/v4l2-core/v4l2-dev.c static void determine_valid_ioctls(struct video_device *vdev) · line 790

Quoted 10 lines
drivers/media/v4l2-core/v4l2-dev.c +10 -0
+						  intf_type,
+						  0, VIDEO_MAJOR,
+						  vdev->minor,
+						  GFP_KERNEL);
+	if (!vdev->intf_devnode)
+		return -ENOMEM;
+
+	if (create_entity)
+		media_create_intf_link(&vdev->entity,
+				       &vdev->intf_devnode->intf, 0);

You need a NULL pointer check here as well. It might be a good idea to add __must_check to the media_create_intf_link() prototype. I think there are more places where this isn't checked.

Quoted 52 lines
drivers/media/v4l2-core/v4l2-dev.c +9 -15
+
+	/* FIXME: how to create the other interface links? */
+
+#endif
+	return 0;
+}
+
 /**
  *	__video_register_device - register video4linux devices
  *	@vdev: video device structure we want to register
@@ -908,22 +990,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
 	/* Increase v4l2_device refcount */
 	v4l2_device_get(vdev->v4l2_dev);
 
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	/* Part 5: Register the entity. */
-	if (vdev->v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
-		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
-		vdev->entity.name = vdev->name;
-		vdev->entity.info.dev.major = VIDEO_MAJOR;
-		vdev->entity.info.dev.minor = vdev->minor;
-		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
-			&vdev->entity);
-		if (ret < 0)
-			printk(KERN_WARNING
-			       "%s: media_device_register_entity failed\n",
-			       __func__);
-	}
-#endif
+	ret = video_register_media_controller(vdev, type);
+
 	/* Part 6: Activate this minor. The char device can now be used. */
 	set_bit(V4L2_FL_REGISTERED, &vdev->flags);
 
drivers/media/v4l2-core/v4l2-device.c +5 -0
index 5b0a30b9252b..17ec73b1796e 100644
@@ -249,6 +249,11 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
 #if defined(CONFIG_MEDIA_CONTROLLER)
 		sd->entity.info.dev.major = VIDEO_MAJOR;
 		sd->entity.info.dev.minor = vdev->minor;
+
+		/* Interface is created by __video_register_device() */
+		if (vdev->v4l2_dev->mdev)
+			media_create_intf_link(&sd->entity,
+					       &vdev->intf_devnode->intf, 0);
 #endif
 		sd->devnode = vdev;
 	}

drivers/media/v4l2-core/v4l2-device.c void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) · line 295

Quoted 7 lines
drivers/media/v4l2-core/v4l2-device.c +3 -1
@@ -285,7 +290,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	if (v4l2_dev->mdev) {
-		media_entity_remove_links(&sd->entity);
+		/*
+		 * No need to explicitly remove links, as both pads and
+		 * links are removed by the function below, at the right order

s/, at/ in/

Quoted 10 lines
drivers/media/v4l2-core/v4l2-device.c +1 -0
+		 */
 		media_device_unregister_entity(&sd->entity);
 	}
 #endif
include/media/v4l2-dev.h +0 -0
index acbcd2f5fe7f..eeabf20e87a6 100644

include/media/v4l2-dev.h struct video_device · line 92

Quoted 7 lines
include/media/v4l2-dev.h +1 -0
@@ -86,6 +86,7 @@ struct video_device
 {
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	struct media_entity entity;
+	struct media_intf_devnode *intf_devnode;
 #endif
 	/* device ops */
 	const struct v4l2_file_operations *fops;

Regards,

Hans

#254 lore raw

Re: [PATCH v8 53/55] [media] v4l2-core: create MC interfaces for devnodes

Em Mon, 31 Aug 2015 15:23:59 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 41 lines · Mauro Carvalho Chehab
Quoted 6 lines

V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.

Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.

A general note: I think this patch (and any prerequisite patches) should come before the patches adding G_TOPOLOGY support.

What the G_TOPOLOGY ioctl returns only makes sense IMHO if this code is present as well, so it is a more logical order for this patch series.

In addition, since G_TOPOLOGY is a userspace API it is likely that that will create more discussions, whereas this is internal to the kernel and could be merged before G_TOPOLOGY.

Quoted 9 lines
drivers/media/v4l2-core/v4l2-dev.c +0 -0
index 44b330589787..427a5a32b3de 100644
@@ -194,9 +194,12 @@ static void v4l2_device_release(struct device *cd)
 	mutex_unlock(&videodev_lock);

drivers/media/v4l2-core/v4l2-dev.c static void v4l2_device_release(struct device *cd) · line 201

Quoted 10 lines
drivers/media/v4l2-core/v4l2-dev.c +5 -3
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-	if (v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV)
-		media_device_unregister_entity(&vdev->entity);
+	if (v4l2_dev->mdev) {
+		/* Remove interfaces and interface links */
+		media_devnode_remove(vdev->intf_devnode);
+		if (vdev->vfl_type != VFL_TYPE_SUBDEV)
+			media_device_unregister_entity(&vdev->entity);

RADIO doesn't have an entity either, so this should probably check for both SUBDEV and RADIO.

Quoted 3 lines

I think it is cleaner if video_register_media_controller() sets a new video_device
flag: V4L2_FL_CREATED_ENTITY, and if this release function would just check the flag.

I don't see the need for a new flag here. I guess this should do the job:

drivers/media/v4l2-core/v4l2-dev.c +3 -1
index 427a5a32b3de..298aaf6f4296 100644
@@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd)
 	if (v4l2_dev->mdev) {
 		/* Remove interfaces and interface links */
 		media_devnode_remove(vdev->intf_devnode);
-		if (vdev->vfl_type != VFL_TYPE_SUBDEV)
+		if (vdev->entity.type)
 			media_device_unregister_entity(&vdev->entity);
 	}
 #endif
@@ -775,6 +775,8 @@ static int video_register_media_controller(struct video_device *vdev, int type)
 				__func__);
 			return ret;
 		}
+	} else {
+		vdev->entity.type = 0;
 	}
 
 	vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev,

Regards,
Mauro

#255 lore raw

PATCH v8 54/55 au0828: unregister MC at the end

In reply to Mauro Carvalho Chehab

au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop the media interfaces.

We can't release the media controller before that, or an OOPS will occur:

[  176.938752] usb 1-4.4: Media device released
[  176.938753] usb 1-4.4: Media device unregistered
[  177.091235] general protection fault: 0000 [#1] SMP
[  177.091253] Modules linked in: ir_lirc_codec ir_xmp_decoder lirc_dev ir_mce_kbd_decoder ir_sharp_decoder ir_sanyo_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_nec_decoder ir_rc5_decoder au8522_dig xc5000 tuner au8522_decoder au8522_common au0828(-) videobuf2_vmalloc videobuf2_memops tveeprom videobuf2_core dvb_core rc_core v4l2_common videodev media cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats parport_pc ppdev lp parport snd_hda_codec_hdmi i915 x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi coretemp kvm_intel kvm btusb crct10dif_pclmul snd_hda_codec_realtek crc32_pclmul btrtl crc32c_intel btbcm snd_hda_codec_generic ghash_clmulni_intel btintel i2c_algo_bit drm_kms_helper bluetooth iTCO_wdt snd_usb_audio snd_hda_intel iTCO_vendor_support jitterentropy_rng
[  177.091455]  snd_hda_codec evdev sha256_ssse3 drm sha256_generic hmac snd_usbmidi_lib snd_hwdep snd_hda_core snd_rawmidi drbg snd_seq_device snd_pcm aesni_intel aes_x86_64 lrw gf128mul mei_me glue_helper snd_timer ablk_helper cryptd mei rfkill snd psmouse sg shpchp soundcore lpc_ich serio_raw i2c_i801 pcspkr mfd_core tpm_tis tpm battery dw_dmac video i2c_designware_platform dw_dmac_core i2c_designware_core acpi_pad processor button ext4 crc16 mbcache jbd2 dm_mod sd_mod ahci libahci libata e1000e scsi_mod ptp pps_core ehci_pci xhci_pci ehci_hcd xhci_hcd thermal fan thermal_sys sdhci_acpi sdhci mmc_core i2c_hid hid [last unloaded: rc_core]
[  177.091632] CPU: 1 PID: 18040 Comm: rmmod Tainted: G        W       4.2.0-rc2+ #9
[  177.091648] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/NUC5i7RYB, BIOS RYBDWi35.86A.0246.2015.0309.1355 03/09/2015
[  177.091677] task: ffff88040811b080 ti: ffff880036b88000 task.ti: ffff880036b88000
[  177.091693] RIP: 0010:[<ffffffff810aecc3>]  [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180
[  177.091718] RSP: 0018:ffff880036b8bcd8  EFLAGS: 00010202
[  177.091730] RAX: 0000000000003ffe RBX: ffff880407e11b70 RCX: ffff88041ec962c0
[  177.091745] RDX: 7463656a62506357 RSI: 0000000000080000 RDI: ffff880407e11b74
[  177.091760] RBP: ffff880407e11b74 R08: 0000000000000001 R09: ffffffff812bf4e0
[  177.091776] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88040811b080
[  177.091791] R13: ffff88003601cec8 R14: ffff8804084b8890 R15: ffff8804084b8800
[  177.091807] FS:  00007f2f9bab1700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000
[  177.091824] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  177.091837] CR2: 00007fe8c0f900e0 CR3: 0000000035c47000 CR4: 00000000003407e0
[  177.091852] Stack:
[  177.091857]  ffffffff81562e3d ffffffff815613b3 0000000000000000 0000000000000000
[  177.091876]  ffff88040b6d3240 ffff8804084b8890 ffff880407e11b70 ffff88003601cd30
[  177.091895]  ffff88003601ce28 ffff88003601cec8 ffff8804084b8890 ffffffff8156148b
[  177.091914] Call Trace:
[  177.091923]  [<ffffffff81562e3d>] ? _raw_spin_lock+0x1d/0x20
[  177.091936]  [<ffffffff815613b3>] ? __mutex_lock_slowpath+0x43/0x100
[  177.091951]  [<ffffffff8156148b>] ? mutex_lock+0x1b/0x30
[  177.091965]  [<ffffffffa028480d>] ? media_remove_intf_links+0x1d/0x40 [media]
[  177.091981]  [<ffffffffa028483e>] ? media_devnode_remove+0xe/0x20 [media]
[  177.091997]  [<ffffffffa063d875>] ? v4l2_device_release+0x95/0x100 [videodev]
[  177.092014]  [<ffffffff813ca19d>] ? device_release+0x2d/0x90
[  177.092028]  [<ffffffff812be5e9>] ? kobject_release+0x79/0x1b0
[  177.092042]  [<ffffffffa07b19ea>] ? au0828_analog_unregister+0x2a/0x60 [au0828]
[  177.092059]  [<ffffffffa07ac10e>] ? au0828_usb_disconnect+0x9e/0xd0 [au0828]
[  177.092075]  [<ffffffff8140e609>] ? usb_unbind_interface+0x79/0x270
[  177.092090]  [<ffffffff813cf285>] ? __device_release_driver+0x95/0x130
[  177.092105]  [<ffffffff813cf41b>] ? driver_detach+0xab/0xb0
[  177.092120]  [<ffffffff813ce4c5>] ? bus_remove_driver+0x55/0xd0
[  177.092134]  [<ffffffff8140d951>] ? usb_deregister+0x71/0xc0
[  177.092148]  [<ffffffff810e438a>] ? SyS_delete_module+0x1aa/0x250
[  177.092163]  [<ffffffff81088ee9>] ? task_work_run+0x89/0xc0
[  177.092176]  [<ffffffff815631f2>] ? entry_SYSCALL_64_fastpath+0x16/0x75
[  177.092191] Code: 87 47 02 c1 e0 10 85 c0 74 38 48 89 c2 c1 e8 12 48 c1 ea 0c 83 e8 01 83 e2 30 48 98 48 81 c2 c0 62 01 00 48 03 14 c5 c0 62 90 81 <48> 89 0a 8b 41 08 85 c0 75 0d f3 90 8b 41 08 85 c0 74 f7 eb 02
[  177.092281] RIP  [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180
[  177.092299]  RSP <ffff880036b8bcd8>
[  177.097721] ---[ end trace b12d5a66f4c6f1c1 ]---
[  177.243899] lirc_dev: module unloaded
drivers/media/usb/au0828/au0828-core.c +2 -2
index 7f645bcb7463..e28cabe65934 100644
@@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 	*/
 	dev->dev_state = DEV_DISCONNECTED;
 
-	au0828_unregister_media_device(dev);
-
 	au0828_rc_unregister(dev);
 	/* Digital TV */
 	au0828_dvb_unregister(dev);
@@ -193,6 +191,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 		return;
 	}
 #endif
+	au0828_unregister_media_device(dev);
+
 	au0828_usb_release(dev);
 }
 
Signature · 1 line
2.4.3
#256 lore raw

Re: [PATCH v8 54/55] [media] au0828: unregister MC at the end

Quoted 6 lines · Mauro Carvalho Chehab

au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop the media interfaces.

We can't release the media controller before that, or an OOPS will occur:

So this patch should be moved to a place earlier in the patch series, right? To prevent bisects that hit this bug.

Regards,

Hans

Quoted 73 lines
[  176.938752] usb 1-4.4: Media device released
[  176.938753] usb 1-4.4: Media device unregistered
[  177.091235] general protection fault: 0000 [#1] SMP
[  177.091253] Modules linked in: ir_lirc_codec ir_xmp_decoder lirc_dev ir_mce_kbd_decoder ir_sharp_decoder ir_sanyo_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_nec_decoder ir_rc5_decoder au8522_dig xc5000 tuner au8522_decoder au8522_common au0828(-) videobuf2_vmalloc videobuf2_memops tveeprom videobuf2_core dvb_core rc_core v4l2_common videodev media cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats parport_pc ppdev lp parport snd_hda_codec_hdmi i915 x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi coretemp kvm_intel kvm btusb crct10dif_pclmul snd_hda_codec_realtek crc32_pclmul btrtl crc32c_intel btbcm snd_hda_codec_generic ghash_clmulni_intel btintel i2c_algo_bit drm_kms_helper bluetooth iTCO_wdt snd_usb_audio snd_hda_intel iTCO_vendor_support jitterentropy_rng
[  177.091455]  snd_hda_codec evdev sha256_ssse3 drm sha256_generic hmac snd_usbmidi_lib snd_hwdep snd_hda_core snd_rawmidi drbg snd_seq_device snd_pcm aesni_intel aes_x86_64 lrw gf128mul mei_me glue_helper snd_timer ablk_helper cryptd mei rfkill snd psmouse sg shpchp soundcore lpc_ich serio_raw i2c_i801 pcspkr mfd_core tpm_tis tpm battery dw_dmac video i2c_designware_platform dw_dmac_core i2c_designware_core acpi_pad processor button ext4 crc16 mbcache jbd2 dm_mod sd_mod ahci libahci libata e1000e scsi_mod ptp pps_core ehci_pci xhci_pci ehci_hcd xhci_hcd thermal fan thermal_sys sdhci_acpi sdhci mmc_core i2c_hid hid [last unloaded: rc_core]
[  177.091632] CPU: 1 PID: 18040 Comm: rmmod Tainted: G        W       4.2.0-rc2+ #9
[  177.091648] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/NUC5i7RYB, BIOS RYBDWi35.86A.0246.2015.0309.1355 03/09/2015
[  177.091677] task: ffff88040811b080 ti: ffff880036b88000 task.ti: ffff880036b88000
[  177.091693] RIP: 0010:[<ffffffff810aecc3>]  [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180
[  177.091718] RSP: 0018:ffff880036b8bcd8  EFLAGS: 00010202
[  177.091730] RAX: 0000000000003ffe RBX: ffff880407e11b70 RCX: ffff88041ec962c0
[  177.091745] RDX: 7463656a62506357 RSI: 0000000000080000 RDI: ffff880407e11b74
[  177.091760] RBP: ffff880407e11b74 R08: 0000000000000001 R09: ffffffff812bf4e0
[  177.091776] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88040811b080
[  177.091791] R13: ffff88003601cec8 R14: ffff8804084b8890 R15: ffff8804084b8800
[  177.091807] FS:  00007f2f9bab1700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000
[  177.091824] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  177.091837] CR2: 00007fe8c0f900e0 CR3: 0000000035c47000 CR4: 00000000003407e0
[  177.091852] Stack:
[  177.091857]  ffffffff81562e3d ffffffff815613b3 0000000000000000 0000000000000000
[  177.091876]  ffff88040b6d3240 ffff8804084b8890 ffff880407e11b70 ffff88003601cd30
[  177.091895]  ffff88003601ce28 ffff88003601cec8 ffff8804084b8890 ffffffff8156148b
[  177.091914] Call Trace:
[  177.091923]  [<ffffffff81562e3d>] ? _raw_spin_lock+0x1d/0x20
[  177.091936]  [<ffffffff815613b3>] ? __mutex_lock_slowpath+0x43/0x100
[  177.091951]  [<ffffffff8156148b>] ? mutex_lock+0x1b/0x30
[  177.091965]  [<ffffffffa028480d>] ? media_remove_intf_links+0x1d/0x40 [media]
[  177.091981]  [<ffffffffa028483e>] ? media_devnode_remove+0xe/0x20 [media]
[  177.091997]  [<ffffffffa063d875>] ? v4l2_device_release+0x95/0x100 [videodev]
[  177.092014]  [<ffffffff813ca19d>] ? device_release+0x2d/0x90
[  177.092028]  [<ffffffff812be5e9>] ? kobject_release+0x79/0x1b0
[  177.092042]  [<ffffffffa07b19ea>] ? au0828_analog_unregister+0x2a/0x60 [au0828]
[  177.092059]  [<ffffffffa07ac10e>] ? au0828_usb_disconnect+0x9e/0xd0 [au0828]
[  177.092075]  [<ffffffff8140e609>] ? usb_unbind_interface+0x79/0x270
[  177.092090]  [<ffffffff813cf285>] ? __device_release_driver+0x95/0x130
[  177.092105]  [<ffffffff813cf41b>] ? driver_detach+0xab/0xb0
[  177.092120]  [<ffffffff813ce4c5>] ? bus_remove_driver+0x55/0xd0
[  177.092134]  [<ffffffff8140d951>] ? usb_deregister+0x71/0xc0
[  177.092148]  [<ffffffff810e438a>] ? SyS_delete_module+0x1aa/0x250
[  177.092163]  [<ffffffff81088ee9>] ? task_work_run+0x89/0xc0
[  177.092176]  [<ffffffff815631f2>] ? entry_SYSCALL_64_fastpath+0x16/0x75
[  177.092191] Code: 87 47 02 c1 e0 10 85 c0 74 38 48 89 c2 c1 e8 12 48 c1 ea 0c 83 e8 01 83 e2 30 48 98 48 81 c2 c0 62 01 00 48 03 14 c5 c0 62 90 81 <48> 89 0a 8b 41 08 85 c0 75 0d f3 90 8b 41 08 85 c0 74 f7 eb 02
[  177.092281] RIP  [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180
[  177.092299]  RSP <ffff880036b8bcd8>
[  177.097721] ---[ end trace b12d5a66f4c6f1c1 ]---
[  177.243899] lirc_dev: module unloaded
drivers/media/usb/au0828/au0828-core.c +2 -2
index 7f645bcb7463..e28cabe65934 100644
@@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 	*/
 	dev->dev_state = DEV_DISCONNECTED;
 
-	au0828_unregister_media_device(dev);
-
 	au0828_rc_unregister(dev);
 	/* Digital TV */
 	au0828_dvb_unregister(dev);
@@ -193,6 +191,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
 		return;
 	}
 #endif
+	au0828_unregister_media_device(dev);
+
 	au0828_usb_release(dev);
 }
 
#257 lore raw

Re: [PATCH v8 54/55] [media] au0828: unregister MC at the end

Em Mon, 31 Aug 2015 15:25:39 +0200
Hans Verkuil <[email protected]> escreveu:

Quoted 10 lines · Mauro Carvalho Chehab
Quoted 6 lines

au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop the media interfaces.

We can't release the media controller before that, or an OOPS will occur:

So this patch should be moved to a place earlier in the patch series, right? To prevent bisects that hit this bug.

Yes, it should be before the previous patch.

Regards,
Mauro

#258 lore raw

PATCH v8 55/55 media-entity.h: document all the structs

In reply to Mauro Carvalho Chehab

Only a few structs are documented on kernel-doc-nano format (the ones added by the MC next gen patches).

Add a documentation for all structs, and ensure that they'll be producing the documentation at the Kernel's device driver DocBook.

include/media/media-entity.h +82 -28
index 7fd6265f0bcb..c42d191fa5a8 100644
@@ -55,11 +55,13 @@ enum media_gobj_type {
 /**
  * struct media_gobj - Define a graph object.
  *
+ * @mdev:	Pointer to the struct media_device that owns the object
  * @id:		Non-zero object ID identifier. The ID should be unique
  *		inside a media_device, as it is composed by
  *		MEDIA_BITS_PER_TYPE to store the type plus
  *		MEDIA_BITS_PER_LOCAL_ID	to store a per-type ID
  *		(called as "local ID").
+ * @list:	Linked list associated to one of the per-type mdev object lists
  *
  * All objects on the media graph should have this struct embedded
  */
@@ -73,6 +75,28 @@ struct media_gobj {
 struct media_pipeline {
 };
 
+/**
+ * struct media_link - Define a media link graph object.
+ *
+ * @graph_obj:	Embedded structure containing the media object common data
+ * @list:	Linked list associated with an entity or an interface that
+ *		owns the link.
+ * @gobj0:	Part of an union. Used to get the pointer for the first
+ *		graph_object of the link.
+ * @source:	Part of an union. Used only if the first object (gobj0) is
+ *		a pad. On such case, it represents the source pad.
+ * @intf:	Part of an union. Used only if the first object (gobj0) is
+ *		an interface.
+ * @gobj1:	Part of an union. Used to get the pointer for the second
+ *		graph_object of the link.
+ * @source:	Part of an union. Used only if the second object (gobj0) is
+ *		a pad. On such case, it represents the sink pad.
+ * @entity:	Part of an union. Used only if the second object (gobj0) is
+ *		an entity.
+ * @reverse:	Pointer to the link for the reverse direction of a pad to pad
+ *		link.
+ * @flags:	Link flags, as defined at uapi/media.h (MEDIA_LNK_FL_*)
+ */
 struct media_link {
 	struct media_gobj graph_obj;
 	struct list_head list;
@@ -86,15 +110,23 @@ struct media_link {
 		struct media_pad *sink;
 		struct media_entity *entity;
 	};
-	struct media_link *reverse;	/* Link in the reverse direction */
-	unsigned long flags;		/* Link flags (MEDIA_LNK_FL_*) */
+	struct media_link *reverse;
+	unsigned long flags;
 };
 
+/**
+ * struct media_pad - Define a media pad graph object.
+ *
+ * @graph_obj:	Embedded structure containing the media object common data
+ * @entity:	Entity where this object belongs
+ * @index:	Pad index in the entity pads array, numbered from 0 to n
+ * @flags:	Pad flags, as defined at uapi/media.h (MEDIA_PAD_FL_*)
+ */
 struct media_pad {
 	struct media_gobj graph_obj;	/* must be first field in struct */
-	struct media_entity *entity;	/* Entity this pad belongs to */
-	u16 index;			/* Pad index in the entity pads array */
-	unsigned long flags;		/* Pad flags (MEDIA_PAD_FL_*) */
+	struct media_entity *entity;
+	u16 index;
+	unsigned long flags;
 };
 
 /**
@@ -113,51 +145,73 @@ struct media_entity_operations {
 	int (*link_validate)(struct media_link *link);
 };
 
+/**
+ * struct media_entity - Define a media entity graph object.
+ *
+ * @graph_obj:	Embedded structure containing the media object common data.
+ * @name:	Entity name.
+ * @type:	Entity type, as defined at uapi/media.h (MEDIA_ENT_T_*)
+ * @revision:	Entity revision - OBSOLETE - should be removed soon.
+ * @flags:	Entity flags, as defined at uapi/media.h (MEDIA_ENT_FL_*)
+ * @group_id:	Entity group ID - OBSOLETE - should be removed soon.
+ * @num_pads:	Number of sink and source pads.
+ * @num_links:	Number of existing links, both enabled and disabled.
+ * @num_backlinks: Number of backlinks
+ * @pads:	Pads array with the size defined by @num_pads.
+ * @links:	Linked list for the data links.
+ * @ops:	Entity operations.
+ * @stream_count: Stream count for the entity.
+ * @use_count:	Use count for the entity.
+ * @pipe:	Pipeline this entity belongs to.
+ * @info:	Union with devnode information.  Kept just for backward
+ * 		compatibility.
+ * @major:	Devnode major number (zero if not applicable). Kept just
+ * 		for backward compatibility.
+ * @minor:	Devnode minor number (zero if not applicable). Kept just
+ * 		for backward compatibility.
+ *
+ * NOTE: @stream_count and @use_count reference counts must never be
+ * negative, but are signed integers on purpose: a simple WARN_ON(<0) check
+ * can be used to detect reference count bugs that would make them negative.
+ */
 struct media_entity {
 	struct media_gobj graph_obj;	/* must be first field in struct */
-	const char *name;		/* Entity name */
-	u32 type;			/* Entity type (MEDIA_ENT_T_*) */
-	u32 revision;			/* Entity revision, driver specific */
-	unsigned long flags;		/* Entity flags (MEDIA_ENT_FL_*) */
-	u32 group_id;			/* Entity group ID */
+	const char *name;
+	u32 type;
+	u32 revision;
+	unsigned long flags;
+	u32 group_id;
 
-	u16 num_pads;			/* Number of sink and source pads */
-	u16 num_links;			/* Number of existing links, both
-					 * enabled and disabled */
-	u16 num_backlinks;		/* Number of backlinks */
+	u16 num_pads;
+	u16 num_links;
+	u16 num_backlinks;
 
-	struct media_pad *pads;		/* Pads array (num_pads objects) */
-	struct list_head links;		/* Pad-to-pad links list */
+	struct media_pad *pads;
+	struct list_head links;
 
-	const struct media_entity_operations *ops;	/* Entity operations */
+	const struct media_entity_operations *ops;
 
 	/* Reference counts must never be negative, but are signed integers on
 	 * purpose: a simple WARN_ON(<0) check can be used to detect reference
 	 * count bugs that would make them negative.
 	 */
-	int stream_count;		/* Stream count for the entity. */
-	int use_count;			/* Use count for the entity. */
+	int stream_count;
+	int use_count;
 
-	struct media_pipeline *pipe;	/* Pipeline this entity belongs to. */
+	struct media_pipeline *pipe;
 
 	union {
-		/* Node specifications */
 		struct {
 			u32 major;
 			u32 minor;
 		} dev;
-
-		/* Sub-device specifications */
-		/* Nothing needed yet */
 	} info;
 };
 
 /**
- * struct media_interface - Define a Kernel API interface
+ * struct media_interface - Define a media interface graph object
  *
  * @graph_obj:		embedded graph object
- * @list:		Linked list used to find other interfaces that belong
- *			to the same media controller
  * @links:		List of links pointing to graph entities
  * @type:		Type of the interface as defined at the
  *			uapi/media/media.h header, e. g.
@@ -177,7 +231,7 @@ struct media_interface {
 };
 
 /**
- * struct media_intf_devnode - Define a Kernel API interface via a device node
+ * struct media_intf_devnode - Define a media interface via a device node
  *
  * @intf:	embedded interface object
  * @major:	Major number of a device node
Signature · 1 line
2.4.3
#259 lore raw
In reply to Mauro Carvalho Chehab

Em Sun, 30 Aug 2015 00:06:11 -0300
Mauro Carvalho Chehab <[email protected]> escreveu:

Quoted 11 lines

That's the 8th version of the MC next generation patches.

Differences from version 7:

- Patches reworked to make the reviewers happy;
- Bug fixes;
- ALSA changes got their own separate patches;
- Javier patches got integrated into this series;
- media-entity.h structs are now properly documented;
- Tested on both au0828 and omap3isp.

Quoted 6 lines

Due to the complexity of this change, other platform drivers may require some fixes.

As the patch series sent before, this is not meant to be sent upstream yet. Its goal is to merge it for Kernel 4.4, in order to give people enough time to review and fix pending issues.

As on the previous series, the patches are available on my experimental tree:
http://git.linuxtv.org/cgit.cgi/mchehab/experimental.git/log/?h=mc_next_gen

There's one additional patch there that removes the backlinks from G_TOPOLOGY ioctl. I'll be posting it in separate at the ML.

I also added a new branch:
http://git.linuxtv.org/cgit.cgi/mchehab/experimental.git/log/?h=mc_next_gen_test

Based on the first one. It contains a hack for au0828 that exposes the tuner also via subdev devnode, and reduces the number of output pads of the DVB demux to just 5, as the default is too high to produce a .dot file that would be useful. Of course, this patch should never leave my experimental tree ;)

There are a few other from Javier there meant to allow testing the omap3isp on my Beaglebone (that doesn't have any sensor on it) and on his omap3 devices.

I added support at the mc_nextgen_test tool to produce Graphviz .dot files. It is still experimental, but it is good enough to already produce some useful graphs. The newest version is at:

http://git.linuxtv.org/cgit.cgi/mchehab/experimental-v4l-utils.git/log/?h=mc-next-gen

I added some graphs produced by it at:
https://mchehab.fedorapeople.org/mc-next-gen/

Regards,
Mauro