Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a65a948 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] uvcvideo: Connect video devices to media entities



The video devices associated to USB streaming terminals must be
connected to their associated terminal's media entity instead of being
standalone entities.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 4ffc2d89
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1616,6 +1616,10 @@ static void uvc_delete(struct uvc_device *dev)
#ifdef CONFIG_MEDIA_CONTROLLER
		uvc_mc_cleanup_entity(entity);
#endif
		if (entity->vdev) {
			video_device_release(entity->vdev);
			entity->vdev = NULL;
		}
		kfree(entity);
	}

@@ -1638,8 +1642,6 @@ static void uvc_release(struct video_device *vdev)
	struct uvc_streaming *stream = video_get_drvdata(vdev);
	struct uvc_device *dev = stream->dev;

	video_device_release(vdev);

	/* Decrement the registered streams count and delete the device when it
	 * reaches zero.
	 */
@@ -1753,6 +1755,8 @@ static int uvc_register_terms(struct uvc_device *dev,
		ret = uvc_register_video(dev, stream);
		if (ret < 0)
			return ret;

		term->vdev = stream->vdev;
	}

	return 0;
+32 −8
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
	int ret;

	for (i = 0; i < entity->num_pads; ++i) {
		struct media_entity *source;
		struct media_entity *sink;

		if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK))
			continue;

@@ -40,14 +43,23 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
		if (remote == NULL)
			return -EINVAL;

		source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
		       ? &remote->vdev->entity : &remote->subdev.entity;
		sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
		     ? &entity->vdev->entity : &entity->subdev.entity;

		remote_pad = remote->num_pads - 1;
		ret = media_entity_create_link(&remote->subdev.entity,
				remote_pad, &entity->subdev.entity, i, flags);
		ret = media_entity_create_link(source, remote_pad,
					       sink, i, flags);
		if (ret < 0)
			return ret;
	}

	return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev);
	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING)
		ret = v4l2_device_register_subdev(&chain->dev->vdev,
						  &entity->subdev);

	return ret;
}

static struct v4l2_subdev_ops uvc_subdev_ops = {
@@ -55,16 +67,28 @@ static struct v4l2_subdev_ops uvc_subdev_ops = {

void uvc_mc_cleanup_entity(struct uvc_entity *entity)
{
	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING)
		media_entity_cleanup(&entity->subdev.entity);
	else if (entity->vdev != NULL)
		media_entity_cleanup(&entity->vdev->entity);
}

static int uvc_mc_init_entity(struct uvc_entity *entity)
{
	int ret;

	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) {
		v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops);
	strlcpy(entity->subdev.name, entity->name, sizeof(entity->subdev.name));
		strlcpy(entity->subdev.name, entity->name,
			sizeof(entity->subdev.name));

	return media_entity_init(&entity->subdev.entity, entity->num_pads,
				 entity->pads, 0);
		ret = media_entity_init(&entity->subdev.entity,
					entity->num_pads, entity->pads, 0);
	} else
		ret = media_entity_init(&entity->vdev->entity,
					entity->num_pads, entity->pads, 0);

	return ret;
}

int uvc_mc_register_entities(struct uvc_video_chain *chain)
+1 −0
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ struct uvc_entity {
	char name[64];

	/* Media controller-related fields. */
	struct video_device *vdev;
	struct v4l2_subdev subdev;
	unsigned int num_pads;
	unsigned int num_links;