diff options
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 2 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 10 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 2 |
3 files changed, 11 insertions, 3 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index b6eae48d7fb8..1f962dc3a6a9 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1960,7 +1960,7 @@ static int __uvc_resume(struct usb_interface *intf, int reset) list_for_each_entry(stream, &dev->streams, list) { if (stream->intf == intf) - return uvc_video_resume(stream); + return uvc_video_resume(stream, reset); } uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface " diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 49994793cc77..6f147defcce7 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -1104,10 +1104,18 @@ int uvc_video_suspend(struct uvc_streaming *stream) * buffers, making sure userspace applications are notified of the problem * instead of waiting forever. */ -int uvc_video_resume(struct uvc_streaming *stream) +int uvc_video_resume(struct uvc_streaming *stream, int reset) { int ret; + /* If the bus has been reset on resume, set the alternate setting to 0. + * This should be the default value, but some devices crash or otherwise + * misbehave if they don't receive a SET_INTERFACE request before any + * other video control request. + */ + if (reset) + usb_set_interface(stream->dev->udev, stream->intfnum, 0); + stream->frozen = 0; ret = uvc_commit_video(stream, &stream->ctrl); diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 20107fd3574d..2a38d5e55358 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -639,7 +639,7 @@ extern void uvc_mc_cleanup_entity(struct uvc_entity *entity); /* Video */ extern int uvc_video_init(struct uvc_streaming *stream); extern int uvc_video_suspend(struct uvc_streaming *stream); -extern int uvc_video_resume(struct uvc_streaming *stream); +extern int uvc_video_resume(struct uvc_streaming *stream, int reset); extern int uvc_video_enable(struct uvc_streaming *stream, int enable); extern int uvc_probe_video(struct uvc_streaming *stream, struct uvc_streaming_control *probe); |