@@ -1898,14 +1898,22 @@ 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);
+
+ mutex_unlock(&stream->queue.mutex);
+ mutex_unlock(&stream->mutex);
}
uvc_status_unregister(dev);
@@ -1917,6 +1925,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,
@@ -38,10 +38,18 @@ static int uvc_pm_get(struct uvc_streaming *stream)
return ret;
mutex_lock(&stream->dev->lock);
+
+ if (!video_is_registered(&stream->vdev)) {
+ ret = -ENODEV;
+ goto done;
+ }
+
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)