aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-03-15 11:11:17 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-25 07:46:42 -0400
commita4056c2fb4c4646267e23dcf6d72f0e28f2e0891 (patch)
tree77711afd42db8b7e201eb1903d30ebe48f5b288b
parent382c31a94330a96e5800358140840998671722bf (diff)
[media] solo6x10: convert the display node to vb2
As a consequence the ioctl op has been replaced by unlocked_ioctl. Since we are now using the core lock the locking scheme has been simplified as well. The main reason for converting this driver to vb2 was that the locking scheme in v4l2.c was hopeless. It was easier to just convert the driver then to try and salvage a threading and videobuf nightmare. The videobuf2 framework is far, far superior compared to the old videobuf. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/staging/media/solo6x10/Kconfig2
-rw-r--r--drivers/staging/media/solo6x10/solo6x10.h7
-rw-r--r--drivers/staging/media/solo6x10/v4l2-enc.c12
-rw-r--r--drivers/staging/media/solo6x10/v4l2.c289
4 files changed, 103 insertions, 207 deletions
diff --git a/drivers/staging/media/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig
index f93b4cab9cc7..ec32776ff547 100644
--- a/drivers/staging/media/solo6x10/Kconfig
+++ b/drivers/staging/media/solo6x10/Kconfig
@@ -1,8 +1,8 @@
1config SOLO6X10 1config SOLO6X10
2 tristate "Softlogic 6x10 MPEG codec cards" 2 tristate "Softlogic 6x10 MPEG codec cards"
3 depends on PCI && VIDEO_DEV && SND && I2C 3 depends on PCI && VIDEO_DEV && SND && I2C
4 select VIDEOBUF_DMA_SG
5 select VIDEOBUF2_DMA_SG 4 select VIDEOBUF2_DMA_SG
5 select VIDEOBUF2_DMA_CONTIG
6 select SND_PCM 6 select SND_PCM
7 ---help--- 7 ---help---
8 This driver supports the Softlogic based MPEG-4 and h.264 codec 8 This driver supports the Softlogic based MPEG-4 and h.264 codec
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h
index d18093fac2b2..518166271acf 100644
--- a/drivers/staging/media/solo6x10/solo6x10.h
+++ b/drivers/staging/media/solo6x10/solo6x10.h
@@ -39,7 +39,6 @@
39#include <media/v4l2-dev.h> 39#include <media/v4l2-dev.h>
40#include <media/v4l2-device.h> 40#include <media/v4l2-device.h>
41#include <media/v4l2-ctrls.h> 41#include <media/v4l2-ctrls.h>
42#include <media/videobuf-core.h>
43#include <media/videobuf2-core.h> 42#include <media/videobuf2-core.h>
44 43
45#include "registers.h" 44#include "registers.h"
@@ -259,8 +258,6 @@ struct solo_dev {
259 /* Ring thread */ 258 /* Ring thread */
260 struct task_struct *ring_thread; 259 struct task_struct *ring_thread;
261 wait_queue_head_t ring_thread_wait; 260 wait_queue_head_t ring_thread_wait;
262 atomic_t enc_users;
263 atomic_t disp_users;
264 261
265 /* VOP_HEADER handling */ 262 /* VOP_HEADER handling */
266 void *vh_buf; 263 void *vh_buf;
@@ -268,8 +265,10 @@ struct solo_dev {
268 int vh_size; 265 int vh_size;
269 266
270 /* Buffer handling */ 267 /* Buffer handling */
271 struct videobuf_queue vidq; 268 struct vb2_queue vidq;
269 struct vb2_alloc_ctx *alloc_ctx;
272 struct task_struct *kthread; 270 struct task_struct *kthread;
271 struct mutex lock;
273 spinlock_t slock; 272 spinlock_t slock;
274 int old_write; 273 int old_write;
275 struct list_head vidq_active; 274 struct list_head vidq_active;
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c
index d7d96ce1006d..4dda6ecfea60 100644
--- a/drivers/staging/media/solo6x10/v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/v4l2-enc.c
@@ -41,11 +41,6 @@
41#define MP4_QS 16 41#define MP4_QS 16
42#define DMA_ALIGN 4096 42#define DMA_ALIGN 4096
43 43
44struct solo_videobuf {
45 struct videobuf_buffer vb;
46 unsigned int flags;
47};
48
49/* 6010 M4V */ 44/* 6010 M4V */
50static unsigned char vop_6010_ntsc_d1[] = { 45static unsigned char vop_6010_ntsc_d1[] = {
51 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 46 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20,
@@ -672,9 +667,6 @@ static void solo_enc_buf_queue(struct vb2_buffer *vb)
672 667
673static int solo_ring_start(struct solo_dev *solo_dev) 668static int solo_ring_start(struct solo_dev *solo_dev)
674{ 669{
675 if (atomic_inc_return(&solo_dev->enc_users) > 1)
676 return 0;
677
678 solo_dev->ring_thread = kthread_run(solo_ring_thread, solo_dev, 670 solo_dev->ring_thread = kthread_run(solo_ring_thread, solo_dev,
679 SOLO6X10_NAME "_ring"); 671 SOLO6X10_NAME "_ring");
680 if (IS_ERR(solo_dev->ring_thread)) { 672 if (IS_ERR(solo_dev->ring_thread)) {
@@ -690,9 +682,6 @@ static int solo_ring_start(struct solo_dev *solo_dev)
690 682
691static void solo_ring_stop(struct solo_dev *solo_dev) 683static void solo_ring_stop(struct solo_dev *solo_dev)
692{ 684{
693 if (atomic_dec_return(&solo_dev->enc_users) > 0)
694 return;
695
696 if (solo_dev->ring_thread) { 685 if (solo_dev->ring_thread) {
697 kthread_stop(solo_dev->ring_thread); 686 kthread_stop(solo_dev->ring_thread);
698 solo_dev->ring_thread = NULL; 687 solo_dev->ring_thread = NULL;
@@ -1279,7 +1268,6 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
1279{ 1268{
1280 int i; 1269 int i;
1281 1270
1282 atomic_set(&solo_dev->enc_users, 0);
1283 init_waitqueue_head(&solo_dev->ring_thread_wait); 1271 init_waitqueue_head(&solo_dev->ring_thread_wait);
1284 1272
1285 solo_dev->vh_size = sizeof(struct vop_header); 1273 solo_dev->vh_size = sizeof(struct vop_header);
diff --git a/drivers/staging/media/solo6x10/v4l2.c b/drivers/staging/media/solo6x10/v4l2.c
index 13b7640d8cac..d38a8fe8962d 100644
--- a/drivers/staging/media/solo6x10/v4l2.c
+++ b/drivers/staging/media/solo6x10/v4l2.c
@@ -30,7 +30,7 @@
30#include <media/v4l2-ioctl.h> 30#include <media/v4l2-ioctl.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32#include <media/v4l2-event.h> 32#include <media/v4l2-event.h>
33#include <media/videobuf-dma-contig.h> 33#include <media/videobuf2-dma-contig.h>
34 34
35#include "solo6x10.h" 35#include "solo6x10.h"
36#include "tw28.h" 36#include "tw28.h"
@@ -192,19 +192,19 @@ static int solo_v4l2_set_ch(struct solo_dev *solo_dev, u8 ch)
192} 192}
193 193
194static void solo_fillbuf(struct solo_dev *solo_dev, 194static void solo_fillbuf(struct solo_dev *solo_dev,
195 struct videobuf_buffer *vb) 195 struct vb2_buffer *vb)
196{ 196{
197 dma_addr_t vbuf; 197 dma_addr_t vbuf;
198 unsigned int fdma_addr; 198 unsigned int fdma_addr;
199 int error = -1; 199 int error = -1;
200 int i; 200 int i;
201 201
202 vbuf = videobuf_to_dma_contig(vb); 202 vbuf = vb2_dma_contig_plane_dma_addr(vb, 0);
203 if (!vbuf) 203 if (!vbuf)
204 goto finish_buf; 204 goto finish_buf;
205 205
206 if (erase_off(solo_dev)) { 206 if (erase_off(solo_dev)) {
207 void *p = videobuf_queue_to_vaddr(&solo_dev->vidq, vb); 207 void *p = vb2_plane_vaddr(vb, 0);
208 int image_size = solo_image_size(solo_dev); 208 int image_size = solo_image_size(solo_dev);
209 for (i = 0; i < image_size; i += 2) { 209 for (i = 0; i < image_size; i += 2) {
210 ((u8 *)p)[i] = 0x80; 210 ((u8 *)p)[i] = 0x80;
@@ -221,19 +221,19 @@ static void solo_fillbuf(struct solo_dev *solo_dev,
221 } 221 }
222 222
223finish_buf: 223finish_buf:
224 if (error) { 224 if (!error) {
225 vb->state = VIDEOBUF_ERROR; 225 vb2_set_plane_payload(vb, 0,
226 } else { 226 solo_vlines(solo_dev) * solo_bytesperline(solo_dev));
227 vb->state = VIDEOBUF_DONE; 227 vb->v4l2_buf.sequence++;
228 vb->field_count++; 228 v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
229 } 229 }
230 230
231 wake_up(&vb->done); 231 vb2_buffer_done(vb, error ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
232} 232}
233 233
234static void solo_thread_try(struct solo_dev *solo_dev) 234static void solo_thread_try(struct solo_dev *solo_dev)
235{ 235{
236 struct videobuf_buffer *vb; 236 struct solo_vb2_buf *vb;
237 237
238 /* Only "break" from this loop if slock is held, otherwise 238 /* Only "break" from this loop if slock is held, otherwise
239 * just return. */ 239 * just return. */
@@ -250,19 +250,15 @@ static void solo_thread_try(struct solo_dev *solo_dev)
250 if (list_empty(&solo_dev->vidq_active)) 250 if (list_empty(&solo_dev->vidq_active))
251 break; 251 break;
252 252
253 vb = list_first_entry(&solo_dev->vidq_active, struct videobuf_buffer, 253 vb = list_first_entry(&solo_dev->vidq_active, struct solo_vb2_buf,
254 queue); 254 list);
255
256 if (!waitqueue_active(&vb->done))
257 break;
258 255
259 solo_dev->old_write = cur_write; 256 solo_dev->old_write = cur_write;
260 list_del(&vb->queue); 257 list_del(&vb->list);
261 vb->state = VIDEOBUF_ACTIVE;
262 258
263 spin_unlock(&solo_dev->slock); 259 spin_unlock(&solo_dev->slock);
264 260
265 solo_fillbuf(solo_dev, vb); 261 solo_fillbuf(solo_dev, &vb->vb);
266 } 262 }
267 263
268 assert_spin_locked(&solo_dev->slock); 264 assert_spin_locked(&solo_dev->slock);
@@ -294,15 +290,14 @@ static int solo_start_thread(struct solo_dev *solo_dev)
294{ 290{
295 int ret = 0; 291 int ret = 0;
296 292
297 if (atomic_inc_return(&solo_dev->disp_users) == 1)
298 solo_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN);
299
300 solo_dev->kthread = kthread_run(solo_thread, solo_dev, SOLO6X10_NAME "_disp"); 293 solo_dev->kthread = kthread_run(solo_thread, solo_dev, SOLO6X10_NAME "_disp");
301 294
302 if (IS_ERR(solo_dev->kthread)) { 295 if (IS_ERR(solo_dev->kthread)) {
303 ret = PTR_ERR(solo_dev->kthread); 296 ret = PTR_ERR(solo_dev->kthread);
304 solo_dev->kthread = NULL; 297 solo_dev->kthread = NULL;
298 return ret;
305 } 299 }
300 solo_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN);
306 301
307 return ret; 302 return ret;
308} 303}
@@ -312,116 +307,65 @@ static void solo_stop_thread(struct solo_dev *solo_dev)
312 if (!solo_dev->kthread) 307 if (!solo_dev->kthread)
313 return; 308 return;
314 309
310 solo_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN);
315 kthread_stop(solo_dev->kthread); 311 kthread_stop(solo_dev->kthread);
316 solo_dev->kthread = NULL; 312 solo_dev->kthread = NULL;
317
318 if (atomic_dec_return(&solo_dev->disp_users) == 0)
319 solo_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN);
320} 313}
321 314
322static int solo_buf_setup(struct videobuf_queue *vq, unsigned int *count, 315static int solo_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
323 unsigned int *size) 316 unsigned int *num_buffers, unsigned int *num_planes,
317 unsigned int sizes[], void *alloc_ctxs[])
324{ 318{
325 struct solo_dev *solo_dev = vq->priv_data; 319 struct solo_dev *solo_dev = vb2_get_drv_priv(q);
326 320
327 *size = solo_image_size(solo_dev); 321 sizes[0] = solo_image_size(solo_dev);
322 alloc_ctxs[0] = solo_dev->alloc_ctx;
323 *num_planes = 1;
328 324
329 if (*count < MIN_VID_BUFFERS) 325 if (*num_buffers < MIN_VID_BUFFERS)
330 *count = MIN_VID_BUFFERS; 326 *num_buffers = MIN_VID_BUFFERS;
331 327
332 return 0; 328 return 0;
333} 329}
334 330
335static int solo_buf_prepare(struct videobuf_queue *vq, 331static int solo_start_streaming(struct vb2_queue *q, unsigned int count)
336 struct videobuf_buffer *vb, enum v4l2_field field)
337{ 332{
338 struct solo_dev *solo_dev = vq->priv_data; 333 struct solo_dev *solo_dev = vb2_get_drv_priv(q);
339 334
340 vb->size = solo_image_size(solo_dev); 335 return solo_start_thread(solo_dev);
341 if (vb->baddr != 0 && vb->bsize < vb->size) 336}
342 return -EINVAL;
343 337
344 /* XXX: These properties only change when queue is idle */ 338static int solo_stop_streaming(struct vb2_queue *q)
345 vb->width = solo_dev->video_hsize; 339{
346 vb->height = solo_vlines(solo_dev); 340 struct solo_dev *solo_dev = vb2_get_drv_priv(q);
347 vb->bytesperline = solo_bytesperline(solo_dev);
348 vb->field = field;
349
350 if (vb->state == VIDEOBUF_NEEDS_INIT) {
351 int rc = videobuf_iolock(vq, vb, NULL);
352 if (rc < 0) {
353 videobuf_dma_contig_free(vq, vb);
354 vb->state = VIDEOBUF_NEEDS_INIT;
355 return rc;
356 }
357 }
358 vb->state = VIDEOBUF_PREPARED;
359 341
342 solo_stop_thread(solo_dev);
343 INIT_LIST_HEAD(&solo_dev->vidq_active);
360 return 0; 344 return 0;
361} 345}
362 346
363static void solo_buf_queue(struct videobuf_queue *vq, 347static void solo_buf_queue(struct vb2_buffer *vb)
364 struct videobuf_buffer *vb)
365{ 348{
366 struct solo_dev *solo_dev = vq->priv_data; 349 struct vb2_queue *vq = vb->vb2_queue;
350 struct solo_dev *solo_dev = vb2_get_drv_priv(vq);
351 struct solo_vb2_buf *solo_vb =
352 container_of(vb, struct solo_vb2_buf, vb);
367 353
368 vb->state = VIDEOBUF_QUEUED; 354 spin_lock(&solo_dev->slock);
369 list_add_tail(&vb->queue, &solo_dev->vidq_active); 355 list_add_tail(&solo_vb->list, &solo_dev->vidq_active);
356 spin_unlock(&solo_dev->slock);
370 wake_up_interruptible(&solo_dev->disp_thread_wait); 357 wake_up_interruptible(&solo_dev->disp_thread_wait);
371} 358}
372 359
373static void solo_buf_release(struct videobuf_queue *vq, 360static const struct vb2_ops solo_video_qops = {
374 struct videobuf_buffer *vb) 361 .queue_setup = solo_queue_setup,
375{
376 videobuf_dma_contig_free(vq, vb);
377 vb->state = VIDEOBUF_NEEDS_INIT;
378}
379
380static const struct videobuf_queue_ops solo_video_qops = {
381 .buf_setup = solo_buf_setup,
382 .buf_prepare = solo_buf_prepare,
383 .buf_queue = solo_buf_queue, 362 .buf_queue = solo_buf_queue,
384 .buf_release = solo_buf_release, 363 .start_streaming = solo_start_streaming,
364 .stop_streaming = solo_stop_streaming,
365 .wait_prepare = vb2_ops_wait_prepare,
366 .wait_finish = vb2_ops_wait_finish,
385}; 367};
386 368
387static unsigned int solo_v4l2_poll(struct file *file,
388 struct poll_table_struct *wait)
389{
390 struct solo_dev *solo_dev = video_drvdata(file);
391 unsigned long req_events = poll_requested_events(wait);
392 unsigned res = v4l2_ctrl_poll(file, wait);
393
394 if (!(req_events & (POLLIN | POLLRDNORM)))
395 return res;
396 return res | videobuf_poll_stream(file, &solo_dev->vidq, wait);
397}
398
399static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
400{
401 struct solo_dev *solo_dev = video_drvdata(file);
402
403 return videobuf_mmap_mapper(&solo_dev->vidq, vma);
404}
405
406static ssize_t solo_v4l2_read(struct file *file, char __user *data,
407 size_t count, loff_t *ppos)
408{
409 struct solo_dev *solo_dev = video_drvdata(file);
410
411 return videobuf_read_stream(&solo_dev->vidq, data, count, ppos, 0,
412 file->f_flags & O_NONBLOCK);
413}
414
415static int solo_v4l2_release(struct file *file)
416{
417 struct solo_dev *solo_dev = video_drvdata(file);
418
419 solo_stop_thread(solo_dev);
420 videobuf_stop(&solo_dev->vidq);
421 videobuf_mmap_free(&solo_dev->vidq);
422 return v4l2_fh_release(file);
423}
424
425static int solo_querycap(struct file *file, void *priv, 369static int solo_querycap(struct file *file, void *priv,
426 struct v4l2_capability *cap) 370 struct v4l2_capability *cap)
427{ 371{
@@ -550,7 +494,7 @@ static int solo_set_fmt_cap(struct file *file, void *priv,
550{ 494{
551 struct solo_dev *solo_dev = video_drvdata(file); 495 struct solo_dev *solo_dev = video_drvdata(file);
552 496
553 if (videobuf_queue_is_busy(&solo_dev->vidq)) 497 if (vb2_is_busy(&solo_dev->vidq))
554 return -EBUSY; 498 return -EBUSY;
555 499
556 /* For right now, if it doesn't match our running config, 500 /* For right now, if it doesn't match our running config,
@@ -576,61 +520,6 @@ static int solo_get_fmt_cap(struct file *file, void *priv,
576 return 0; 520 return 0;
577} 521}
578 522
579static int solo_reqbufs(struct file *file, void *priv,
580 struct v4l2_requestbuffers *req)
581{
582 struct solo_dev *solo_dev = video_drvdata(file);
583
584 return videobuf_reqbufs(&solo_dev->vidq, req);
585}
586
587static int solo_querybuf(struct file *file, void *priv,
588 struct v4l2_buffer *buf)
589{
590 struct solo_dev *solo_dev = video_drvdata(file);
591
592 return videobuf_querybuf(&solo_dev->vidq, buf);
593}
594
595static int solo_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
596{
597 struct solo_dev *solo_dev = video_drvdata(file);
598
599 return videobuf_qbuf(&solo_dev->vidq, buf);
600}
601
602static int solo_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
603{
604 struct solo_dev *solo_dev = video_drvdata(file);
605
606 return videobuf_dqbuf(&solo_dev->vidq, buf, file->f_flags & O_NONBLOCK);
607}
608
609static int solo_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
610{
611 struct solo_dev *solo_dev = video_drvdata(file);
612 int ret;
613
614 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
615 return -EINVAL;
616
617 ret = solo_start_thread(solo_dev);
618 if (ret)
619 return ret;
620
621 return videobuf_streamon(&solo_dev->vidq);
622}
623
624static int solo_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
625{
626 struct solo_dev *solo_dev = video_drvdata(file);
627
628 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
629 return -EINVAL;
630
631 return videobuf_streamoff(&solo_dev->vidq);
632}
633
634static int solo_s_std(struct file *file, void *priv, v4l2_std_id i) 523static int solo_s_std(struct file *file, void *priv, v4l2_std_id i)
635{ 524{
636 return 0; 525 return 0;
@@ -668,11 +557,11 @@ static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
668static const struct v4l2_file_operations solo_v4l2_fops = { 557static const struct v4l2_file_operations solo_v4l2_fops = {
669 .owner = THIS_MODULE, 558 .owner = THIS_MODULE,
670 .open = v4l2_fh_open, 559 .open = v4l2_fh_open,
671 .release = solo_v4l2_release, 560 .release = vb2_fop_release,
672 .read = solo_v4l2_read, 561 .read = vb2_fop_read,
673 .poll = solo_v4l2_poll, 562 .poll = vb2_fop_poll,
674 .mmap = solo_v4l2_mmap, 563 .mmap = vb2_fop_mmap,
675 .ioctl = video_ioctl2, 564 .unlocked_ioctl = video_ioctl2,
676}; 565};
677 566
678static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { 567static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = {
@@ -688,12 +577,12 @@ static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = {
688 .vidioc_s_fmt_vid_cap = solo_set_fmt_cap, 577 .vidioc_s_fmt_vid_cap = solo_set_fmt_cap,
689 .vidioc_g_fmt_vid_cap = solo_get_fmt_cap, 578 .vidioc_g_fmt_vid_cap = solo_get_fmt_cap,
690 /* Streaming I/O */ 579 /* Streaming I/O */
691 .vidioc_reqbufs = solo_reqbufs, 580 .vidioc_reqbufs = vb2_ioctl_reqbufs,
692 .vidioc_querybuf = solo_querybuf, 581 .vidioc_querybuf = vb2_ioctl_querybuf,
693 .vidioc_qbuf = solo_qbuf, 582 .vidioc_qbuf = vb2_ioctl_qbuf,
694 .vidioc_dqbuf = solo_dqbuf, 583 .vidioc_dqbuf = vb2_ioctl_dqbuf,
695 .vidioc_streamon = solo_streamon, 584 .vidioc_streamon = vb2_ioctl_streamon,
696 .vidioc_streamoff = solo_streamoff, 585 .vidioc_streamoff = vb2_ioctl_streamoff,
697 /* Logging and events */ 586 /* Logging and events */
698 .vidioc_log_status = v4l2_ctrl_log_status, 587 .vidioc_log_status = v4l2_ctrl_log_status,
699 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 588 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
@@ -729,8 +618,10 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
729 int ret; 618 int ret;
730 int i; 619 int i;
731 620
732 atomic_set(&solo_dev->disp_users, 0);
733 init_waitqueue_head(&solo_dev->disp_thread_wait); 621 init_waitqueue_head(&solo_dev->disp_thread_wait);
622 spin_lock_init(&solo_dev->slock);
623 mutex_init(&solo_dev->lock);
624 INIT_LIST_HEAD(&solo_dev->vidq_active);
734 625
735 solo_dev->vfd = video_device_alloc(); 626 solo_dev->vfd = video_device_alloc();
736 if (!solo_dev->vfd) 627 if (!solo_dev->vfd)
@@ -738,24 +629,37 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
738 629
739 *solo_dev->vfd = solo_v4l2_template; 630 *solo_dev->vfd = solo_v4l2_template;
740 solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev; 631 solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev;
632 solo_dev->vfd->queue = &solo_dev->vidq;
633 solo_dev->vfd->lock = &solo_dev->lock;
741 v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1); 634 v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1);
742 v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL); 635 v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL);
743 if (solo_dev->disp_hdl.error) 636 if (solo_dev->disp_hdl.error) {
744 return solo_dev->disp_hdl.error; 637 ret = solo_dev->disp_hdl.error;
638 goto fail;
639 }
745 solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; 640 solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl;
746 set_bit(V4L2_FL_USE_FH_PRIO, &solo_dev->vfd->flags); 641 set_bit(V4L2_FL_USE_FH_PRIO, &solo_dev->vfd->flags);
747 642
748 video_set_drvdata(solo_dev->vfd, solo_dev); 643 video_set_drvdata(solo_dev->vfd, solo_dev);
749 644
750 spin_lock_init(&solo_dev->slock); 645 solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
751 INIT_LIST_HEAD(&solo_dev->vidq_active); 646 solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
752 647 solo_dev->vidq.ops = &solo_video_qops;
753 videobuf_queue_dma_contig_init(&solo_dev->vidq, &solo_video_qops, 648 solo_dev->vidq.mem_ops = &vb2_dma_contig_memops;
754 &solo_dev->pdev->dev, &solo_dev->slock, 649 solo_dev->vidq.drv_priv = solo_dev;
755 V4L2_BUF_TYPE_VIDEO_CAPTURE, 650 solo_dev->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
756 V4L2_FIELD_INTERLACED, 651 solo_dev->vidq.gfp_flags = __GFP_DMA32;
757 sizeof(struct videobuf_buffer), 652 solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
758 solo_dev, NULL); 653 solo_dev->vidq.lock = &solo_dev->lock;
654 ret = vb2_queue_init(&solo_dev->vidq);
655 if (ret < 0)
656 goto fail;
657
658 solo_dev->alloc_ctx = vb2_dma_contig_init_ctx(&solo_dev->pdev->dev);
659 if (IS_ERR(solo_dev->alloc_ctx)) {
660 dev_err(&solo_dev->pdev->dev, "Can't allocate buffer context");
661 return PTR_ERR(solo_dev->alloc_ctx);
662 }
759 663
760 /* Cycle all the channels and clear */ 664 /* Cycle all the channels and clear */
761 for (i = 0; i < solo_dev->nr_chans; i++) { 665 for (i = 0; i < solo_dev->nr_chans; i++) {
@@ -770,11 +674,8 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
770 /* Do nothing */; 674 /* Do nothing */;
771 675
772 ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); 676 ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr);
773 if (ret < 0) { 677 if (ret < 0)
774 video_device_release(solo_dev->vfd); 678 goto fail;
775 solo_dev->vfd = NULL;
776 return ret;
777 }
778 679
779 snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", 680 snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)",
780 SOLO6X10_NAME, solo_dev->vfd->num); 681 SOLO6X10_NAME, solo_dev->vfd->num);
@@ -784,6 +685,13 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr)
784 solo_dev->nr_chans, solo_dev->nr_ext); 685 solo_dev->nr_chans, solo_dev->nr_ext);
785 686
786 return 0; 687 return 0;
688
689fail:
690 video_device_release(solo_dev->vfd);
691 vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx);
692 v4l2_ctrl_handler_free(&solo_dev->disp_hdl);
693 solo_dev->vfd = NULL;
694 return ret;
787} 695}
788 696
789void solo_v4l2_exit(struct solo_dev *solo_dev) 697void solo_v4l2_exit(struct solo_dev *solo_dev)
@@ -792,6 +700,7 @@ void solo_v4l2_exit(struct solo_dev *solo_dev)
792 return; 700 return;
793 701
794 video_unregister_device(solo_dev->vfd); 702 video_unregister_device(solo_dev->vfd);
703 vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx);
795 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); 704 v4l2_ctrl_handler_free(&solo_dev->disp_hdl);
796 solo_dev->vfd = NULL; 705 solo_dev->vfd = NULL;
797} 706}