diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-dev.c')
| -rw-r--r-- | drivers/media/v4l2-core/v4l2-dev.c | 18 | 
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 69e775930fc4..feb749aaaa42 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -444,8 +444,22 @@ static int v4l2_release(struct inode *inode, struct file *filp)  	struct video_device *vdev = video_devdata(filp);  	int ret = 0; -	if (vdev->fops->release) -		ret = vdev->fops->release(filp); +	/* +	 * We need to serialize the release() with queueing new requests. +	 * The release() may trigger the cancellation of a streaming +	 * operation, and that should not be mixed with queueing a new +	 * request at the same time. +	 */ +	if (vdev->fops->release) { +		if (v4l2_device_supports_requests(vdev->v4l2_dev)) { +			mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex); +			ret = vdev->fops->release(filp); +			mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex); +		} else { +			ret = vdev->fops->release(filp); +		} +	} +  	if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP)  		dprintk("%s: release\n",  			video_device_node_name(vdev));  | 
