mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
UPSTREAM: media: uvcvideo: Convert from using an atomic variable to a reference count
When adding support for metadata nodes, we'll have to keep video
devices registered until all metadata nodes are closed too. Since
this has nothing to do with stream counting, replace the nstreams
atomic variable with a reference counter.
Change-Id: Ied4c660b0cc618f010e4fffc3c3e06a2f71f4aa7
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: William Wu <william.wu@rock-chips.com>
(cherry picked from commit 9d15cd958c)
This commit is contained in:
committed by
Tao Huang
parent
a74ace07b6
commit
a953079953
@@ -1768,8 +1768,9 @@ static int uvc_scan_device(struct uvc_device *dev)
|
||||
* already been canceled by the USB core. There is no need to kill the
|
||||
* interrupt URB manually.
|
||||
*/
|
||||
static void uvc_delete(struct uvc_device *dev)
|
||||
static void uvc_delete(struct kref *kref)
|
||||
{
|
||||
struct uvc_device *dev = container_of(kref, struct uvc_device, ref);
|
||||
struct list_head *p, *n;
|
||||
|
||||
uvc_status_cleanup(dev);
|
||||
@@ -1819,11 +1820,7 @@ static void uvc_release(struct video_device *vdev)
|
||||
struct uvc_streaming *stream = video_get_drvdata(vdev);
|
||||
struct uvc_device *dev = stream->dev;
|
||||
|
||||
/* Decrement the registered streams count and delete the device when it
|
||||
* reaches zero.
|
||||
*/
|
||||
if (atomic_dec_and_test(&dev->nstreams))
|
||||
uvc_delete(dev);
|
||||
kref_put(&dev->ref, uvc_delete);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1835,10 +1832,10 @@ static void uvc_unregister_video(struct uvc_device *dev)
|
||||
|
||||
/* Unregistering all video devices might result in uvc_delete() being
|
||||
* called from inside the loop if there's no open file handle. To avoid
|
||||
* that, increment the stream count before iterating over the streams
|
||||
* and decrement it when done.
|
||||
* that, increment the refcount before iterating over the streams and
|
||||
* decrement it when done.
|
||||
*/
|
||||
atomic_inc(&dev->nstreams);
|
||||
kref_get(&dev->ref);
|
||||
|
||||
list_for_each_entry(stream, &dev->streams, list) {
|
||||
if (!video_is_registered(&stream->vdev))
|
||||
@@ -1849,11 +1846,7 @@ static void uvc_unregister_video(struct uvc_device *dev)
|
||||
uvc_debugfs_cleanup_stream(stream);
|
||||
}
|
||||
|
||||
/* Decrement the stream count and call uvc_delete explicitly if there
|
||||
* are no stream left.
|
||||
*/
|
||||
if (atomic_dec_and_test(&dev->nstreams))
|
||||
uvc_delete(dev);
|
||||
kref_put(&dev->ref, uvc_delete);
|
||||
}
|
||||
|
||||
static int uvc_register_video(struct uvc_device *dev,
|
||||
@@ -1911,7 +1904,7 @@ static int uvc_register_video(struct uvc_device *dev,
|
||||
else
|
||||
stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
|
||||
|
||||
atomic_inc(&dev->nstreams);
|
||||
kref_get(&dev->ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1995,7 +1988,7 @@ static int uvc_probe(struct usb_interface *intf,
|
||||
INIT_LIST_HEAD(&dev->entities);
|
||||
INIT_LIST_HEAD(&dev->chains);
|
||||
INIT_LIST_HEAD(&dev->streams);
|
||||
atomic_set(&dev->nstreams, 0);
|
||||
kref_init(&dev->ref);
|
||||
atomic_set(&dev->nmappings, 0);
|
||||
mutex_init(&dev->lock);
|
||||
|
||||
|
||||
@@ -554,7 +554,7 @@ struct uvc_device {
|
||||
|
||||
/* Video Streaming interfaces */
|
||||
struct list_head streams;
|
||||
atomic_t nstreams;
|
||||
struct kref ref;
|
||||
|
||||
/* Status Interrupt Endpoint */
|
||||
struct usb_host_endpoint *int_ep;
|
||||
|
||||
Reference in New Issue
Block a user