diff options
Diffstat (limited to 'drivers/media/usb/uvc/uvc_driver.c')
-rw-r--r-- | drivers/media/usb/uvc/uvc_driver.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index a7e64af5f82e..81695d48c13e 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1836,8 +1836,8 @@ static int uvc_probe(struct usb_interface *intf, INIT_LIST_HEAD(&dev->chains); INIT_LIST_HEAD(&dev->streams); atomic_set(&dev->nstreams, 0); - atomic_set(&dev->users, 0); atomic_set(&dev->nmappings, 0); + mutex_init(&dev->lock); dev->udev = usb_get_dev(udev); dev->intf = usb_get_intf(intf); @@ -1950,8 +1950,13 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message) /* Controls are cached on the fly so they don't need to be saved. */ if (intf->cur_altsetting->desc.bInterfaceSubClass == - UVC_SC_VIDEOCONTROL) - return uvc_status_suspend(dev); + UVC_SC_VIDEOCONTROL) { + mutex_lock(&dev->lock); + if (dev->users) + uvc_status_stop(dev); + mutex_unlock(&dev->lock); + return 0; + } list_for_each_entry(stream, &dev->streams, list) { if (stream->intf == intf) @@ -1973,14 +1978,20 @@ static int __uvc_resume(struct usb_interface *intf, int reset) if (intf->cur_altsetting->desc.bInterfaceSubClass == UVC_SC_VIDEOCONTROL) { - if (reset) { - int ret = uvc_ctrl_resume_device(dev); + int ret = 0; + if (reset) { + ret = uvc_ctrl_resume_device(dev); if (ret < 0) return ret; } - return uvc_status_resume(dev); + mutex_lock(&dev->lock); + if (dev->users) + ret = uvc_status_start(dev, GFP_NOIO); + mutex_unlock(&dev->lock); + + return ret; } list_for_each_entry(stream, &dev->streams, list) { |