aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2011-06-10 14:36:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-06 16:37:18 -0400
commite578588eb01d9493513ca1527f464715cfd3f47f (patch)
tree8073e81fb2d3463117c9c2db1defec6990bfcbd3 /drivers/media
parentd3953223b0905437fef7ce60506b5fdfaf98dda6 (diff)
[media] s5p-fimc: Conversion to use struct v4l2_fh
This is a prerequisite for the patch converting the driver to use the control framework. As the capture driver does not use per file handle contexts, two separate ioctl handlers are created for it (vidioc_try_fmt_mplane, and vidioc_g_fmt_mplane) so there is no handlers shared between the memory-to-memory and capture video node. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c114
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c179
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h10
3 files changed, 165 insertions, 138 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index a1ac986a5e72..562b23c7d486 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -276,7 +276,10 @@ static struct vb2_ops fimc_capture_qops = {
276static int fimc_capture_open(struct file *file) 276static int fimc_capture_open(struct file *file)
277{ 277{
278 struct fimc_dev *fimc = video_drvdata(file); 278 struct fimc_dev *fimc = video_drvdata(file);
279 int ret = 0; 279 int ret = v4l2_fh_open(file);
280
281 if (ret)
282 return ret;
280 283
281 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); 284 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
282 285
@@ -285,11 +288,12 @@ static int fimc_capture_open(struct file *file)
285 return -EBUSY; 288 return -EBUSY;
286 289
287 ret = pm_runtime_get_sync(&fimc->pdev->dev); 290 ret = pm_runtime_get_sync(&fimc->pdev->dev);
288 if (ret) 291 if (ret < 0) {
292 v4l2_fh_release(file);
289 return ret; 293 return ret;
294 }
290 295
291 ++fimc->vid_cap.refcnt; 296 ++fimc->vid_cap.refcnt;
292 file->private_data = fimc->vid_cap.ctx;
293 297
294 return 0; 298 return 0;
295} 299}
@@ -307,22 +311,20 @@ static int fimc_capture_close(struct file *file)
307 311
308 pm_runtime_put(&fimc->pdev->dev); 312 pm_runtime_put(&fimc->pdev->dev);
309 313
310 return 0; 314 return v4l2_fh_release(file);
311} 315}
312 316
313static unsigned int fimc_capture_poll(struct file *file, 317static unsigned int fimc_capture_poll(struct file *file,
314 struct poll_table_struct *wait) 318 struct poll_table_struct *wait)
315{ 319{
316 struct fimc_ctx *ctx = file->private_data; 320 struct fimc_dev *fimc = video_drvdata(file);
317 struct fimc_dev *fimc = ctx->fimc_dev;
318 321
319 return vb2_poll(&fimc->vid_cap.vbq, file, wait); 322 return vb2_poll(&fimc->vid_cap.vbq, file, wait);
320} 323}
321 324
322static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) 325static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
323{ 326{
324 struct fimc_ctx *ctx = file->private_data; 327 struct fimc_dev *fimc = video_drvdata(file);
325 struct fimc_dev *fimc = ctx->fimc_dev;
326 328
327 return vb2_mmap(&fimc->vid_cap.vbq, vma); 329 return vb2_mmap(&fimc->vid_cap.vbq, vma);
328} 330}
@@ -340,8 +342,7 @@ static const struct v4l2_file_operations fimc_capture_fops = {
340static int fimc_vidioc_querycap_capture(struct file *file, void *priv, 342static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
341 struct v4l2_capability *cap) 343 struct v4l2_capability *cap)
342{ 344{
343 struct fimc_ctx *ctx = file->private_data; 345 struct fimc_dev *fimc = video_drvdata(file);
344 struct fimc_dev *fimc = ctx->fimc_dev;
345 346
346 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1); 347 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
347 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1); 348 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
@@ -388,20 +389,41 @@ static int sync_capture_fmt(struct fimc_ctx *ctx)
388 return 0; 389 return 0;
389} 390}
390 391
392static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
393 struct v4l2_format *f)
394{
395 struct fimc_dev *fimc = video_drvdata(file);
396 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
397
398 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
399 return -EINVAL;
400
401 return fimc_fill_format(&ctx->d_frame, f);
402}
403
404static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
405 struct v4l2_format *f)
406{
407 struct fimc_dev *fimc = video_drvdata(file);
408 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
409
410 return fimc_try_fmt_mplane(ctx, f);
411}
412
391static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, 413static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
392 struct v4l2_format *f) 414 struct v4l2_format *f)
393{ 415{
394 struct fimc_ctx *ctx = priv; 416 struct fimc_dev *fimc = video_drvdata(file);
395 struct fimc_dev *fimc = ctx->fimc_dev; 417 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
396 struct fimc_frame *frame;
397 struct v4l2_pix_format_mplane *pix; 418 struct v4l2_pix_format_mplane *pix;
419 struct fimc_frame *frame;
398 int ret; 420 int ret;
399 int i; 421 int i;
400 422
401 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 423 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
402 return -EINVAL; 424 return -EINVAL;
403 425
404 ret = fimc_vidioc_try_fmt_mplane(file, priv, f); 426 ret = fimc_try_fmt_mplane(ctx, f);
405 if (ret) 427 if (ret)
406 return ret; 428 return ret;
407 429
@@ -443,7 +465,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
443static int fimc_cap_enum_input(struct file *file, void *priv, 465static int fimc_cap_enum_input(struct file *file, void *priv,
444 struct v4l2_input *i) 466 struct v4l2_input *i)
445{ 467{
446 struct fimc_ctx *ctx = priv; 468 struct fimc_dev *fimc = video_drvdata(file);
447 469
448 if (i->index != 0) 470 if (i->index != 0)
449 return -EINVAL; 471 return -EINVAL;
@@ -467,8 +489,8 @@ static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
467static int fimc_cap_streamon(struct file *file, void *priv, 489static int fimc_cap_streamon(struct file *file, void *priv,
468 enum v4l2_buf_type type) 490 enum v4l2_buf_type type)
469{ 491{
470 struct fimc_ctx *ctx = priv; 492 struct fimc_dev *fimc = video_drvdata(file);
471 struct fimc_dev *fimc = ctx->fimc_dev; 493 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
472 494
473 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd) 495 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd)
474 return -EBUSY; 496 return -EBUSY;
@@ -484,8 +506,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
484static int fimc_cap_streamoff(struct file *file, void *priv, 506static int fimc_cap_streamoff(struct file *file, void *priv,
485 enum v4l2_buf_type type) 507 enum v4l2_buf_type type)
486{ 508{
487 struct fimc_ctx *ctx = priv; 509 struct fimc_dev *fimc = video_drvdata(file);
488 struct fimc_dev *fimc = ctx->fimc_dev;
489 510
490 return vb2_streamoff(&fimc->vid_cap.vbq, type); 511 return vb2_streamoff(&fimc->vid_cap.vbq, type);
491} 512}
@@ -493,47 +514,43 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
493static int fimc_cap_reqbufs(struct file *file, void *priv, 514static int fimc_cap_reqbufs(struct file *file, void *priv,
494 struct v4l2_requestbuffers *reqbufs) 515 struct v4l2_requestbuffers *reqbufs)
495{ 516{
496 struct fimc_ctx *ctx = priv; 517 struct fimc_dev *fimc = video_drvdata(file);
497 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; 518 int ret = vb2_reqbufs(&fimc->vid_cap.vbq, reqbufs);
498 int ret;
499
500 519
501 ret = vb2_reqbufs(&cap->vbq, reqbufs);
502 if (!ret) 520 if (!ret)
503 cap->reqbufs_count = reqbufs->count; 521 fimc->vid_cap.reqbufs_count = reqbufs->count;
504
505 return ret; 522 return ret;
506} 523}
507 524
508static int fimc_cap_querybuf(struct file *file, void *priv, 525static int fimc_cap_querybuf(struct file *file, void *priv,
509 struct v4l2_buffer *buf) 526 struct v4l2_buffer *buf)
510{ 527{
511 struct fimc_ctx *ctx = priv; 528 struct fimc_dev *fimc = video_drvdata(file);
512 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
513 529
514 return vb2_querybuf(&cap->vbq, buf); 530 return vb2_querybuf(&fimc->vid_cap.vbq, buf);
515} 531}
516 532
517static int fimc_cap_qbuf(struct file *file, void *priv, 533static int fimc_cap_qbuf(struct file *file, void *priv,
518 struct v4l2_buffer *buf) 534 struct v4l2_buffer *buf)
519{ 535{
520 struct fimc_ctx *ctx = priv; 536 struct fimc_dev *fimc = video_drvdata(file);
521 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; 537
522 return vb2_qbuf(&cap->vbq, buf); 538 return vb2_qbuf(&fimc->vid_cap.vbq, buf);
523} 539}
524 540
525static int fimc_cap_dqbuf(struct file *file, void *priv, 541static int fimc_cap_dqbuf(struct file *file, void *priv,
526 struct v4l2_buffer *buf) 542 struct v4l2_buffer *buf)
527{ 543{
528 struct fimc_ctx *ctx = priv; 544 struct fimc_dev *fimc = video_drvdata(file);
529 return vb2_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf, 545
530 file->f_flags & O_NONBLOCK); 546 return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK);
531} 547}
532 548
533static int fimc_cap_s_ctrl(struct file *file, void *priv, 549static int fimc_cap_s_ctrl(struct file *file, void *priv,
534 struct v4l2_control *ctrl) 550 struct v4l2_control *ctrl)
535{ 551{
536 struct fimc_ctx *ctx = priv; 552 struct fimc_dev *fimc = video_drvdata(file);
553 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
537 int ret = -EINVAL; 554 int ret = -EINVAL;
538 555
539 /* Allow any controls but 90/270 rotation while streaming */ 556 /* Allow any controls but 90/270 rotation while streaming */
@@ -556,14 +573,12 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
556static int fimc_cap_cropcap(struct file *file, void *fh, 573static int fimc_cap_cropcap(struct file *file, void *fh,
557 struct v4l2_cropcap *cr) 574 struct v4l2_cropcap *cr)
558{ 575{
559 struct fimc_frame *f; 576 struct fimc_dev *fimc = video_drvdata(file);
560 struct fimc_ctx *ctx = fh; 577 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
561 578
562 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 579 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
563 return -EINVAL; 580 return -EINVAL;
564 581
565 f = &ctx->s_frame;
566
567 cr->bounds.left = 0; 582 cr->bounds.left = 0;
568 cr->bounds.top = 0; 583 cr->bounds.top = 0;
569 cr->bounds.width = f->o_width; 584 cr->bounds.width = f->o_width;
@@ -575,10 +590,8 @@ static int fimc_cap_cropcap(struct file *file, void *fh,
575 590
576static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 591static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
577{ 592{
578 struct fimc_frame *f; 593 struct fimc_dev *fimc = video_drvdata(file);
579 struct fimc_ctx *ctx = file->private_data; 594 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
580
581 f = &ctx->s_frame;
582 595
583 cr->c.left = f->offs_h; 596 cr->c.left = f->offs_h;
584 cr->c.top = f->offs_v; 597 cr->c.top = f->offs_v;
@@ -588,12 +601,11 @@ static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
588 return 0; 601 return 0;
589} 602}
590 603
591static int fimc_cap_s_crop(struct file *file, void *fh, 604static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
592 struct v4l2_crop *cr)
593{ 605{
606 struct fimc_dev *fimc = video_drvdata(file);
607 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
594 struct fimc_frame *f; 608 struct fimc_frame *f;
595 struct fimc_ctx *ctx = file->private_data;
596 struct fimc_dev *fimc = ctx->fimc_dev;
597 int ret = -EINVAL; 609 int ret = -EINVAL;
598 610
599 if (fimc_capture_active(fimc)) 611 if (fimc_capture_active(fimc))
@@ -631,9 +643,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
631 .vidioc_querycap = fimc_vidioc_querycap_capture, 643 .vidioc_querycap = fimc_vidioc_querycap_capture,
632 644
633 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane, 645 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane,
634 .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane, 646 .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
635 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane, 647 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
636 .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane, 648 .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
637 649
638 .vidioc_reqbufs = fimc_cap_reqbufs, 650 .vidioc_reqbufs = fimc_cap_reqbufs,
639 .vidioc_querybuf = fimc_cap_querybuf, 651 .vidioc_querybuf = fimc_cap_querybuf,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 16314c94cc12..3dab803e8054 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -777,10 +777,10 @@ static struct vb2_ops fimc_qops = {
777 .start_streaming = start_streaming, 777 .start_streaming = start_streaming,
778}; 778};
779 779
780static int fimc_m2m_querycap(struct file *file, void *priv, 780static int fimc_m2m_querycap(struct file *file, void *fh,
781 struct v4l2_capability *cap) 781 struct v4l2_capability *cap)
782{ 782{
783 struct fimc_ctx *ctx = file->private_data; 783 struct fimc_ctx *ctx = fh_to_ctx(fh);
784 struct fimc_dev *fimc = ctx->fimc_dev; 784 struct fimc_dev *fimc = ctx->fimc_dev;
785 785
786 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1); 786 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
@@ -808,42 +808,41 @@ int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
808 return 0; 808 return 0;
809} 809}
810 810
811int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv, 811int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
812 struct v4l2_format *f)
813{ 812{
814 struct fimc_ctx *ctx = priv; 813 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
815 struct fimc_frame *frame;
816 struct v4l2_pix_format_mplane *pixm;
817 int i; 814 int i;
818 815
819 frame = ctx_get_frame(ctx, f->type); 816 pixm->width = frame->o_width;
820 if (IS_ERR(frame)) 817 pixm->height = frame->o_height;
821 return PTR_ERR(frame); 818 pixm->field = V4L2_FIELD_NONE;
822 819 pixm->pixelformat = frame->fmt->fourcc;
823 pixm = &f->fmt.pix_mp; 820 pixm->colorspace = V4L2_COLORSPACE_JPEG;
824 821 pixm->num_planes = frame->fmt->memplanes;
825 pixm->width = frame->width;
826 pixm->height = frame->height;
827 pixm->field = V4L2_FIELD_NONE;
828 pixm->pixelformat = frame->fmt->fourcc;
829 pixm->colorspace = V4L2_COLORSPACE_JPEG;
830 pixm->num_planes = frame->fmt->memplanes;
831 822
832 for (i = 0; i < pixm->num_planes; ++i) { 823 for (i = 0; i < pixm->num_planes; ++i) {
833 int bpl = frame->o_width; 824 int bpl = frame->f_width;
834
835 if (frame->fmt->colplanes == 1) /* packed formats */ 825 if (frame->fmt->colplanes == 1) /* packed formats */
836 bpl = (bpl * frame->fmt->depth[0]) / 8; 826 bpl = (bpl * frame->fmt->depth[0]) / 8;
837
838 pixm->plane_fmt[i].bytesperline = bpl; 827 pixm->plane_fmt[i].bytesperline = bpl;
839
840 pixm->plane_fmt[i].sizeimage = (frame->o_width * 828 pixm->plane_fmt[i].sizeimage = (frame->o_width *
841 frame->o_height * frame->fmt->depth[i]) / 8; 829 frame->o_height * frame->fmt->depth[i]) / 8;
842 } 830 }
843
844 return 0; 831 return 0;
845} 832}
846 833
834static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
835 struct v4l2_format *f)
836{
837 struct fimc_ctx *ctx = fh_to_ctx(fh);
838 struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
839
840 if (IS_ERR(frame))
841 return PTR_ERR(frame);
842
843 return fimc_fill_format(frame, f);
844}
845
847struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask) 846struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask)
848{ 847{
849 struct fimc_fmt *fmt; 848 struct fimc_fmt *fmt;
@@ -874,11 +873,8 @@ struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
874 return (i == ARRAY_SIZE(fimc_formats)) ? NULL : fmt; 873 return (i == ARRAY_SIZE(fimc_formats)) ? NULL : fmt;
875} 874}
876 875
877 876int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
878int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
879 struct v4l2_format *f)
880{ 877{
881 struct fimc_ctx *ctx = priv;
882 struct fimc_dev *fimc = ctx->fimc_dev; 878 struct fimc_dev *fimc = ctx->fimc_dev;
883 struct samsung_fimc_variant *variant = fimc->variant; 879 struct samsung_fimc_variant *variant = fimc->variant;
884 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; 880 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
@@ -957,17 +953,25 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
957 return 0; 953 return 0;
958} 954}
959 955
960static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, 956static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
957 struct v4l2_format *f)
958{
959 struct fimc_ctx *ctx = fh_to_ctx(fh);
960
961 return fimc_try_fmt_mplane(ctx, f);
962}
963
964static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
961 struct v4l2_format *f) 965 struct v4l2_format *f)
962{ 966{
963 struct fimc_ctx *ctx = priv; 967 struct fimc_ctx *ctx = fh_to_ctx(fh);
964 struct fimc_dev *fimc = ctx->fimc_dev; 968 struct fimc_dev *fimc = ctx->fimc_dev;
965 struct vb2_queue *vq; 969 struct vb2_queue *vq;
966 struct fimc_frame *frame; 970 struct fimc_frame *frame;
967 struct v4l2_pix_format_mplane *pix; 971 struct v4l2_pix_format_mplane *pix;
968 int i, ret = 0; 972 int i, ret = 0;
969 973
970 ret = fimc_vidioc_try_fmt_mplane(file, priv, f); 974 ret = fimc_try_fmt_mplane(ctx, f);
971 if (ret) 975 if (ret)
972 return ret; 976 return ret;
973 977
@@ -978,15 +982,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
978 return -EBUSY; 982 return -EBUSY;
979 } 983 }
980 984
981 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 985 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
982 frame = &ctx->s_frame; 986 frame = &ctx->s_frame;
983 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 987 else
984 frame = &ctx->d_frame; 988 frame = &ctx->d_frame;
985 } else {
986 v4l2_err(fimc->m2m.vfd,
987 "Wrong buffer/video queue type (%d)\n", f->type);
988 return -EINVAL;
989 }
990 989
991 pix = &f->fmt.pix_mp; 990 pix = &f->fmt.pix_mp;
992 frame->fmt = find_format(f, FMT_FLAGS_M2M); 991 frame->fmt = find_format(f, FMT_FLAGS_M2M);
@@ -1018,39 +1017,42 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
1018 return 0; 1017 return 0;
1019} 1018}
1020 1019
1021static int fimc_m2m_reqbufs(struct file *file, void *priv, 1020static int fimc_m2m_reqbufs(struct file *file, void *fh,
1022 struct v4l2_requestbuffers *reqbufs) 1021 struct v4l2_requestbuffers *reqbufs)
1023{ 1022{
1024 struct fimc_ctx *ctx = priv; 1023 struct fimc_ctx *ctx = fh_to_ctx(fh);
1024
1025 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); 1025 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
1026} 1026}
1027 1027
1028static int fimc_m2m_querybuf(struct file *file, void *priv, 1028static int fimc_m2m_querybuf(struct file *file, void *fh,
1029 struct v4l2_buffer *buf) 1029 struct v4l2_buffer *buf)
1030{ 1030{
1031 struct fimc_ctx *ctx = priv; 1031 struct fimc_ctx *ctx = fh_to_ctx(fh);
1032
1032 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); 1033 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
1033} 1034}
1034 1035
1035static int fimc_m2m_qbuf(struct file *file, void *priv, 1036static int fimc_m2m_qbuf(struct file *file, void *fh,
1036 struct v4l2_buffer *buf) 1037 struct v4l2_buffer *buf)
1037{ 1038{
1038 struct fimc_ctx *ctx = priv; 1039 struct fimc_ctx *ctx = fh_to_ctx(fh);
1039 1040
1040 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 1041 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
1041} 1042}
1042 1043
1043static int fimc_m2m_dqbuf(struct file *file, void *priv, 1044static int fimc_m2m_dqbuf(struct file *file, void *fh,
1044 struct v4l2_buffer *buf) 1045 struct v4l2_buffer *buf)
1045{ 1046{
1046 struct fimc_ctx *ctx = priv; 1047 struct fimc_ctx *ctx = fh_to_ctx(fh);
1048
1047 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 1049 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
1048} 1050}
1049 1051
1050static int fimc_m2m_streamon(struct file *file, void *priv, 1052static int fimc_m2m_streamon(struct file *file, void *fh,
1051 enum v4l2_buf_type type) 1053 enum v4l2_buf_type type)
1052{ 1054{
1053 struct fimc_ctx *ctx = priv; 1055 struct fimc_ctx *ctx = fh_to_ctx(fh);
1054 1056
1055 /* The source and target color format need to be set */ 1057 /* The source and target color format need to be set */
1056 if (V4L2_TYPE_IS_OUTPUT(type)) { 1058 if (V4L2_TYPE_IS_OUTPUT(type)) {
@@ -1063,17 +1065,19 @@ static int fimc_m2m_streamon(struct file *file, void *priv,
1063 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 1065 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
1064} 1066}
1065 1067
1066static int fimc_m2m_streamoff(struct file *file, void *priv, 1068static int fimc_m2m_streamoff(struct file *file, void *fh,
1067 enum v4l2_buf_type type) 1069 enum v4l2_buf_type type)
1068{ 1070{
1069 struct fimc_ctx *ctx = priv; 1071 struct fimc_ctx *ctx = fh_to_ctx(fh);
1072
1070 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); 1073 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
1071} 1074}
1072 1075
1073int fimc_vidioc_queryctrl(struct file *file, void *priv, 1076int fimc_vidioc_queryctrl(struct file *file, void *fh,
1074 struct v4l2_queryctrl *qc) 1077 struct v4l2_queryctrl *qc)
1075{ 1078{
1076 struct fimc_ctx *ctx = priv; 1079 struct fimc_ctx *ctx = fh_to_ctx(fh);
1080 struct fimc_dev *fimc = ctx->fimc_dev;
1077 struct v4l2_queryctrl *c; 1081 struct v4l2_queryctrl *c;
1078 int ret = -EINVAL; 1082 int ret = -EINVAL;
1079 1083
@@ -1090,10 +1094,9 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
1090 return ret; 1094 return ret;
1091} 1095}
1092 1096
1093int fimc_vidioc_g_ctrl(struct file *file, void *priv, 1097int fimc_vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
1094 struct v4l2_control *ctrl)
1095{ 1098{
1096 struct fimc_ctx *ctx = priv; 1099 struct fimc_ctx *ctx = fh_to_ctx(fh);
1097 struct fimc_dev *fimc = ctx->fimc_dev; 1100 struct fimc_dev *fimc = ctx->fimc_dev;
1098 1101
1099 switch (ctrl->id) { 1102 switch (ctrl->id) {
@@ -1186,10 +1189,10 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1186 return 0; 1189 return 0;
1187} 1190}
1188 1191
1189static int fimc_m2m_s_ctrl(struct file *file, void *priv, 1192static int fimc_m2m_s_ctrl(struct file *file, void *fh,
1190 struct v4l2_control *ctrl) 1193 struct v4l2_control *ctrl)
1191{ 1194{
1192 struct fimc_ctx *ctx = priv; 1195 struct fimc_ctx *ctx = fh_to_ctx(fh);
1193 int ret = 0; 1196 int ret = 0;
1194 1197
1195 ret = check_ctrl_val(ctx, ctrl); 1198 ret = check_ctrl_val(ctx, ctrl);
@@ -1201,10 +1204,10 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv,
1201} 1204}
1202 1205
1203static int fimc_m2m_cropcap(struct file *file, void *fh, 1206static int fimc_m2m_cropcap(struct file *file, void *fh,
1204 struct v4l2_cropcap *cr) 1207 struct v4l2_cropcap *cr)
1205{ 1208{
1209 struct fimc_ctx *ctx = fh_to_ctx(fh);
1206 struct fimc_frame *frame; 1210 struct fimc_frame *frame;
1207 struct fimc_ctx *ctx = fh;
1208 1211
1209 frame = ctx_get_frame(ctx, cr->type); 1212 frame = ctx_get_frame(ctx, cr->type);
1210 if (IS_ERR(frame)) 1213 if (IS_ERR(frame))
@@ -1221,8 +1224,8 @@ static int fimc_m2m_cropcap(struct file *file, void *fh,
1221 1224
1222static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1225static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1223{ 1226{
1227 struct fimc_ctx *ctx = fh_to_ctx(fh);
1224 struct fimc_frame *frame; 1228 struct fimc_frame *frame;
1225 struct fimc_ctx *ctx = file->private_data;
1226 1229
1227 frame = ctx_get_frame(ctx, cr->type); 1230 frame = ctx_get_frame(ctx, cr->type);
1228 if (IS_ERR(frame)) 1231 if (IS_ERR(frame))
@@ -1300,7 +1303,7 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1300 1303
1301static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1304static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1302{ 1305{
1303 struct fimc_ctx *ctx = file->private_data; 1306 struct fimc_ctx *ctx = fh_to_ctx(fh);
1304 struct fimc_dev *fimc = ctx->fimc_dev; 1307 struct fimc_dev *fimc = ctx->fimc_dev;
1305 struct fimc_frame *f; 1308 struct fimc_frame *f;
1306 int ret; 1309 int ret;
@@ -1347,11 +1350,11 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
1347 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane, 1350 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane,
1348 .vidioc_enum_fmt_vid_out_mplane = fimc_vidioc_enum_fmt_mplane, 1351 .vidioc_enum_fmt_vid_out_mplane = fimc_vidioc_enum_fmt_mplane,
1349 1352
1350 .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane, 1353 .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
1351 .vidioc_g_fmt_vid_out_mplane = fimc_vidioc_g_fmt_mplane, 1354 .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
1352 1355
1353 .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane, 1356 .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
1354 .vidioc_try_fmt_vid_out_mplane = fimc_vidioc_try_fmt_mplane, 1357 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
1355 1358
1356 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane, 1359 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
1357 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane, 1360 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
@@ -1407,7 +1410,8 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
1407static int fimc_m2m_open(struct file *file) 1410static int fimc_m2m_open(struct file *file)
1408{ 1411{
1409 struct fimc_dev *fimc = video_drvdata(file); 1412 struct fimc_dev *fimc = video_drvdata(file);
1410 struct fimc_ctx *ctx = NULL; 1413 struct fimc_ctx *ctx;
1414 int ret;
1411 1415
1412 dbg("pid: %d, state: 0x%lx, refcnt: %d", 1416 dbg("pid: %d, state: 0x%lx, refcnt: %d",
1413 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); 1417 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
@@ -1422,13 +1426,16 @@ static int fimc_m2m_open(struct file *file)
1422 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 1426 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1423 if (!ctx) 1427 if (!ctx)
1424 return -ENOMEM; 1428 return -ENOMEM;
1429 v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
1430
1431 file->private_data = &ctx->fh;
1432 v4l2_fh_add(&ctx->fh);
1425 1433
1426 file->private_data = ctx;
1427 ctx->fimc_dev = fimc; 1434 ctx->fimc_dev = fimc;
1428 /* Default color format */ 1435 /* Default color format */
1429 ctx->s_frame.fmt = &fimc_formats[0]; 1436 ctx->s_frame.fmt = &fimc_formats[0];
1430 ctx->d_frame.fmt = &fimc_formats[0]; 1437 ctx->d_frame.fmt = &fimc_formats[0];
1431 /* Setup the device context for mem2mem mode. */ 1438 /* Setup the device context for memory-to-memory mode */
1432 ctx->state = FIMC_CTX_M2M; 1439 ctx->state = FIMC_CTX_M2M;
1433 ctx->flags = 0; 1440 ctx->flags = 0;
1434 ctx->in_path = FIMC_DMA; 1441 ctx->in_path = FIMC_DMA;
@@ -1437,26 +1444,32 @@ static int fimc_m2m_open(struct file *file)
1437 1444
1438 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); 1445 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
1439 if (IS_ERR(ctx->m2m_ctx)) { 1446 if (IS_ERR(ctx->m2m_ctx)) {
1440 int err = PTR_ERR(ctx->m2m_ctx); 1447 ret = PTR_ERR(ctx->m2m_ctx);
1441 kfree(ctx); 1448 goto error_fh;
1442 return err;
1443 } 1449 }
1444 1450
1445 if (fimc->m2m.refcnt++ == 0) 1451 if (fimc->m2m.refcnt++ == 0)
1446 set_bit(ST_M2M_RUN, &fimc->state); 1452 set_bit(ST_M2M_RUN, &fimc->state);
1447
1448 return 0; 1453 return 0;
1454
1455error_fh:
1456 v4l2_fh_del(&ctx->fh);
1457 v4l2_fh_exit(&ctx->fh);
1458 kfree(ctx);
1459 return ret;
1449} 1460}
1450 1461
1451static int fimc_m2m_release(struct file *file) 1462static int fimc_m2m_release(struct file *file)
1452{ 1463{
1453 struct fimc_ctx *ctx = file->private_data; 1464 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
1454 struct fimc_dev *fimc = ctx->fimc_dev; 1465 struct fimc_dev *fimc = ctx->fimc_dev;
1455 1466
1456 dbg("pid: %d, state: 0x%lx, refcnt= %d", 1467 dbg("pid: %d, state: 0x%lx, refcnt= %d",
1457 task_pid_nr(current), fimc->state, fimc->m2m.refcnt); 1468 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
1458 1469
1459 v4l2_m2m_ctx_release(ctx->m2m_ctx); 1470 v4l2_m2m_ctx_release(ctx->m2m_ctx);
1471 v4l2_fh_del(&ctx->fh);
1472 v4l2_fh_exit(&ctx->fh);
1460 1473
1461 if (--fimc->m2m.refcnt <= 0) 1474 if (--fimc->m2m.refcnt <= 0)
1462 clear_bit(ST_M2M_RUN, &fimc->state); 1475 clear_bit(ST_M2M_RUN, &fimc->state);
@@ -1465,9 +1478,9 @@ static int fimc_m2m_release(struct file *file)
1465} 1478}
1466 1479
1467static unsigned int fimc_m2m_poll(struct file *file, 1480static unsigned int fimc_m2m_poll(struct file *file,
1468 struct poll_table_struct *wait) 1481 struct poll_table_struct *wait)
1469{ 1482{
1470 struct fimc_ctx *ctx = file->private_data; 1483 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
1471 1484
1472 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); 1485 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
1473} 1486}
@@ -1475,7 +1488,7 @@ static unsigned int fimc_m2m_poll(struct file *file,
1475 1488
1476static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) 1489static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
1477{ 1490{
1478 struct fimc_ctx *ctx = file->private_data; 1491 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
1479 1492
1480 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); 1493 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
1481} 1494}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 5a6234951e2e..22009fe6082d 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -460,6 +460,7 @@ struct fimc_dev {
460 * @state: flags to keep track of user configuration 460 * @state: flags to keep track of user configuration
461 * @fimc_dev: the FIMC device this context applies to 461 * @fimc_dev: the FIMC device this context applies to
462 * @m2m_ctx: memory-to-memory device context 462 * @m2m_ctx: memory-to-memory device context
463 * @fh: v4l2 file handle
463 */ 464 */
464struct fimc_ctx { 465struct fimc_ctx {
465 spinlock_t slock; 466 spinlock_t slock;
@@ -479,8 +480,11 @@ struct fimc_ctx {
479 u32 state; 480 u32 state;
480 struct fimc_dev *fimc_dev; 481 struct fimc_dev *fimc_dev;
481 struct v4l2_m2m_ctx *m2m_ctx; 482 struct v4l2_m2m_ctx *m2m_ctx;
483 struct v4l2_fh fh;
482}; 484};
483 485
486#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
487
484static inline bool fimc_capture_active(struct fimc_dev *fimc) 488static inline bool fimc_capture_active(struct fimc_dev *fimc)
485{ 489{
486 unsigned long flags; 490 unsigned long flags;
@@ -632,18 +636,16 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
632/* fimc-core.c */ 636/* fimc-core.c */
633int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv, 637int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
634 struct v4l2_fmtdesc *f); 638 struct v4l2_fmtdesc *f);
635int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv,
636 struct v4l2_format *f);
637int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
638 struct v4l2_format *f);
639int fimc_vidioc_queryctrl(struct file *file, void *priv, 639int fimc_vidioc_queryctrl(struct file *file, void *priv,
640 struct v4l2_queryctrl *qc); 640 struct v4l2_queryctrl *qc);
641int fimc_vidioc_g_ctrl(struct file *file, void *priv, 641int fimc_vidioc_g_ctrl(struct file *file, void *priv,
642 struct v4l2_control *ctrl); 642 struct v4l2_control *ctrl);
643 643
644int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f);
644int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr); 645int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr);
645int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl); 646int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl);
646int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl); 647int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl);
648int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
647 649
648struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask); 650struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask);
649struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, 651struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,