aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}