aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2010-12-01 08:25:18 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:36 -0400
commit8293ebfce2053242e30069e65427e7560aff1fee (patch)
tree08d6080a6ce0b82ca18cfbd4188486b66ba80827
parentef7af59b2cf950a44576d4364459ffd3d5d1d9bc (diff)
[media] s5p-fimc: Use v4l core mutex in ioctl and file operations
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>
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c208
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c115
2 files changed, 58 insertions, 265 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index e746b684c3b8..3b208f8325ae 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -406,29 +406,23 @@ static int fimc_capture_open(struct file *file)
406 if (fimc_m2m_active(fimc)) 406 if (fimc_m2m_active(fimc))
407 return -EBUSY; 407 return -EBUSY;
408 408
409 if (mutex_lock_interruptible(&fimc->lock))
410 return -ERESTARTSYS;
411
412 if (++fimc->vid_cap.refcnt == 1) { 409 if (++fimc->vid_cap.refcnt == 1) {
413 ret = fimc_isp_subdev_init(fimc, -1); 410 ret = fimc_isp_subdev_init(fimc, -1);
414 if (ret) { 411 if (ret) {
415 fimc->vid_cap.refcnt--; 412 fimc->vid_cap.refcnt--;
416 ret = -EIO; 413 return -EIO;
417 } 414 }
418 } 415 }
419 416
420 file->private_data = fimc->vid_cap.ctx; 417 file->private_data = fimc->vid_cap.ctx;
421 418
422 mutex_unlock(&fimc->lock); 419 return 0;
423 return ret;
424} 420}
425 421
426static int fimc_capture_close(struct file *file) 422static int fimc_capture_close(struct file *file)
427{ 423{
428 struct fimc_dev *fimc = video_drvdata(file); 424 struct fimc_dev *fimc = video_drvdata(file);
429 425
430 if (mutex_lock_interruptible(&fimc->lock))
431 return -ERESTARTSYS;
432 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); 426 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
433 427
434 if (--fimc->vid_cap.refcnt == 0) { 428 if (--fimc->vid_cap.refcnt == 0) {
@@ -441,7 +435,6 @@ static int fimc_capture_close(struct file *file)
441 fimc_subdev_unregister(fimc); 435 fimc_subdev_unregister(fimc);
442 } 436 }
443 437
444 mutex_unlock(&fimc->lock);
445 return 0; 438 return 0;
446} 439}
447 440
@@ -450,30 +443,16 @@ static unsigned int fimc_capture_poll(struct file *file,
450{ 443{
451 struct fimc_ctx *ctx = file->private_data; 444 struct fimc_ctx *ctx = file->private_data;
452 struct fimc_dev *fimc = ctx->fimc_dev; 445 struct fimc_dev *fimc = ctx->fimc_dev;
453 int ret;
454 446
455 if (mutex_lock_interruptible(&fimc->lock)) 447 return vb2_poll(&fimc->vid_cap.vbq, file, wait);
456 return POLLERR;
457
458 ret = vb2_poll(&fimc->vid_cap.vbq, file, wait);
459 mutex_unlock(&fimc->lock);
460
461 return ret;
462} 448}
463 449
464static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) 450static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
465{ 451{
466 struct fimc_ctx *ctx = file->private_data; 452 struct fimc_ctx *ctx = file->private_data;
467 struct fimc_dev *fimc = ctx->fimc_dev; 453 struct fimc_dev *fimc = ctx->fimc_dev;
468 int ret;
469
470 if (mutex_lock_interruptible(&fimc->lock))
471 return -ERESTARTSYS;
472 454
473 ret = vb2_mmap(&fimc->vid_cap.vbq, vma); 455 return vb2_mmap(&fimc->vid_cap.vbq, vma);
474 mutex_unlock(&fimc->lock);
475
476 return ret;
477} 456}
478 457
479/* video device file operations */ 458/* video device file operations */
@@ -555,13 +534,6 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
555 if (ret) 534 if (ret)
556 return ret; 535 return ret;
557 536
558 if (mutex_lock_interruptible(&fimc->lock))
559 return -ERESTARTSYS;
560
561 if (fimc_capture_active(fimc)) {
562 ret = -EBUSY;
563 goto sf_unlock;
564 }
565 if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) 537 if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc))
566 return -EBUSY; 538 return -EBUSY;
567 539
@@ -571,8 +543,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
571 frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM); 543 frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM);
572 if (!frame->fmt) { 544 if (!frame->fmt) {
573 err("fimc target format not found\n"); 545 err("fimc target format not found\n");
574 ret = -EINVAL; 546 return -EINVAL;
575 goto sf_unlock;
576 } 547 }
577 548
578 for (i = 0; i < frame->fmt->colplanes; i++) 549 for (i = 0; i < frame->fmt->colplanes; i++)
@@ -589,12 +560,9 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
589 frame->offs_h = 0; 560 frame->offs_h = 0;
590 frame->offs_v = 0; 561 frame->offs_v = 0;
591 562
592 ret = sync_capture_fmt(ctx);
593
594 ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT); 563 ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT);
595 564
596sf_unlock: 565 ret = sync_capture_fmt(ctx);
597 mutex_unlock(&fimc->lock);
598 return ret; 566 return ret;
599} 567}
600 568
@@ -623,21 +591,16 @@ static int fimc_cap_s_input(struct file *file, void *priv,
623 struct fimc_ctx *ctx = priv; 591 struct fimc_ctx *ctx = priv;
624 struct fimc_dev *fimc = ctx->fimc_dev; 592 struct fimc_dev *fimc = ctx->fimc_dev;
625 struct s3c_platform_fimc *pdata = fimc->pdata; 593 struct s3c_platform_fimc *pdata = fimc->pdata;
626 int ret;
627 594
628 if (fimc_capture_active(ctx->fimc_dev)) 595 if (fimc_capture_active(ctx->fimc_dev))
629 return -EBUSY; 596 return -EBUSY;
630 597
631 if (mutex_lock_interruptible(&fimc->lock)) 598 if (i >= FIMC_MAX_CAMIF_CLIENTS || !pdata->isp_info[i])
632 return -ERESTARTSYS; 599 return -EINVAL;
633 600
634 if (i >= FIMC_MAX_CAMIF_CLIENTS || !pdata->isp_info[i]) {
635 ret = -EINVAL;
636 goto si_unlock;
637 }
638 601
639 if (fimc->vid_cap.sd) { 602 if (fimc->vid_cap.sd) {
640 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 603 int ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
641 if (ret) 604 if (ret)
642 err("s_power failed: %d", ret); 605 err("s_power failed: %d", ret);
643 } 606 }
@@ -645,11 +608,7 @@ static int fimc_cap_s_input(struct file *file, void *priv,
645 /* Release the attached sensor subdevice. */ 608 /* Release the attached sensor subdevice. */
646 fimc_subdev_unregister(fimc); 609 fimc_subdev_unregister(fimc);
647 610
648 ret = fimc_isp_subdev_init(fimc, i); 611 return fimc_isp_subdev_init(fimc, i);
649
650si_unlock:
651 mutex_unlock(&fimc->lock);
652 return ret;
653} 612}
654 613
655static int fimc_cap_g_input(struct file *file, void *priv, 614static int fimc_cap_g_input(struct file *file, void *priv,
@@ -665,112 +624,41 @@ static int fimc_cap_g_input(struct file *file, void *priv,
665static int fimc_cap_streamon(struct file *file, void *priv, 624static int fimc_cap_streamon(struct file *file, void *priv,
666 enum v4l2_buf_type type) 625 enum v4l2_buf_type type)
667{ 626{
668 struct s3c_fimc_isp_info *isp_info;
669 struct fimc_ctx *ctx = priv; 627 struct fimc_ctx *ctx = priv;
670 struct fimc_dev *fimc = ctx->fimc_dev; 628 struct fimc_dev *fimc = ctx->fimc_dev;
671 int ret = -EBUSY;
672
673 if (mutex_lock_interruptible(&fimc->lock))
674 return -ERESTARTSYS;
675 629
676 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd) 630 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd)
677 goto s_unlock; 631 return -EBUSY;
678 632
679 if (!(ctx->state & FIMC_DST_FMT)) { 633 if (!(ctx->state & FIMC_DST_FMT)) {
680 v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n"); 634 v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n");
681 ret = -EINVAL; 635 return -EINVAL;
682 goto s_unlock;
683 }
684
685 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
686 if (ret && ret != -ENOIOCTLCMD)
687 goto s_unlock;
688
689 ret = fimc_prepare_config(ctx, ctx->state);
690 if (ret)
691 goto s_unlock;
692
693 isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index];
694 fimc_hw_set_camera_type(fimc, isp_info);
695 fimc_hw_set_camera_source(fimc, isp_info);
696 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
697
698 if (ctx->state & FIMC_PARAMS) {
699 ret = fimc_set_scaler_info(ctx);
700 if (ret) {
701 err("Scaler setup error");
702 goto s_unlock;
703 }
704 fimc_hw_set_input_path(ctx);
705 fimc_hw_set_scaler(ctx);
706 fimc_hw_set_target_format(ctx);
707 fimc_hw_set_rotation(ctx);
708 fimc_hw_set_effect(ctx);
709 } 636 }
710 637
711 fimc_hw_set_output_path(ctx); 638 return vb2_streamon(&fimc->vid_cap.vbq, type);
712 fimc_hw_set_out_dma(ctx);
713
714 INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
715 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
716 fimc->vid_cap.active_buf_cnt = 0;
717 fimc->vid_cap.frame_count = 0;
718 fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
719
720 set_bit(ST_CAPT_PEND, &fimc->state);
721 ret = vb2_streamon(&fimc->vid_cap.vbq, type);
722
723s_unlock:
724 mutex_unlock(&fimc->lock);
725 return ret;
726} 639}
727 640
728static int fimc_cap_streamoff(struct file *file, void *priv, 641static int fimc_cap_streamoff(struct file *file, void *priv,
729 enum v4l2_buf_type type) 642 enum v4l2_buf_type type)
730{ 643{
731 struct fimc_ctx *ctx = priv; 644 struct fimc_ctx *ctx = priv;
732 struct fimc_dev *fimc = ctx->fimc_dev; 645 struct fimc_dev *fimc = ctx->fimc_dev;
733 struct fimc_vid_cap *cap = &fimc->vid_cap;
734 unsigned long flags;
735 int ret;
736
737 spin_lock_irqsave(&fimc->slock, flags);
738 if (!fimc_capture_running(fimc) && !fimc_capture_pending(fimc)) {
739 spin_unlock_irqrestore(&fimc->slock, flags);
740 dbg("state: 0x%lx", fimc->state);
741 return -EINVAL;
742 }
743 spin_unlock_irqrestore(&fimc->slock, flags);
744
745 if (mutex_lock_interruptible(&fimc->lock))
746 return -ERESTARTSYS;
747 646
748 fimc_stop_capture(fimc); 647 return vb2_streamoff(&fimc->vid_cap.vbq, type);
749 ret = vb2_streamoff(&cap->vbq, type);
750
751 mutex_unlock(&fimc->lock);
752 return ret;
753} 648}
754 649
755static int fimc_cap_reqbufs(struct file *file, void *priv, 650static int fimc_cap_reqbufs(struct file *file, void *priv,
756 struct v4l2_requestbuffers *reqbufs) 651 struct v4l2_requestbuffers *reqbufs)
757{ 652{
758 struct fimc_ctx *ctx = priv; 653 struct fimc_ctx *ctx = priv;
759 struct fimc_dev *fimc = ctx->fimc_dev; 654 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
760 struct fimc_vid_cap *cap = &fimc->vid_cap;
761 int ret; 655 int ret;
762 656
763 if (fimc_capture_active(ctx->fimc_dev))
764 return -EBUSY;
765
766 if (mutex_lock_interruptible(&fimc->lock))
767 return -ERESTARTSYS;
768 657
769 ret = vb2_reqbufs(&cap->vbq, reqbufs); 658 ret = vb2_reqbufs(&cap->vbq, reqbufs);
770 if (!ret) 659 if (!ret)
771 cap->reqbufs_count = reqbufs->count; 660 cap->reqbufs_count = reqbufs->count;
772 661
773 mutex_unlock(&fimc->lock);
774 return ret; 662 return ret;
775} 663}
776 664
@@ -780,9 +668,6 @@ static int fimc_cap_querybuf(struct file *file, void *priv,
780 struct fimc_ctx *ctx = priv; 668 struct fimc_ctx *ctx = priv;
781 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; 669 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
782 670
783 if (fimc_capture_active(ctx->fimc_dev))
784 return -EBUSY;
785
786 return vb2_querybuf(&cap->vbq, buf); 671 return vb2_querybuf(&cap->vbq, buf);
787} 672}
788 673
@@ -790,33 +675,16 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
790 struct v4l2_buffer *buf) 675 struct v4l2_buffer *buf)
791{ 676{
792 struct fimc_ctx *ctx = priv; 677 struct fimc_ctx *ctx = priv;
793 struct fimc_dev *fimc = ctx->fimc_dev; 678 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
794 struct fimc_vid_cap *cap = &fimc->vid_cap; 679 return vb2_qbuf(&cap->vbq, buf);
795 int ret;
796
797 if (mutex_lock_interruptible(&fimc->lock))
798 return -ERESTARTSYS;
799
800 ret = vb2_qbuf(&cap->vbq, buf);
801
802 mutex_unlock(&fimc->lock);
803 return ret;
804} 680}
805 681
806static int fimc_cap_dqbuf(struct file *file, void *priv, 682static int fimc_cap_dqbuf(struct file *file, void *priv,
807 struct v4l2_buffer *buf) 683 struct v4l2_buffer *buf)
808{ 684{
809 struct fimc_ctx *ctx = priv; 685 struct fimc_ctx *ctx = priv;
810 int ret; 686 return vb2_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf,
811
812 if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
813 return -ERESTARTSYS;
814
815 ret = vb2_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf,
816 file->f_flags & O_NONBLOCK); 687 file->f_flags & O_NONBLOCK);
817
818 mutex_unlock(&ctx->fimc_dev->lock);
819 return ret;
820} 688}
821 689
822static int fimc_cap_s_ctrl(struct file *file, void *priv, 690static int fimc_cap_s_ctrl(struct file *file, void *priv,
@@ -825,9 +693,6 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
825 struct fimc_ctx *ctx = priv; 693 struct fimc_ctx *ctx = priv;
826 int ret = -EINVAL; 694 int ret = -EINVAL;
827 695
828 if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
829 return -ERESTARTSYS;
830
831 /* Allow any controls but 90/270 rotation while streaming */ 696 /* Allow any controls but 90/270 rotation while streaming */
832 if (!fimc_capture_active(ctx->fimc_dev) || 697 if (!fimc_capture_active(ctx->fimc_dev) ||
833 ctrl->id != V4L2_CID_ROTATE || 698 ctrl->id != V4L2_CID_ROTATE ||
@@ -842,8 +707,6 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
842 if (ret == -EINVAL) 707 if (ret == -EINVAL)
843 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, 708 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
844 core, s_ctrl, ctrl); 709 core, s_ctrl, ctrl);
845
846 mutex_unlock(&ctx->fimc_dev->lock);
847 return ret; 710 return ret;
848} 711}
849 712
@@ -852,13 +715,10 @@ static int fimc_cap_cropcap(struct file *file, void *fh,
852{ 715{
853 struct fimc_frame *f; 716 struct fimc_frame *f;
854 struct fimc_ctx *ctx = fh; 717 struct fimc_ctx *ctx = fh;
855 struct fimc_dev *fimc = ctx->fimc_dev;
856 718
857 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 719 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
858 return -EINVAL; 720 return -EINVAL;
859 721
860 if (mutex_lock_interruptible(&fimc->lock))
861 return -ERESTARTSYS;
862 f = &ctx->s_frame; 722 f = &ctx->s_frame;
863 723
864 cr->bounds.left = 0; 724 cr->bounds.left = 0;
@@ -867,7 +727,6 @@ static int fimc_cap_cropcap(struct file *file, void *fh,
867 cr->bounds.height = f->o_height; 727 cr->bounds.height = f->o_height;
868 cr->defrect = cr->bounds; 728 cr->defrect = cr->bounds;
869 729
870 mutex_unlock(&fimc->lock);
871 return 0; 730 return 0;
872} 731}
873 732
@@ -875,19 +734,14 @@ static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
875{ 734{
876 struct fimc_frame *f; 735 struct fimc_frame *f;
877 struct fimc_ctx *ctx = file->private_data; 736 struct fimc_ctx *ctx = file->private_data;
878 struct fimc_dev *fimc = ctx->fimc_dev;
879
880
881 if (mutex_lock_interruptible(&fimc->lock))
882 return -ERESTARTSYS;
883 737
884 f = &ctx->s_frame; 738 f = &ctx->s_frame;
739
885 cr->c.left = f->offs_h; 740 cr->c.left = f->offs_h;
886 cr->c.top = f->offs_v; 741 cr->c.top = f->offs_v;
887 cr->c.width = f->width; 742 cr->c.width = f->width;
888 cr->c.height = f->height; 743 cr->c.height = f->height;
889 744
890 mutex_unlock(&fimc->lock);
891 return 0; 745 return 0;
892} 746}
893 747
@@ -906,13 +760,10 @@ static int fimc_cap_s_crop(struct file *file, void *fh,
906 if (ret) 760 if (ret)
907 return ret; 761 return ret;
908 762
909 if (mutex_lock_interruptible(&fimc->lock))
910 return -ERESTARTSYS;
911
912 if (!(ctx->state & FIMC_DST_FMT)) { 763 if (!(ctx->state & FIMC_DST_FMT)) {
913 v4l2_err(&fimc->vid_cap.v4l2_dev, 764 v4l2_err(&fimc->vid_cap.v4l2_dev,
914 "Capture color format not set\n"); 765 "Capture color format not set\n");
915 goto sc_unlock; 766 return -EINVAL; /* TODO: make sure this is the right value */
916 } 767 }
917 768
918 f = &ctx->s_frame; 769 f = &ctx->s_frame;
@@ -920,17 +771,15 @@ static int fimc_cap_s_crop(struct file *file, void *fh,
920 ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); 771 ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame);
921 if (ret) { 772 if (ret) {
922 v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); 773 v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range");
923 } else { 774 return ret;
924 ret = 0;
925 f->offs_h = cr->c.left;
926 f->offs_v = cr->c.top;
927 f->width = cr->c.width;
928 f->height = cr->c.height;
929 } 775 }
930 776
931sc_unlock: 777 f->offs_h = cr->c.left;
932 mutex_unlock(&fimc->lock); 778 f->offs_v = cr->c.top;
933 return ret; 779 f->width = cr->c.width;
780 f->height = cr->c.height;
781
782 return 0;
934} 783}
935 784
936 785
@@ -1013,6 +862,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
1013 vfd->ioctl_ops = &fimc_capture_ioctl_ops; 862 vfd->ioctl_ops = &fimc_capture_ioctl_ops;
1014 vfd->minor = -1; 863 vfd->minor = -1;
1015 vfd->release = video_device_release; 864 vfd->release = video_device_release;
865 vfd->lock = &fimc->lock;
1016 video_set_drvdata(vfd, fimc); 866 video_set_drvdata(vfd, fimc);
1017 867
1018 vid_cap = &fimc->vid_cap; 868 vid_cap = &fimc->vid_cap;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index fe210976f30b..9ebb92530053 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -741,22 +741,17 @@ int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv,
741 struct v4l2_format *f) 741 struct v4l2_format *f)
742{ 742{
743 struct fimc_ctx *ctx = priv; 743 struct fimc_ctx *ctx = priv;
744 struct fimc_dev *fimc = ctx->fimc_dev;
745 struct fimc_frame *frame; 744 struct fimc_frame *frame;
746 745
747 frame = ctx_get_frame(ctx, f->type); 746 frame = ctx_get_frame(ctx, f->type);
748 if (IS_ERR(frame)) 747 if (IS_ERR(frame))
749 return PTR_ERR(frame); 748 return PTR_ERR(frame);
750 749
751 if (mutex_lock_interruptible(&fimc->lock))
752 return -ERESTARTSYS;
753
754 f->fmt.pix.width = frame->width; 750 f->fmt.pix.width = frame->width;
755 f->fmt.pix.height = frame->height; 751 f->fmt.pix.height = frame->height;
756 f->fmt.pix.field = V4L2_FIELD_NONE; 752 f->fmt.pix.field = V4L2_FIELD_NONE;
757 f->fmt.pix.pixelformat = frame->fmt->fourcc; 753 f->fmt.pix.pixelformat = frame->fmt->fourcc;
758 754
759 mutex_unlock(&fimc->lock);
760 return 0; 755 return 0;
761} 756}
762 757
@@ -800,7 +795,8 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
800 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; 795 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
801 struct fimc_fmt *fmt; 796 struct fimc_fmt *fmt;
802 u32 max_width, mod_x, mod_y, mask; 797 u32 max_width, mod_x, mod_y, mask;
803 int ret, i, is_output = 0; 798 int i, is_output = 0;
799
804 800
805 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 801 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
806 if (ctx->state & FIMC_CTX_CAP) 802 if (ctx->state & FIMC_CTX_CAP)
@@ -810,8 +806,6 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
810 return -EINVAL; 806 return -EINVAL;
811 } 807 }
812 808
813 if (mutex_lock_interruptible(&fimc->lock))
814 return -ERESTARTSYS;
815 dbg("w: %d, h: %d", pix->width, pix->height); 809 dbg("w: %d, h: %d", pix->width, pix->height);
816 810
817 mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM; 811 mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM;
@@ -819,13 +813,13 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
819 if (!fmt) { 813 if (!fmt) {
820 v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n", 814 v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n",
821 pix->pixelformat); 815 pix->pixelformat);
822 goto tf_out; 816 return -EINVAL;
823 } 817 }
824 818
825 if (pix->field == V4L2_FIELD_ANY) 819 if (pix->field == V4L2_FIELD_ANY)
826 pix->field = V4L2_FIELD_NONE; 820 pix->field = V4L2_FIELD_NONE;
827 else if (V4L2_FIELD_NONE != pix->field) 821 else if (V4L2_FIELD_NONE != pix->field)
828 goto tf_out; 822 return -EINVAL;
829 823
830 if (is_output) { 824 if (is_output) {
831 max_width = variant->pix_limit->scaler_dis_w; 825 max_width = variant->pix_limit->scaler_dis_w;
@@ -871,11 +865,7 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
871 pix->plane_fmt[i].sizeimage); 865 pix->plane_fmt[i].sizeimage);
872 } 866 }
873 867
874 ret = 0; 868 return 0;
875
876tf_out:
877 mutex_unlock(&fimc->lock);
878 return ret;
879} 869}
880 870
881static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, 871static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
@@ -888,45 +878,33 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
888 struct v4l2_pix_format_mplane *pix; 878 struct v4l2_pix_format_mplane *pix;
889 unsigned long flags; 879 unsigned long flags;
890 int i, ret = 0; 880 int i, ret = 0;
881 u32 tmp;
891 882
892 ret = fimc_vidioc_try_fmt_mplane(file, priv, f); 883 ret = fimc_vidioc_try_fmt_mplane(file, priv, f);
893 if (ret) 884 if (ret)
894 return ret; 885 return ret;
895 886
896 if (mutex_lock_interruptible(&fimc->lock))
897 return -ERESTARTSYS;
898
899 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 887 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
900 888
901 if (vb2_is_streaming(vq)) { 889 if (vb2_is_streaming(vq)) {
902 v4l2_err(&fimc->vid_cap.v4l2_dev, "%s: queue (%d) busy\n", 890 v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type);
903 __func__, f->type); 891 return -EBUSY;
904 ret = -EBUSY;
905 goto sf_out;
906 } 892 }
907 893
908 spin_lock_irqsave(&ctx->slock, flags);
909 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 894 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
910 frame = &ctx->s_frame; 895 frame = &ctx->s_frame;
911 ctx->state |= FIMC_SRC_FMT;
912 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 896 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
913 frame = &ctx->d_frame; 897 frame = &ctx->d_frame;
914 ctx->state |= FIMC_DST_FMT;
915 } else { 898 } else {
916 spin_unlock_irqrestore(&ctx->slock, flags);
917 v4l2_err(&fimc->m2m.v4l2_dev, 899 v4l2_err(&fimc->m2m.v4l2_dev,
918 "Wrong buffer/video queue type (%d)\n", f->type); 900 "Wrong buffer/video queue type (%d)\n", f->type);
919 ret = -EINVAL; 901 return -EINVAL;
920 goto sf_out;
921 } 902 }
922 spin_unlock_irqrestore(&ctx->slock, flags);
923 903
924 pix = &f->fmt.pix_mp; 904 pix = &f->fmt.pix_mp;
925 frame->fmt = find_format(f, FMT_FLAGS_M2M); 905 frame->fmt = find_format(f, FMT_FLAGS_M2M);
926 if (!frame->fmt) { 906 if (!frame->fmt)
927 ret = -EINVAL; 907 return -EINVAL;
928 goto sf_out;
929 }
930 908
931 for (i = 0; i < frame->fmt->colplanes; i++) 909 for (i = 0; i < frame->fmt->colplanes; i++)
932 frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; 910 frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
@@ -942,14 +920,13 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
942 frame->offs_v = 0; 920 frame->offs_v = 0;
943 921
944 spin_lock_irqsave(&ctx->slock, flags); 922 spin_lock_irqsave(&ctx->slock, flags);
945 ctx->state |= FIMC_PARAMS; 923 tmp = (frame == &ctx->d_frame) ? FIMC_DST_FMT : FIMC_SRC_FMT;
924 ctx->state |= FIMC_PARAMS | tmp;
946 spin_unlock_irqrestore(&ctx->slock, flags); 925 spin_unlock_irqrestore(&ctx->slock, flags);
947 926
948 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); 927 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
949 928
950sf_out: 929 return 0;
951 mutex_unlock(&fimc->lock);
952 return ret;
953} 930}
954 931
955static int fimc_m2m_reqbufs(struct file *file, void *priv, 932static int fimc_m2m_reqbufs(struct file *file, void *priv,
@@ -1018,11 +995,8 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
1018 } 995 }
1019 996
1020 if (ctx->state & FIMC_CTX_CAP) { 997 if (ctx->state & FIMC_CTX_CAP) {
1021 if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) 998 return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
1022 return -ERESTARTSYS;
1023 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
1024 core, queryctrl, qc); 999 core, queryctrl, qc);
1025 mutex_unlock(&ctx->fimc_dev->lock);
1026 } 1000 }
1027 return ret; 1001 return ret;
1028} 1002}
@@ -1032,10 +1006,6 @@ int fimc_vidioc_g_ctrl(struct file *file, void *priv,
1032{ 1006{
1033 struct fimc_ctx *ctx = priv; 1007 struct fimc_ctx *ctx = priv;
1034 struct fimc_dev *fimc = ctx->fimc_dev; 1008 struct fimc_dev *fimc = ctx->fimc_dev;
1035 int ret = 0;
1036
1037 if (mutex_lock_interruptible(&fimc->lock))
1038 return -ERESTARTSYS;
1039 1009
1040 switch (ctrl->id) { 1010 switch (ctrl->id) {
1041 case V4L2_CID_HFLIP: 1011 case V4L2_CID_HFLIP:
@@ -1049,18 +1019,17 @@ int fimc_vidioc_g_ctrl(struct file *file, void *priv,
1049 break; 1019 break;
1050 default: 1020 default:
1051 if (ctx->state & FIMC_CTX_CAP) { 1021 if (ctx->state & FIMC_CTX_CAP) {
1052 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, 1022 return v4l2_subdev_call(fimc->vid_cap.sd, core,
1053 g_ctrl, ctrl); 1023 g_ctrl, ctrl);
1054 } else { 1024 } else {
1055 v4l2_err(&fimc->m2m.v4l2_dev, 1025 v4l2_err(&fimc->m2m.v4l2_dev,
1056 "Invalid control\n"); 1026 "Invalid control\n");
1057 ret = -EINVAL; 1027 return -EINVAL;
1058 } 1028 }
1059 } 1029 }
1060 dbg("ctrl->value= %d", ctrl->value); 1030 dbg("ctrl->value= %d", ctrl->value);
1061 1031
1062 mutex_unlock(&fimc->lock); 1032 return 0;
1063 return ret;
1064} 1033}
1065 1034
1066int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl) 1035int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
@@ -1151,22 +1120,17 @@ static int fimc_m2m_cropcap(struct file *file, void *fh,
1151{ 1120{
1152 struct fimc_frame *frame; 1121 struct fimc_frame *frame;
1153 struct fimc_ctx *ctx = fh; 1122 struct fimc_ctx *ctx = fh;
1154 struct fimc_dev *fimc = ctx->fimc_dev;
1155 1123
1156 frame = ctx_get_frame(ctx, cr->type); 1124 frame = ctx_get_frame(ctx, cr->type);
1157 if (IS_ERR(frame)) 1125 if (IS_ERR(frame))
1158 return PTR_ERR(frame); 1126 return PTR_ERR(frame);
1159 1127
1160 if (mutex_lock_interruptible(&fimc->lock))
1161 return -ERESTARTSYS;
1162
1163 cr->bounds.left = 0; 1128 cr->bounds.left = 0;
1164 cr->bounds.top = 0; 1129 cr->bounds.top = 0;
1165 cr->bounds.width = frame->f_width; 1130 cr->bounds.width = frame->f_width;
1166 cr->bounds.height = frame->f_height; 1131 cr->bounds.height = frame->f_height;
1167 cr->defrect = cr->bounds; 1132 cr->defrect = cr->bounds;
1168 1133
1169 mutex_unlock(&fimc->lock);
1170 return 0; 1134 return 0;
1171} 1135}
1172 1136
@@ -1174,21 +1138,16 @@ static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1174{ 1138{
1175 struct fimc_frame *frame; 1139 struct fimc_frame *frame;
1176 struct fimc_ctx *ctx = file->private_data; 1140 struct fimc_ctx *ctx = file->private_data;
1177 struct fimc_dev *fimc = ctx->fimc_dev;
1178 1141
1179 frame = ctx_get_frame(ctx, cr->type); 1142 frame = ctx_get_frame(ctx, cr->type);
1180 if (IS_ERR(frame)) 1143 if (IS_ERR(frame))
1181 return PTR_ERR(frame); 1144 return PTR_ERR(frame);
1182 1145
1183 if (mutex_lock_interruptible(&fimc->lock))
1184 return -ERESTARTSYS;
1185
1186 cr->c.left = frame->offs_h; 1146 cr->c.left = frame->offs_h;
1187 cr->c.top = frame->offs_v; 1147 cr->c.top = frame->offs_v;
1188 cr->c.width = frame->width; 1148 cr->c.width = frame->width;
1189 cr->c.height = frame->height; 1149 cr->c.height = frame->height;
1190 1150
1191 mutex_unlock(&fimc->lock);
1192 return 0; 1151 return 0;
1193} 1152}
1194 1153
@@ -1268,9 +1227,6 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1268 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? 1227 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
1269 &ctx->s_frame : &ctx->d_frame; 1228 &ctx->s_frame : &ctx->d_frame;
1270 1229
1271 if (mutex_lock_interruptible(&fimc->lock))
1272 return -ERESTARTSYS;
1273
1274 spin_lock_irqsave(&ctx->slock, flags); 1230 spin_lock_irqsave(&ctx->slock, flags);
1275 if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { 1231 if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) {
1276 /* Check to see if scaling ratio is within supported range */ 1232 /* Check to see if scaling ratio is within supported range */
@@ -1280,8 +1236,8 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1280 ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); 1236 ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame);
1281 if (ret) { 1237 if (ret) {
1282 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); 1238 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range");
1283 ret = -EINVAL; 1239 spin_unlock_irqrestore(&ctx->slock, flags);
1284 goto scr_unlock; 1240 return -EINVAL;
1285 } 1241 }
1286 } 1242 }
1287 ctx->state |= FIMC_PARAMS; 1243 ctx->state |= FIMC_PARAMS;
@@ -1291,9 +1247,7 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1291 f->width = cr->c.width; 1247 f->width = cr->c.width;
1292 f->height = cr->c.height; 1248 f->height = cr->c.height;
1293 1249
1294scr_unlock:
1295 spin_unlock_irqrestore(&ctx->slock, flags); 1250 spin_unlock_irqrestore(&ctx->slock, flags);
1296 mutex_unlock(&fimc->lock);
1297 return 0; 1251 return 0;
1298} 1252}
1299 1253
@@ -1364,10 +1318,6 @@ static int fimc_m2m_open(struct file *file)
1364{ 1318{
1365 struct fimc_dev *fimc = video_drvdata(file); 1319 struct fimc_dev *fimc = video_drvdata(file);
1366 struct fimc_ctx *ctx = NULL; 1320 struct fimc_ctx *ctx = NULL;
1367 int err = 0;
1368
1369 if (mutex_lock_interruptible(&fimc->lock))
1370 return -ERESTARTSYS;
1371 1321
1372 dbg("pid: %d, state: 0x%lx, refcnt: %d", 1322 dbg("pid: %d, state: 0x%lx, refcnt: %d",
1373 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); 1323 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
@@ -1376,19 +1326,15 @@ static int fimc_m2m_open(struct file *file)
1376 * Return if the corresponding video capture node 1326 * Return if the corresponding video capture node
1377 * is already opened. 1327 * is already opened.
1378 */ 1328 */
1379 if (fimc->vid_cap.refcnt > 0) { 1329 if (fimc->vid_cap.refcnt > 0)
1380 err = -EBUSY; 1330 return -EBUSY;
1381 goto err_unlock;
1382 }
1383 1331
1384 fimc->m2m.refcnt++; 1332 fimc->m2m.refcnt++;
1385 set_bit(ST_OUTDMA_RUN, &fimc->state); 1333 set_bit(ST_OUTDMA_RUN, &fimc->state);
1386 1334
1387 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 1335 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1388 if (!ctx) { 1336 if (!ctx)
1389 err = -ENOMEM; 1337 return -ENOMEM;
1390 goto err_unlock;
1391 }
1392 1338
1393 file->private_data = ctx; 1339 file->private_data = ctx;
1394 ctx->fimc_dev = fimc; 1340 ctx->fimc_dev = fimc;
@@ -1404,13 +1350,12 @@ static int fimc_m2m_open(struct file *file)
1404 1350
1405 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); 1351 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
1406 if (IS_ERR(ctx->m2m_ctx)) { 1352 if (IS_ERR(ctx->m2m_ctx)) {
1407 err = PTR_ERR(ctx->m2m_ctx); 1353 int err = PTR_ERR(ctx->m2m_ctx);
1408 kfree(ctx); 1354 kfree(ctx);
1355 return err;
1409 } 1356 }
1410 1357
1411err_unlock: 1358 return 0;
1412 mutex_unlock(&fimc->lock);
1413 return err;
1414} 1359}
1415 1360
1416static int fimc_m2m_release(struct file *file) 1361static int fimc_m2m_release(struct file *file)
@@ -1418,8 +1363,6 @@ static int fimc_m2m_release(struct file *file)
1418 struct fimc_ctx *ctx = file->private_data; 1363 struct fimc_ctx *ctx = file->private_data;
1419 struct fimc_dev *fimc = ctx->fimc_dev; 1364 struct fimc_dev *fimc = ctx->fimc_dev;
1420 1365
1421 mutex_lock(&fimc->lock);
1422
1423 dbg("pid: %d, state: 0x%lx, refcnt= %d", 1366 dbg("pid: %d, state: 0x%lx, refcnt= %d",
1424 task_pid_nr(current), fimc->state, fimc->m2m.refcnt); 1367 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
1425 1368
@@ -1428,7 +1371,6 @@ static int fimc_m2m_release(struct file *file)
1428 if (--fimc->m2m.refcnt <= 0) 1371 if (--fimc->m2m.refcnt <= 0)
1429 clear_bit(ST_OUTDMA_RUN, &fimc->state); 1372 clear_bit(ST_OUTDMA_RUN, &fimc->state);
1430 1373
1431 mutex_unlock(&fimc->lock);
1432 return 0; 1374 return 0;
1433} 1375}
1434 1376
@@ -1494,6 +1436,7 @@ static int fimc_register_m2m_device(struct fimc_dev *fimc)
1494 vfd->ioctl_ops = &fimc_m2m_ioctl_ops; 1436 vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
1495 vfd->minor = -1; 1437 vfd->minor = -1;
1496 vfd->release = video_device_release; 1438 vfd->release = video_device_release;
1439 vfd->lock = &fimc->lock;
1497 1440
1498 snprintf(vfd->name, sizeof(vfd->name), "%s:m2m", dev_name(&pdev->dev)); 1441 snprintf(vfd->name, sizeof(vfd->name), "%s:m2m", dev_name(&pdev->dev));
1499 1442