aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-fimc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/s5p-fimc')
-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,