@@ -1889,16 +1889,24 @@ static void uvc_unregister_video(struct uvc_device *dev)
{
struct uvc_streaming *stream;
+ mutex_lock(&dev->lock);
+
list_for_each_entry(stream, &dev->streams, list) {
if (!video_is_registered(&stream->vdev))
continue;
+ mutex_lock(&stream->mutex);
+ mutex_lock(&stream->queue.mutex);
+
video_unregister_device(&stream->vdev);
video_unregister_device(&stream->meta.vdev);
uvc_debugfs_cleanup_stream(stream);
vb2_queue_release(&stream->queue.queue);
+
+ mutex_unlock(&stream->queue.mutex);
+ mutex_unlock(&stream->mutex);
}
if (dev->int_ep)
@@ -1911,6 +1919,8 @@ static void uvc_unregister_video(struct uvc_device *dev)
if (media_devnode_is_registered(dev->mdev.devnode))
media_device_unregister(&dev->mdev);
#endif
+
+ mutex_unlock(&dev->lock);
}
int uvc_register_video_device(struct uvc_device *dev,
@@ -37,14 +37,20 @@ static int uvc_pm_get(struct uvc_streaming *stream)
if (ret)
return ret;
+ mutex_lock(&stream->dev->lock);
+
+ if (!video_is_registered(&stream->vdev))
+ goto done;
+
if (!stream->dev->int_ep)
- return 0;
+ goto done;
- mutex_lock(&stream->dev->lock);
if (!stream->dev->users)
ret = uvc_status_start(stream->dev, GFP_KERNEL);
if (!ret)
stream->dev->users++;
+
+done:
mutex_unlock(&stream->dev->lock);
if (ret)