aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-fimc/fimc-capture.c
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 /drivers/media/video/s5p-fimc/fimc-capture.c
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>
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-capture.c')
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c208
1 files changed, 29 insertions, 179 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;