diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-07-31 02:47:07 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-09 19:16:55 -0400 |
commit | 0b7286d92d43885410b7dbc55b16f658b26976f9 (patch) | |
tree | aeb1803b13354336c89e71a2c0a936656d6db8d8 /drivers/media/video/davinci | |
parent | bc738301baa20f3e3eb6909a6e22537a191dbf6d (diff) |
[media] vpif_display: remove V4L2_FL_LOCK_ALL_FOPS
Add proper locking to the file operations, allowing for the removal
of the V4L2_FL_LOCK_ALL_FOPS flag.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/davinci')
-rw-r--r-- | drivers/media/video/davinci/vpif_display.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index e129c98921ad..4a24848c1a66 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c | |||
@@ -695,10 +695,15 @@ static int vpif_mmap(struct file *filep, struct vm_area_struct *vma) | |||
695 | struct vpif_fh *fh = filep->private_data; | 695 | struct vpif_fh *fh = filep->private_data; |
696 | struct channel_obj *ch = fh->channel; | 696 | struct channel_obj *ch = fh->channel; |
697 | struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); | 697 | struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); |
698 | int ret; | ||
698 | 699 | ||
699 | vpif_dbg(2, debug, "vpif_mmap\n"); | 700 | vpif_dbg(2, debug, "vpif_mmap\n"); |
700 | 701 | ||
701 | return vb2_mmap(&common->buffer_queue, vma); | 702 | if (mutex_lock_interruptible(&common->lock)) |
703 | return -ERESTARTSYS; | ||
704 | ret = vb2_mmap(&common->buffer_queue, vma); | ||
705 | mutex_unlock(&common->lock); | ||
706 | return ret; | ||
702 | } | 707 | } |
703 | 708 | ||
704 | /* | 709 | /* |
@@ -709,11 +714,15 @@ static unsigned int vpif_poll(struct file *filep, poll_table *wait) | |||
709 | struct vpif_fh *fh = filep->private_data; | 714 | struct vpif_fh *fh = filep->private_data; |
710 | struct channel_obj *ch = fh->channel; | 715 | struct channel_obj *ch = fh->channel; |
711 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 716 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
717 | unsigned int res = 0; | ||
712 | 718 | ||
713 | if (common->started) | 719 | if (common->started) { |
714 | return vb2_poll(&common->buffer_queue, filep, wait); | 720 | mutex_lock(&common->lock); |
721 | res = vb2_poll(&common->buffer_queue, filep, wait); | ||
722 | mutex_unlock(&common->lock); | ||
723 | } | ||
715 | 724 | ||
716 | return 0; | 725 | return res; |
717 | } | 726 | } |
718 | 727 | ||
719 | /* | 728 | /* |
@@ -723,10 +732,10 @@ static unsigned int vpif_poll(struct file *filep, poll_table *wait) | |||
723 | static int vpif_open(struct file *filep) | 732 | static int vpif_open(struct file *filep) |
724 | { | 733 | { |
725 | struct video_device *vdev = video_devdata(filep); | 734 | struct video_device *vdev = video_devdata(filep); |
726 | struct channel_obj *ch = NULL; | 735 | struct channel_obj *ch = video_get_drvdata(vdev); |
727 | struct vpif_fh *fh = NULL; | 736 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
737 | struct vpif_fh *fh; | ||
728 | 738 | ||
729 | ch = video_get_drvdata(vdev); | ||
730 | /* Allocate memory for the file handle object */ | 739 | /* Allocate memory for the file handle object */ |
731 | fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); | 740 | fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); |
732 | if (fh == NULL) { | 741 | if (fh == NULL) { |
@@ -734,6 +743,10 @@ static int vpif_open(struct file *filep) | |||
734 | return -ENOMEM; | 743 | return -ENOMEM; |
735 | } | 744 | } |
736 | 745 | ||
746 | if (mutex_lock_interruptible(&common->lock)) { | ||
747 | kfree(fh); | ||
748 | return -ERESTARTSYS; | ||
749 | } | ||
737 | /* store pointer to fh in private_data member of filep */ | 750 | /* store pointer to fh in private_data member of filep */ |
738 | filep->private_data = fh; | 751 | filep->private_data = fh; |
739 | fh->channel = ch; | 752 | fh->channel = ch; |
@@ -751,6 +764,7 @@ static int vpif_open(struct file *filep) | |||
751 | /* Initialize priority of this instance to default priority */ | 764 | /* Initialize priority of this instance to default priority */ |
752 | fh->prio = V4L2_PRIORITY_UNSET; | 765 | fh->prio = V4L2_PRIORITY_UNSET; |
753 | v4l2_prio_open(&ch->prio, &fh->prio); | 766 | v4l2_prio_open(&ch->prio, &fh->prio); |
767 | mutex_unlock(&common->lock); | ||
754 | 768 | ||
755 | return 0; | 769 | return 0; |
756 | } | 770 | } |
@@ -765,6 +779,7 @@ static int vpif_release(struct file *filep) | |||
765 | struct channel_obj *ch = fh->channel; | 779 | struct channel_obj *ch = fh->channel; |
766 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 780 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
767 | 781 | ||
782 | mutex_lock(&common->lock); | ||
768 | /* if this instance is doing IO */ | 783 | /* if this instance is doing IO */ |
769 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { | 784 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { |
770 | /* Reset io_usrs member of channel object */ | 785 | /* Reset io_usrs member of channel object */ |
@@ -799,6 +814,7 @@ static int vpif_release(struct file *filep) | |||
799 | v4l2_prio_close(&ch->prio, fh->prio); | 814 | v4l2_prio_close(&ch->prio, fh->prio); |
800 | filep->private_data = NULL; | 815 | filep->private_data = NULL; |
801 | fh->initialized = 0; | 816 | fh->initialized = 0; |
817 | mutex_unlock(&common->lock); | ||
802 | kfree(fh); | 818 | kfree(fh); |
803 | 819 | ||
804 | return 0; | 820 | return 0; |
@@ -1789,10 +1805,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1789 | v4l2_prio_init(&ch->prio); | 1805 | v4l2_prio_init(&ch->prio); |
1790 | ch->common[VPIF_VIDEO_INDEX].fmt.type = | 1806 | ch->common[VPIF_VIDEO_INDEX].fmt.type = |
1791 | V4L2_BUF_TYPE_VIDEO_OUTPUT; | 1807 | V4L2_BUF_TYPE_VIDEO_OUTPUT; |
1792 | /* Locking in file operations other than ioctl should be done | ||
1793 | by the driver, not the V4L2 core. | ||
1794 | This driver needs auditing so that this flag can be removed. */ | ||
1795 | set_bit(V4L2_FL_LOCK_ALL_FOPS, &ch->video_dev->flags); | ||
1796 | ch->video_dev->lock = &common->lock; | 1808 | ch->video_dev->lock = &common->lock; |
1797 | 1809 | ||
1798 | /* register video device */ | 1810 | /* register video device */ |