diff options
Diffstat (limited to 'drivers/media/video/uvc/uvc_video.c')
| -rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 4a44f9a1bae0..b76b0ac0958f 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
| @@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, | |||
| 468 | spin_unlock_irqrestore(&stream->clock.lock, flags); | 468 | spin_unlock_irqrestore(&stream->clock.lock, flags); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | static int uvc_video_clock_init(struct uvc_streaming *stream) | 471 | static void uvc_video_clock_reset(struct uvc_streaming *stream) |
| 472 | { | 472 | { |
| 473 | struct uvc_clock *clock = &stream->clock; | 473 | struct uvc_clock *clock = &stream->clock; |
| 474 | 474 | ||
| 475 | spin_lock_init(&clock->lock); | ||
| 476 | clock->head = 0; | 475 | clock->head = 0; |
| 477 | clock->count = 0; | 476 | clock->count = 0; |
| 478 | clock->size = 32; | ||
| 479 | clock->last_sof = -1; | 477 | clock->last_sof = -1; |
| 480 | clock->sof_offset = -1; | 478 | clock->sof_offset = -1; |
| 479 | } | ||
| 480 | |||
| 481 | static int uvc_video_clock_init(struct uvc_streaming *stream) | ||
| 482 | { | ||
| 483 | struct uvc_clock *clock = &stream->clock; | ||
| 484 | |||
| 485 | spin_lock_init(&clock->lock); | ||
| 486 | clock->size = 32; | ||
| 481 | 487 | ||
| 482 | clock->samples = kmalloc(clock->size * sizeof(*clock->samples), | 488 | clock->samples = kmalloc(clock->size * sizeof(*clock->samples), |
| 483 | GFP_KERNEL); | 489 | GFP_KERNEL); |
| 484 | if (clock->samples == NULL) | 490 | if (clock->samples == NULL) |
| 485 | return -ENOMEM; | 491 | return -ENOMEM; |
| 486 | 492 | ||
| 493 | uvc_video_clock_reset(stream); | ||
| 494 | |||
| 487 | return 0; | 495 | return 0; |
| 488 | } | 496 | } |
| 489 | 497 | ||
| @@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) | |||
| 1424 | 1432 | ||
| 1425 | if (free_buffers) | 1433 | if (free_buffers) |
| 1426 | uvc_free_urb_buffers(stream); | 1434 | uvc_free_urb_buffers(stream); |
| 1427 | |||
| 1428 | uvc_video_clock_cleanup(stream); | ||
| 1429 | } | 1435 | } |
| 1430 | 1436 | ||
| 1431 | /* | 1437 | /* |
| @@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) | |||
| 1555 | 1561 | ||
| 1556 | uvc_video_stats_start(stream); | 1562 | uvc_video_stats_start(stream); |
| 1557 | 1563 | ||
| 1558 | ret = uvc_video_clock_init(stream); | ||
| 1559 | if (ret < 0) | ||
| 1560 | return ret; | ||
| 1561 | |||
| 1562 | if (intf->num_altsetting > 1) { | 1564 | if (intf->num_altsetting > 1) { |
| 1563 | struct usb_host_endpoint *best_ep = NULL; | 1565 | struct usb_host_endpoint *best_ep = NULL; |
| 1564 | unsigned int best_psize = 3 * 1024; | 1566 | unsigned int best_psize = 3 * 1024; |
| @@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) | |||
| 1683 | 1685 | ||
| 1684 | stream->frozen = 0; | 1686 | stream->frozen = 0; |
| 1685 | 1687 | ||
| 1688 | uvc_video_clock_reset(stream); | ||
| 1689 | |||
| 1686 | ret = uvc_commit_video(stream, &stream->ctrl); | 1690 | ret = uvc_commit_video(stream, &stream->ctrl); |
| 1687 | if (ret < 0) { | 1691 | if (ret < 0) { |
| 1688 | uvc_queue_enable(&stream->queue, 0); | 1692 | uvc_queue_enable(&stream->queue, 0); |
| @@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) | |||
| 1819 | uvc_uninit_video(stream, 1); | 1823 | uvc_uninit_video(stream, 1); |
| 1820 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); | 1824 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); |
| 1821 | uvc_queue_enable(&stream->queue, 0); | 1825 | uvc_queue_enable(&stream->queue, 0); |
| 1826 | uvc_video_clock_cleanup(stream); | ||
| 1822 | return 0; | 1827 | return 0; |
| 1823 | } | 1828 | } |
| 1824 | 1829 | ||
| 1825 | ret = uvc_queue_enable(&stream->queue, 1); | 1830 | ret = uvc_video_clock_init(stream); |
| 1826 | if (ret < 0) | 1831 | if (ret < 0) |
| 1827 | return ret; | 1832 | return ret; |
| 1828 | 1833 | ||
| 1834 | ret = uvc_queue_enable(&stream->queue, 1); | ||
| 1835 | if (ret < 0) | ||
| 1836 | goto error_queue; | ||
| 1837 | |||
| 1829 | /* Commit the streaming parameters. */ | 1838 | /* Commit the streaming parameters. */ |
| 1830 | ret = uvc_commit_video(stream, &stream->ctrl); | 1839 | ret = uvc_commit_video(stream, &stream->ctrl); |
| 1831 | if (ret < 0) { | 1840 | if (ret < 0) |
| 1832 | uvc_queue_enable(&stream->queue, 0); | 1841 | goto error_commit; |
| 1833 | return ret; | ||
| 1834 | } | ||
| 1835 | 1842 | ||
| 1836 | ret = uvc_init_video(stream, GFP_KERNEL); | 1843 | ret = uvc_init_video(stream, GFP_KERNEL); |
| 1837 | if (ret < 0) { | 1844 | if (ret < 0) |
| 1838 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); | 1845 | goto error_video; |
| 1839 | uvc_queue_enable(&stream->queue, 0); | 1846 | |
| 1840 | } | 1847 | return 0; |
| 1848 | |||
| 1849 | error_video: | ||
| 1850 | usb_set_interface(stream->dev->udev, stream->intfnum, 0); | ||
| 1851 | error_commit: | ||
| 1852 | uvc_queue_enable(&stream->queue, 0); | ||
| 1853 | error_queue: | ||
| 1854 | uvc_video_clock_cleanup(stream); | ||
| 1841 | 1855 | ||
| 1842 | return ret; | 1856 | return ret; |
| 1843 | } | 1857 | } |
