diff options
author | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2017-03-22 12:42:52 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-12-05 11:16:48 +0300 |
commit | b012186acef57b683e3c22ba758d60c3780db16a (patch) | |
tree | 4dc9516d77492defff614c86f2ad61a4f32292c6 /drivers/media/usb/uvc/uvc_driver.c | |
parent | ece41454c6a5ed8f301ef1c37710ab222e577823 (diff) | |
download | linux-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.c | 11 |
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; } |