diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2014-10-21 12:03:08 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2014-11-25 05:40:08 -0500 |
commit | a11a03e50b73234444f7d439fb8ee6eaec3cffd1 (patch) | |
tree | dc0d201f4b84a90de7faf132ccc61e4271829cc0 | |
parent | bc75d5a0097b4100b4a4e06db62b2afb80d96393 (diff) |
[media] uvcvideo: Implement vb2 queue start and stop stream operations
To work propertly the videobuf2 core code needs to be in charge of
stream start/stop control. Implement the start_streaming and
stop_streaming vb2 operations and move video enable/disable code to
them.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r-- | drivers/media/usb/uvc/uvc_queue.c | 43 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_v4l2.c | 10 |
2 files changed, 28 insertions, 25 deletions
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 97036559bb92..758247048ee1 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c | |||
@@ -135,6 +135,29 @@ static void uvc_wait_finish(struct vb2_queue *vq) | |||
135 | mutex_lock(&queue->mutex); | 135 | mutex_lock(&queue->mutex); |
136 | } | 136 | } |
137 | 137 | ||
138 | static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count) | ||
139 | { | ||
140 | struct uvc_video_queue *queue = vb2_get_drv_priv(vq); | ||
141 | struct uvc_streaming *stream = uvc_queue_to_stream(queue); | ||
142 | |||
143 | queue->buf_used = 0; | ||
144 | |||
145 | return uvc_video_enable(stream, 1); | ||
146 | } | ||
147 | |||
148 | static void uvc_stop_streaming(struct vb2_queue *vq) | ||
149 | { | ||
150 | struct uvc_video_queue *queue = vb2_get_drv_priv(vq); | ||
151 | struct uvc_streaming *stream = uvc_queue_to_stream(queue); | ||
152 | unsigned long flags; | ||
153 | |||
154 | uvc_video_enable(stream, 0); | ||
155 | |||
156 | spin_lock_irqsave(&queue->irqlock, flags); | ||
157 | INIT_LIST_HEAD(&queue->irqqueue); | ||
158 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
159 | } | ||
160 | |||
138 | static struct vb2_ops uvc_queue_qops = { | 161 | static struct vb2_ops uvc_queue_qops = { |
139 | .queue_setup = uvc_queue_setup, | 162 | .queue_setup = uvc_queue_setup, |
140 | .buf_prepare = uvc_buffer_prepare, | 163 | .buf_prepare = uvc_buffer_prepare, |
@@ -142,6 +165,8 @@ static struct vb2_ops uvc_queue_qops = { | |||
142 | .buf_finish = uvc_buffer_finish, | 165 | .buf_finish = uvc_buffer_finish, |
143 | .wait_prepare = uvc_wait_prepare, | 166 | .wait_prepare = uvc_wait_prepare, |
144 | .wait_finish = uvc_wait_finish, | 167 | .wait_finish = uvc_wait_finish, |
168 | .start_streaming = uvc_start_streaming, | ||
169 | .stop_streaming = uvc_stop_streaming, | ||
145 | }; | 170 | }; |
146 | 171 | ||
147 | int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | 172 | int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, |
@@ -310,27 +335,15 @@ int uvc_queue_allocated(struct uvc_video_queue *queue) | |||
310 | */ | 335 | */ |
311 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) | 336 | int uvc_queue_enable(struct uvc_video_queue *queue, int enable) |
312 | { | 337 | { |
313 | unsigned long flags; | ||
314 | int ret; | 338 | int ret; |
315 | 339 | ||
316 | mutex_lock(&queue->mutex); | 340 | mutex_lock(&queue->mutex); |
317 | if (enable) { | ||
318 | ret = vb2_streamon(&queue->queue, queue->queue.type); | ||
319 | if (ret < 0) | ||
320 | goto done; | ||
321 | 341 | ||
322 | queue->buf_used = 0; | 342 | if (enable) |
323 | } else { | 343 | ret = vb2_streamon(&queue->queue, queue->queue.type); |
344 | else | ||
324 | ret = vb2_streamoff(&queue->queue, queue->queue.type); | 345 | ret = vb2_streamoff(&queue->queue, queue->queue.type); |
325 | if (ret < 0) | ||
326 | goto done; | ||
327 | |||
328 | spin_lock_irqsave(&queue->irqlock, flags); | ||
329 | INIT_LIST_HEAD(&queue->irqqueue); | ||
330 | spin_unlock_irqrestore(&queue->irqlock, flags); | ||
331 | } | ||
332 | 346 | ||
333 | done: | ||
334 | mutex_unlock(&queue->mutex); | 347 | mutex_unlock(&queue->mutex); |
335 | return ret; | 348 | return ret; |
336 | } | 349 | } |
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index e8bf4f149a26..4619fd6b0494 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c | |||
@@ -531,7 +531,6 @@ static int uvc_v4l2_release(struct file *file) | |||
531 | 531 | ||
532 | /* Only free resources if this is a privileged handle. */ | 532 | /* Only free resources if this is a privileged handle. */ |
533 | if (uvc_has_privileges(handle)) { | 533 | if (uvc_has_privileges(handle)) { |
534 | uvc_video_enable(stream, 0); | ||
535 | uvc_queue_enable(&stream->queue, 0); | 534 | uvc_queue_enable(&stream->queue, 0); |
536 | uvc_free_buffers(&stream->queue); | 535 | uvc_free_buffers(&stream->queue); |
537 | } | 536 | } |
@@ -768,14 +767,6 @@ static int uvc_ioctl_streamon(struct file *file, void *fh, | |||
768 | 767 | ||
769 | mutex_lock(&stream->mutex); | 768 | mutex_lock(&stream->mutex); |
770 | ret = uvc_queue_enable(&stream->queue, 1); | 769 | ret = uvc_queue_enable(&stream->queue, 1); |
771 | if (ret < 0) | ||
772 | goto done; | ||
773 | |||
774 | ret = uvc_video_enable(stream, 1); | ||
775 | if (ret < 0) | ||
776 | uvc_queue_enable(&stream->queue, 0); | ||
777 | |||
778 | done: | ||
779 | mutex_unlock(&stream->mutex); | 770 | mutex_unlock(&stream->mutex); |
780 | 771 | ||
781 | return ret; | 772 | return ret; |
@@ -794,7 +785,6 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, | |||
794 | return -EBUSY; | 785 | return -EBUSY; |
795 | 786 | ||
796 | mutex_lock(&stream->mutex); | 787 | mutex_lock(&stream->mutex); |
797 | uvc_video_enable(stream, 0); | ||
798 | uvc_queue_enable(&stream->queue, 0); | 788 | uvc_queue_enable(&stream->queue, 0); |
799 | mutex_unlock(&stream->mutex); | 789 | mutex_unlock(&stream->mutex); |
800 | 790 | ||