aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_entity.c34
-rw-r--r--drivers/media/video/uvc/uvc_queue.c2
-rw-r--r--drivers/media/video/uvc/uvc_video.c4
3 files changed, 26 insertions, 14 deletions
diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c
index c3ab0c813be2..48fea373c25a 100644
--- a/drivers/media/video/uvc/uvc_entity.c
+++ b/drivers/media/video/uvc/uvc_entity.c
@@ -27,14 +27,20 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
27 struct uvc_entity *entity) 27 struct uvc_entity *entity)
28{ 28{
29 const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; 29 const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
30 struct uvc_entity *remote; 30 struct media_entity *sink;
31 unsigned int i; 31 unsigned int i;
32 u8 remote_pad; 32 int ret;
33 int ret = 0; 33
34 sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
35 ? (entity->vdev ? &entity->vdev->entity : NULL)
36 : &entity->subdev.entity;
37 if (sink == NULL)
38 return 0;
34 39
35 for (i = 0; i < entity->num_pads; ++i) { 40 for (i = 0; i < entity->num_pads; ++i) {
36 struct media_entity *source; 41 struct media_entity *source;
37 struct media_entity *sink; 42 struct uvc_entity *remote;
43 u8 remote_pad;
38 44
39 if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) 45 if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK))
40 continue; 46 continue;
@@ -43,10 +49,11 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
43 if (remote == NULL) 49 if (remote == NULL)
44 return -EINVAL; 50 return -EINVAL;
45 51
46 source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) 52 source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING)
47 ? &remote->vdev->entity : &remote->subdev.entity; 53 ? (remote->vdev ? &remote->vdev->entity : NULL)
48 sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) 54 : &remote->subdev.entity;
49 ? &entity->vdev->entity : &entity->subdev.entity; 55 if (source == NULL)
56 continue;
50 57
51 remote_pad = remote->num_pads - 1; 58 remote_pad = remote->num_pads - 1;
52 ret = media_entity_create_link(source, remote_pad, 59 ret = media_entity_create_link(source, remote_pad,
@@ -55,11 +62,10 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
55 return ret; 62 return ret;
56 } 63 }
57 64
58 if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) 65 if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
59 ret = v4l2_device_register_subdev(&chain->dev->vdev, 66 return 0;
60 &entity->subdev);
61 67
62 return ret; 68 return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev);
63} 69}
64 70
65static struct v4l2_subdev_ops uvc_subdev_ops = { 71static struct v4l2_subdev_ops uvc_subdev_ops = {
@@ -84,9 +90,11 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
84 90
85 ret = media_entity_init(&entity->subdev.entity, 91 ret = media_entity_init(&entity->subdev.entity,
86 entity->num_pads, entity->pads, 0); 92 entity->num_pads, entity->pads, 0);
87 } else 93 } else if (entity->vdev != NULL) {
88 ret = media_entity_init(&entity->vdev->entity, 94 ret = media_entity_init(&entity->vdev->entity,
89 entity->num_pads, entity->pads, 0); 95 entity->num_pads, entity->pads, 0);
96 } else
97 ret = 0;
90 98
91 return ret; 99 return ret;
92} 100}
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 109a06384a8f..f90ce9fce539 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -104,6 +104,8 @@ static int __uvc_free_buffers(struct uvc_video_queue *queue)
104 } 104 }
105 105
106 if (queue->count) { 106 if (queue->count) {
107 uvc_queue_cancel(queue, 0);
108 INIT_LIST_HEAD(&queue->mainqueue);
107 vfree(queue->mem); 109 vfree(queue->mem);
108 queue->count = 0; 110 queue->count = 0;
109 } 111 }
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index fc766b9f24c5..49994793cc77 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1255,8 +1255,10 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
1255 1255
1256 /* Commit the streaming parameters. */ 1256 /* Commit the streaming parameters. */
1257 ret = uvc_commit_video(stream, &stream->ctrl); 1257 ret = uvc_commit_video(stream, &stream->ctrl);
1258 if (ret < 0) 1258 if (ret < 0) {
1259 uvc_queue_enable(&stream->queue, 0);
1259 return ret; 1260 return ret;
1261 }
1260 1262
1261 return uvc_init_video(stream, GFP_KERNEL); 1263 return uvc_init_video(stream, GFP_KERNEL);
1262} 1264}