diff options
Diffstat (limited to 'drivers/media/common/videobuf2/videobuf2-v4l2.c')
-rw-r--r-- | drivers/media/common/videobuf2/videobuf2-v4l2.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index cfe197df970d..96d3b2b2aa31 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -14,21 +14,22 @@ * the Free Software Foundation. */ +#include <linux/device.h> #include <linux/err.h> +#include <linux/freezer.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/kthread.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/poll.h> -#include <linux/slab.h> #include <linux/sched.h> -#include <linux/freezer.h> -#include <linux/kthread.h> +#include <linux/slab.h> +#include <media/v4l2-common.h> #include <media/v4l2-dev.h> #include <media/v4l2-device.h> -#include <media/v4l2-fh.h> #include <media/v4l2-event.h> -#include <media/v4l2-common.h> +#include <media/v4l2-fh.h> #include <media/videobuf2-v4l2.h> @@ -600,7 +601,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) break; case VB2_BUF_STATE_ERROR: b->flags |= V4L2_BUF_FLAG_ERROR; - /* fall through */ + fallthrough; case VB2_BUF_STATE_DONE: b->flags |= V4L2_BUF_FLAG_DONE; break; @@ -1220,6 +1221,44 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area); #endif +void vb2_video_unregister_device(struct video_device *vdev) +{ + /* Check if vdev was ever registered at all */ + if (!vdev || !video_is_registered(vdev)) + return; + + /* + * Calling this function only makes sense if vdev->queue is set. + * If it is NULL, then just call video_unregister_device() instead. + */ + WARN_ON(!vdev->queue); + + /* + * Take a reference to the device since video_unregister_device() + * calls device_unregister(), but we don't want that to release + * the device since we want to clean up the queue first. + */ + get_device(&vdev->dev); + video_unregister_device(vdev); + if (vdev->queue && vdev->queue->owner) { + struct mutex *lock = vdev->queue->lock ? + vdev->queue->lock : vdev->lock; + + if (lock) + mutex_lock(lock); + vb2_queue_release(vdev->queue); + vdev->queue->owner = NULL; + if (lock) + mutex_unlock(lock); + } + /* + * Now we put the device, and in most cases this will release + * everything. + */ + put_device(&vdev->dev); +} +EXPORT_SYMBOL_GPL(vb2_video_unregister_device); + /* vb2_ops helpers. Only use if vq->lock is non-NULL. */ void vb2_ops_wait_prepare(struct vb2_queue *vq) |