diff options
author | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2020-12-01 15:44:43 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2021-01-04 15:14:25 +0300 |
commit | 28955a61568ca4ef39ef7fc814b443be24616c64 (patch) | |
tree | 50e213599c76d44e8d87c338d13d07a23e02461a /drivers | |
parent | 726daf6bafe9d1d9e5c36e1e2a4008941fbc28bd (diff) | |
download | linux-28955a61568ca4ef39ef7fc814b443be24616c64.tar.xz |
media: v4l2-dev/event: add v4l2_event_wake_all()
When unregistering a V4L2 device node, make sure any filehandles
that are waiting for an event are woken up.
Add v4l2_event_wake_all() to v4l2-event.c and call it from
video_unregister_device().
Otherwise userspace might never know that a device node was removed.
[hverkuil: checkpatch: replaced 'if (vdev == NULL)' by 'if (!vdev)']
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-dev.c | 3 | ||||
-rw-r--r-- | drivers/media/v4l2-core/v4l2-event.c | 17 |
2 files changed, 20 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index a593ea0598b5..0ddc3554f1a4 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -28,6 +28,7 @@ #include <media/v4l2-common.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-event.h> #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" @@ -1086,6 +1087,8 @@ void video_unregister_device(struct video_device *vdev) */ clear_bit(V4L2_FL_REGISTERED, &vdev->flags); mutex_unlock(&videodev_lock); + if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags)) + v4l2_event_wake_all(vdev); device_unregister(&vdev->dev); } EXPORT_SYMBOL(video_unregister_device); diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index 290c6b213179..caad58bde326 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c @@ -187,6 +187,23 @@ int v4l2_event_pending(struct v4l2_fh *fh) } EXPORT_SYMBOL_GPL(v4l2_event_pending); +void v4l2_event_wake_all(struct video_device *vdev) +{ + struct v4l2_fh *fh; + unsigned long flags; + + if (!vdev) + return; + + spin_lock_irqsave(&vdev->fh_lock, flags); + + list_for_each_entry(fh, &vdev->fh_list, list) + wake_up_all(&fh->wait); + + spin_unlock_irqrestore(&vdev->fh_lock, flags); +} +EXPORT_SYMBOL_GPL(v4l2_event_wake_all); + static void __v4l2_event_unsubscribe(struct v4l2_subscribed_event *sev) { struct v4l2_fh *fh = sev->fh; |