8390bec
@@ -, +, @@ 
8390bec
 drivers/media/video/uvc/uvc_video.c |   50 ++++++++++++++++++++++------------
8390bec
 1 files changed, 32 insertions(+), 18 deletions(-)
8390bec
--- a/drivers/media/video/uvc/uvc_video.c	
8390bec
+++ a/drivers/media/video/uvc/uvc_video.c	
8390bec
@@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
8390bec
 	spin_unlock_irqrestore(&stream->clock.lock, flags);
8390bec
 }
8390bec
 
8390bec
-static int uvc_video_clock_init(struct uvc_streaming *stream)
8390bec
+static void uvc_video_clock_reset(struct uvc_streaming *stream)
8390bec
 {
8390bec
 	struct uvc_clock *clock = &stream->clock;
8390bec
 
8390bec
-	spin_lock_init(&clock->lock);
8390bec
 	clock->head = 0;
8390bec
 	clock->count = 0;
8390bec
-	clock->size = 32;
8390bec
 	clock->last_sof = -1;
8390bec
 	clock->sof_offset = -1;
8390bec
+}
8390bec
+
8390bec
+static int uvc_video_clock_init(struct uvc_streaming *stream)
8390bec
+{
8390bec
+	struct uvc_clock *clock = &stream->clock;
8390bec
+
8390bec
+	spin_lock_init(&clock->lock);
8390bec
+	clock->size = 32;
8390bec
 
8390bec
 	clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
8390bec
 				 GFP_KERNEL);
8390bec
 	if (clock->samples == NULL)
8390bec
 		return -ENOMEM;
8390bec
 
8390bec
+	uvc_video_clock_reset(stream);
8390bec
+
8390bec
 	return 0;
8390bec
 }
8390bec
 
8390bec
@@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
8390bec
 
8390bec
 	if (free_buffers)
8390bec
 		uvc_free_urb_buffers(stream);
8390bec
-
8390bec
-	uvc_video_clock_cleanup(stream);
8390bec
 }
8390bec
 
8390bec
 /*
8390bec
@@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
8390bec
 
8390bec
 	uvc_video_stats_start(stream);
8390bec
 
8390bec
-	ret = uvc_video_clock_init(stream);
8390bec
-	if (ret < 0)
8390bec
-		return ret;
8390bec
-
8390bec
 	if (intf->num_altsetting > 1) {
8390bec
 		struct usb_host_endpoint *best_ep = NULL;
8390bec
 		unsigned int best_psize = 3 * 1024;
8390bec
@@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset)
8390bec
 
8390bec
 	stream->frozen = 0;
8390bec
 
8390bec
+	uvc_video_clock_reset(stream);
8390bec
+
8390bec
 	ret = uvc_commit_video(stream, &stream->ctrl);
8390bec
 	if (ret < 0) {
8390bec
 		uvc_queue_enable(&stream->queue, 0);
8390bec
@@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
8390bec
 		uvc_uninit_video(stream, 1);
8390bec
 		usb_set_interface(stream->dev->udev, stream->intfnum, 0);
8390bec
 		uvc_queue_enable(&stream->queue, 0);
8390bec
+		uvc_video_clock_cleanup(stream);
8390bec
 		return 0;
8390bec
 	}
8390bec
 
8390bec
-	ret = uvc_queue_enable(&stream->queue, 1);
8390bec
+	ret = uvc_video_clock_init(stream);
8390bec
 	if (ret < 0)
8390bec
 		return ret;
8390bec
 
8390bec
+	ret = uvc_queue_enable(&stream->queue, 1);
8390bec
+	if (ret < 0)
8390bec
+		goto error_queue;
8390bec
+
8390bec
 	/* Commit the streaming parameters. */
8390bec
 	ret = uvc_commit_video(stream, &stream->ctrl);
8390bec
-	if (ret < 0) {
8390bec
-		uvc_queue_enable(&stream->queue, 0);
8390bec
-		return ret;
8390bec
-	}
8390bec
+	if (ret < 0)
8390bec
+		goto error_commit;
8390bec
 
8390bec
 	ret = uvc_init_video(stream, GFP_KERNEL);
8390bec
-	if (ret < 0) {
8390bec
-		usb_set_interface(stream->dev->udev, stream->intfnum, 0);
8390bec
-		uvc_queue_enable(&stream->queue, 0);
8390bec
-	}
8390bec
+	if (ret < 0)
8390bec
+		goto error_video;
8390bec
+
8390bec
+	return 0;
8390bec
+
8390bec
+error_video:
8390bec
+	usb_set_interface(stream->dev->udev, stream->intfnum, 0);
8390bec
+error_commit:
8390bec
+	uvc_queue_enable(&stream->queue, 0);
8390bec
+error_queue:
8390bec
+	uvc_video_clock_cleanup(stream);
8390bec
 
8390bec
 	return ret;
8390bec
 }