summaryrefslogtreecommitdiff
path: root/drivers/media/usb/uvc/uvc_driver.c
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2017-03-22 12:42:52 +0300
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-12-05 11:16:48 +0300
commitb012186acef57b683e3c22ba758d60c3780db16a (patch)
tree4dc9516d77492defff614c86f2ad61a4f32292c6 /drivers/media/usb/uvc/uvc_driver.c
parentece41454c6a5ed8f301ef1c37710ab222e577823 (diff)
downloadlinux-b012186acef57b683e3c22ba758d60c3780db16a.tar.xz
media: uvcvideo: Move decode processing to process context
Newer high definition cameras, and cameras with multiple lenses such as the range of stereo-vision cameras now available have ever increasing data rates. The inclusion of a variable length packet header in URB packets mean that we must memcpy the frame data out to our destination 'manually'. This can result in data rates of up to 2 gigabits per second being processed. To improve efficiency, and maximise throughput, handle the URB decode processing through a work queue to move it from interrupt context, and allow multiple processors to work on URBs in parallel. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/usb/uvc/uvc_driver.c')
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index afb44d1c9d04..b62cbd800111 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -401,6 +401,9 @@ static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
static void uvc_stream_delete(struct uvc_streaming *stream)
{
+ if (stream->async_wq)
+ destroy_workqueue(stream->async_wq);
+
mutex_destroy(&stream->mutex);
usb_put_intf(stream->intf);
@@ -425,6 +428,14 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
stream->intf = usb_get_intf(intf);
stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
+ /* Allocate a stream specific work queue for asynchronous tasks. */
+ stream->async_wq = alloc_workqueue("uvcvideo", WQ_UNBOUND | WQ_HIGHPRI,
+ 0);
+ if (!stream->async_wq) {
+ uvc_stream_delete(stream);
+ return NULL;
+ }
+
return stream;
}