aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2012-06-27 08:56:17 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 18:22:44 -0400
commitc2d430af08f38a0b3145c3b60381146b8ac88c88 (patch)
treea63e00cf263b47d7c9e8648cc5af27d8c74b0184
parent837c7e4256d5285700fe0d500eeb15801b55bb0e (diff)
[media] s5p-fimc: Remove V4L2_FL_LOCK_ALL_FOPS flag
This patch adds locking for open(), close(), poll() and mmap() file operations in the driver as a follow up to the changes done in commit 5126f2590bee412e3053de851cb07f531 "v4l2-dev: add flag to have the core lock all 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.c78
-rw-r--r--drivers/media/video/s5p-fimc/fimc-m2m.c45
2 files changed, 87 insertions, 36 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 6a34183564d2..8e413dd3c0b0 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -480,48 +480,59 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc);
480static int fimc_capture_open(struct file *file) 480static int fimc_capture_open(struct file *file)
481{ 481{
482 struct fimc_dev *fimc = video_drvdata(file); 482 struct fimc_dev *fimc = video_drvdata(file);
483 int ret; 483 int ret = -EBUSY;
484 484
485 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); 485 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
486 486
487 if (mutex_lock_interruptible(&fimc->lock))
488 return -ERESTARTSYS;
489
487 if (fimc_m2m_active(fimc)) 490 if (fimc_m2m_active(fimc))
488 return -EBUSY; 491 goto unlock;
489 492
490 set_bit(ST_CAPT_BUSY, &fimc->state); 493 set_bit(ST_CAPT_BUSY, &fimc->state);
491 ret = pm_runtime_get_sync(&fimc->pdev->dev); 494 ret = pm_runtime_get_sync(&fimc->pdev->dev);
492 if (ret < 0) 495 if (ret < 0)
493 return ret; 496 goto unlock;
494 497
495 ret = v4l2_fh_open(file); 498 ret = v4l2_fh_open(file);
496 if (ret) 499 if (ret) {
497 return ret; 500 pm_runtime_put(&fimc->pdev->dev);
498 501 goto unlock;
499 if (++fimc->vid_cap.refcnt != 1) 502 }
500 return 0;
501 503
502 ret = fimc_pipeline_initialize(&fimc->pipeline, 504 if (++fimc->vid_cap.refcnt == 1) {
505 ret = fimc_pipeline_initialize(&fimc->pipeline,
503 &fimc->vid_cap.vfd->entity, true); 506 &fimc->vid_cap.vfd->entity, true);
504 if (ret < 0) {
505 clear_bit(ST_CAPT_BUSY, &fimc->state);
506 pm_runtime_put_sync(&fimc->pdev->dev);
507 fimc->vid_cap.refcnt--;
508 v4l2_fh_release(file);
509 return ret;
510 }
511 ret = fimc_capture_ctrls_create(fimc);
512 507
513 if (!ret && !fimc->vid_cap.user_subdev_api) 508 if (!ret && !fimc->vid_cap.user_subdev_api)
514 ret = fimc_capture_set_default_format(fimc); 509 ret = fimc_capture_set_default_format(fimc);
510
511 if (!ret)
512 ret = fimc_capture_ctrls_create(fimc);
515 513
514 if (ret < 0) {
515 clear_bit(ST_CAPT_BUSY, &fimc->state);
516 pm_runtime_put_sync(&fimc->pdev->dev);
517 fimc->vid_cap.refcnt--;
518 v4l2_fh_release(file);
519 }
520 }
521unlock:
522 mutex_unlock(&fimc->lock);
516 return ret; 523 return ret;
517} 524}
518 525
519static int fimc_capture_close(struct file *file) 526static int fimc_capture_close(struct file *file)
520{ 527{
521 struct fimc_dev *fimc = video_drvdata(file); 528 struct fimc_dev *fimc = video_drvdata(file);
529 int ret;
522 530
523 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); 531 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
524 532
533 if (mutex_lock_interruptible(&fimc->lock))
534 return -ERESTARTSYS;
535
525 if (--fimc->vid_cap.refcnt == 0) { 536 if (--fimc->vid_cap.refcnt == 0) {
526 clear_bit(ST_CAPT_BUSY, &fimc->state); 537 clear_bit(ST_CAPT_BUSY, &fimc->state);
527 fimc_stop_capture(fimc, false); 538 fimc_stop_capture(fimc, false);
@@ -535,22 +546,40 @@ static int fimc_capture_close(struct file *file)
535 vb2_queue_release(&fimc->vid_cap.vbq); 546 vb2_queue_release(&fimc->vid_cap.vbq);
536 fimc_ctrls_delete(fimc->vid_cap.ctx); 547 fimc_ctrls_delete(fimc->vid_cap.ctx);
537 } 548 }
538 return v4l2_fh_release(file); 549
550 ret = v4l2_fh_release(file);
551
552 mutex_unlock(&fimc->lock);
553 return ret;
539} 554}
540 555
541static unsigned int fimc_capture_poll(struct file *file, 556static unsigned int fimc_capture_poll(struct file *file,
542 struct poll_table_struct *wait) 557 struct poll_table_struct *wait)
543{ 558{
544 struct fimc_dev *fimc = video_drvdata(file); 559 struct fimc_dev *fimc = video_drvdata(file);
560 int ret;
545 561
546 return vb2_poll(&fimc->vid_cap.vbq, file, wait); 562 if (mutex_lock_interruptible(&fimc->lock))
563 return POLL_ERR;
564
565 ret = vb2_poll(&fimc->vid_cap.vbq, file, wait);
566 mutex_unlock(&fimc->lock);
567
568 return ret;
547} 569}
548 570
549static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) 571static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
550{ 572{
551 struct fimc_dev *fimc = video_drvdata(file); 573 struct fimc_dev *fimc = video_drvdata(file);
574 int ret;
575
576 if (mutex_lock_interruptible(&fimc->lock))
577 return -ERESTARTSYS;
552 578
553 return vb2_mmap(&fimc->vid_cap.vbq, vma); 579 ret = vb2_mmap(&fimc->vid_cap.vbq, vma);
580 mutex_unlock(&fimc->lock);
581
582 return ret;
554} 583}
555 584
556static const struct v4l2_file_operations fimc_capture_fops = { 585static const struct v4l2_file_operations fimc_capture_fops = {
@@ -1589,10 +1618,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
1589 vfd->minor = -1; 1618 vfd->minor = -1;
1590 vfd->release = video_device_release; 1619 vfd->release = video_device_release;
1591 vfd->lock = &fimc->lock; 1620 vfd->lock = &fimc->lock;
1592 /* Locking in file operations other than ioctl should be done 1621
1593 by the driver, not the V4L2 core.
1594 This driver needs auditing so that this flag can be removed. */
1595 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
1596 video_set_drvdata(vfd, fimc); 1622 video_set_drvdata(vfd, fimc);
1597 1623
1598 vid_cap = &fimc->vid_cap; 1624 vid_cap = &fimc->vid_cap;
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c
index 4c58e0570962..41eda2e27488 100644
--- a/drivers/media/video/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/video/s5p-fimc/fimc-m2m.c
@@ -642,21 +642,25 @@ static int fimc_m2m_open(struct file *file)
642{ 642{
643 struct fimc_dev *fimc = video_drvdata(file); 643 struct fimc_dev *fimc = video_drvdata(file);
644 struct fimc_ctx *ctx; 644 struct fimc_ctx *ctx;
645 int ret; 645 int ret = -EBUSY;
646 646
647 dbg("pid: %d, state: 0x%lx, refcnt: %d", 647 dbg("pid: %d, state: 0x%lx, refcnt: %d",
648 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); 648 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
649 649
650 if (mutex_lock_interruptible(&fimc->lock))
651 return -ERESTARTSYS;
650 /* 652 /*
651 * Return if the corresponding video capture node 653 * Return if the corresponding video capture node
652 * is already opened. 654 * is already opened.
653 */ 655 */
654 if (fimc->vid_cap.refcnt > 0) 656 if (fimc->vid_cap.refcnt > 0)
655 return -EBUSY; 657 goto unlock;
656 658
657 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 659 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
658 if (!ctx) 660 if (!ctx) {
659 return -ENOMEM; 661 ret = -ENOMEM;
662 goto unlock;
663 }
660 v4l2_fh_init(&ctx->fh, fimc->m2m.vfd); 664 v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
661 ctx->fimc_dev = fimc; 665 ctx->fimc_dev = fimc;
662 666
@@ -687,6 +691,8 @@ static int fimc_m2m_open(struct file *file)
687 691
688 if (fimc->m2m.refcnt++ == 0) 692 if (fimc->m2m.refcnt++ == 0)
689 set_bit(ST_M2M_RUN, &fimc->state); 693 set_bit(ST_M2M_RUN, &fimc->state);
694
695 mutex_unlock(&fimc->lock);
690 return 0; 696 return 0;
691 697
692error_c: 698error_c:
@@ -695,6 +701,8 @@ error_fh:
695 v4l2_fh_del(&ctx->fh); 701 v4l2_fh_del(&ctx->fh);
696 v4l2_fh_exit(&ctx->fh); 702 v4l2_fh_exit(&ctx->fh);
697 kfree(ctx); 703 kfree(ctx);
704unlock:
705 mutex_unlock(&fimc->lock);
698 return ret; 706 return ret;
699} 707}
700 708
@@ -706,6 +714,9 @@ static int fimc_m2m_release(struct file *file)
706 dbg("pid: %d, state: 0x%lx, refcnt= %d", 714 dbg("pid: %d, state: 0x%lx, refcnt= %d",
707 task_pid_nr(current), fimc->state, fimc->m2m.refcnt); 715 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
708 716
717 if (mutex_lock_interruptible(&fimc->lock))
718 return -ERESTARTSYS;
719
709 v4l2_m2m_ctx_release(ctx->m2m_ctx); 720 v4l2_m2m_ctx_release(ctx->m2m_ctx);
710 fimc_ctrls_delete(ctx); 721 fimc_ctrls_delete(ctx);
711 v4l2_fh_del(&ctx->fh); 722 v4l2_fh_del(&ctx->fh);
@@ -714,6 +725,8 @@ static int fimc_m2m_release(struct file *file)
714 if (--fimc->m2m.refcnt <= 0) 725 if (--fimc->m2m.refcnt <= 0)
715 clear_bit(ST_M2M_RUN, &fimc->state); 726 clear_bit(ST_M2M_RUN, &fimc->state);
716 kfree(ctx); 727 kfree(ctx);
728
729 mutex_unlock(&fimc->lock);
717 return 0; 730 return 0;
718} 731}
719 732
@@ -721,16 +734,32 @@ static unsigned int fimc_m2m_poll(struct file *file,
721 struct poll_table_struct *wait) 734 struct poll_table_struct *wait)
722{ 735{
723 struct fimc_ctx *ctx = fh_to_ctx(file->private_data); 736 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
737 struct fimc_dev *fimc = ctx->fimc_dev;
738 int ret;
724 739
725 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); 740 if (mutex_lock_interruptible(&fimc->lock))
741 return -ERESTARTSYS;
742
743 ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
744 mutex_unlock(&fimc->lock);
745
746 return ret;
726} 747}
727 748
728 749
729static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) 750static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
730{ 751{
731 struct fimc_ctx *ctx = fh_to_ctx(file->private_data); 752 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
753 struct fimc_dev *fimc = ctx->fimc_dev;
754 int ret;
755
756 if (mutex_lock_interruptible(&fimc->lock))
757 return -ERESTARTSYS;
732 758
733 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); 759 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
760 mutex_unlock(&fimc->lock);
761
762 return ret;
734} 763}
735 764
736static const struct v4l2_file_operations fimc_m2m_fops = { 765static const struct v4l2_file_operations fimc_m2m_fops = {
@@ -772,10 +801,6 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
772 vfd->minor = -1; 801 vfd->minor = -1;
773 vfd->release = video_device_release; 802 vfd->release = video_device_release;
774 vfd->lock = &fimc->lock; 803 vfd->lock = &fimc->lock;
775 /* Locking in file operations other than ioctl should be done
776 by the driver, not the V4L2 core.
777 This driver needs auditing so that this flag can be removed. */
778 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
779 804
780 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id); 805 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
781 video_set_drvdata(vfd, fimc); 806 video_set_drvdata(vfd, fimc);