r8152-add-pid-for-the-lenovo-onelink-dock.patch
arm64-mm-consolidate-tcr_el1-fields.patch
+usb-gadget-uvc-consistently-use-define-for-headerlen.patch
+usb-gadget-uvc-use-on-returned-header-len-in-video_encode_isoc_sg.patch
+usb-gadget-uvc-rework-uvcg_queue_next_buffer-to-uvcg_complete_buffer.patch
+usb-gadget-uvc-giveback-vb2-buffer-on-req-complete.patch
+usb-gadget-uvc-improve-sg-exit-condition.patch
--- /dev/null
+From 859c675d84d488e2f9b515c713ea890c9f045f0c Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Mon, 18 Oct 2021 09:20:59 +0200
+Subject: usb: gadget: uvc: consistently use define for headerlen
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 859c675d84d488e2f9b515c713ea890c9f045f0c upstream.
+
+The uvc request headerlen of 2 was defined as UVCG_REQUEST_HEADER_LEN
+in commit e81e7f9a0eb9 ("usb: gadget: uvc: add scatter gather support").
+We missed to use it consistently. This patch fixes that.
+
+Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20211018072059.11465-1-m.grzeschik@pengutronix.de
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: Dan Vacura <w36195@motorola.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/uvc.h | 4 +++-
+ drivers/usb/gadget/function/uvc_video.c | 6 +++---
+ drivers/usb/gadget/function/uvc_video.h | 2 --
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/gadget/function/uvc.h
++++ b/drivers/usb/gadget/function/uvc.h
+@@ -69,6 +69,8 @@ extern unsigned int uvc_gadget_trace_par
+ #define UVC_MAX_REQUEST_SIZE 64
+ #define UVC_MAX_EVENTS 4
+
++#define UVCG_REQUEST_HEADER_LEN 2
++
+ /* ------------------------------------------------------------------------
+ * Structures
+ */
+@@ -77,7 +79,7 @@ struct uvc_request {
+ u8 *req_buffer;
+ struct uvc_video *video;
+ struct sg_table sgt;
+- u8 header[2];
++ u8 header[UVCG_REQUEST_HEADER_LEN];
+ };
+
+ struct uvc_video {
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -33,7 +33,7 @@ uvc_video_encode_header(struct uvc_video
+ if (buf->bytesused - video->queue.buf_used <= len - UVCG_REQUEST_HEADER_LEN)
+ data[1] |= UVC_STREAM_EOF;
+
+- return 2;
++ return UVCG_REQUEST_HEADER_LEN;
+ }
+
+ static int
+@@ -302,8 +302,8 @@ uvc_video_alloc_requests(struct uvc_vide
+ list_add_tail(&video->ureq[i].req->list, &video->req_free);
+ /* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */
+ sg_alloc_table(&video->ureq[i].sgt,
+- DIV_ROUND_UP(req_size - 2, PAGE_SIZE) + 2,
+- GFP_KERNEL);
++ DIV_ROUND_UP(req_size - UVCG_REQUEST_HEADER_LEN,
++ PAGE_SIZE) + 2, GFP_KERNEL);
+ }
+
+ video->req_size = req_size;
+--- a/drivers/usb/gadget/function/uvc_video.h
++++ b/drivers/usb/gadget/function/uvc_video.h
+@@ -12,8 +12,6 @@
+ #ifndef __UVC_VIDEO_H__
+ #define __UVC_VIDEO_H__
+
+-#define UVCG_REQUEST_HEADER_LEN 2
+-
+ struct uvc_video;
+
+ int uvcg_video_enable(struct uvc_video *video, int enable);
--- /dev/null
+From 9b969f93bcef9b3d9e92f1810e22bbd6c344a0e5 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Sun, 3 Apr 2022 01:27:43 +0200
+Subject: usb: gadget: uvc: giveback vb2 buffer on req complete
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 9b969f93bcef9b3d9e92f1810e22bbd6c344a0e5 upstream.
+
+On uvc_video_encode_isoc_sg the mapped vb2 buffer is returned
+to early. Only after the last usb_request worked with the buffer
+it is allowed to give it back to vb2. This patch fixes that.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20220402232744.3622565-3-m.grzeschik@pengutronix.de
+Cc: Dan Vacura <w36195@motorola.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/uvc.h | 1 +
+ drivers/usb/gadget/function/uvc_queue.c | 2 --
+ drivers/usb/gadget/function/uvc_video.c | 11 ++++++++++-
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/function/uvc.h
++++ b/drivers/usb/gadget/function/uvc.h
+@@ -80,6 +80,7 @@ struct uvc_request {
+ struct uvc_video *video;
+ struct sg_table sgt;
+ u8 header[UVCG_REQUEST_HEADER_LEN];
++ struct uvc_buffer *last_buf;
+ };
+
+ struct uvc_video {
+--- a/drivers/usb/gadget/function/uvc_queue.c
++++ b/drivers/usb/gadget/function/uvc_queue.c
+@@ -345,8 +345,6 @@ void uvcg_complete_buffer(struct uvc_vid
+ return;
+ }
+
+- list_del(&buf->queue);
+-
+ buf->buf.field = V4L2_FIELD_NONE;
+ buf->buf.sequence = queue->sequence++;
+ buf->buf.vb2_buf.timestamp = ktime_get_ns();
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -83,6 +83,7 @@ uvc_video_encode_bulk(struct usb_request
+ if (buf->bytesused == video->queue.buf_used) {
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
++ list_del(&buf->queue);
+ uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
+
+@@ -154,8 +155,9 @@ uvc_video_encode_isoc_sg(struct usb_requ
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+ buf->offset = 0;
+- uvcg_complete_buffer(&video->queue, buf);
++ list_del(&buf->queue);
+ video->fid ^= UVC_STREAM_FID;
++ ureq->last_buf = buf;
+ }
+ }
+
+@@ -181,6 +183,7 @@ uvc_video_encode_isoc(struct usb_request
+ if (buf->bytesused == video->queue.buf_used) {
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
++ list_del(&buf->queue);
+ uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
+ }
+@@ -231,6 +234,11 @@ uvc_video_complete(struct usb_ep *ep, st
+ uvcg_queue_cancel(queue, 0);
+ }
+
++ if (ureq->last_buf) {
++ uvcg_complete_buffer(&video->queue, ureq->last_buf);
++ ureq->last_buf = NULL;
++ }
++
+ spin_lock_irqsave(&video->req_lock, flags);
+ list_add_tail(&req->list, &video->req_free);
+ spin_unlock_irqrestore(&video->req_lock, flags);
+@@ -298,6 +306,7 @@ uvc_video_alloc_requests(struct uvc_vide
+ video->ureq[i].req->complete = uvc_video_complete;
+ video->ureq[i].req->context = &video->ureq[i];
+ video->ureq[i].video = video;
++ video->ureq[i].last_buf = NULL;
+
+ list_add_tail(&video->ureq[i].req->list, &video->req_free);
+ /* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */
--- /dev/null
+From aef11279888c00e1841a3533a35d279285af3a51 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Sun, 3 Apr 2022 01:27:44 +0200
+Subject: usb: gadget: uvc: improve sg exit condition
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit aef11279888c00e1841a3533a35d279285af3a51 upstream.
+
+The exit condition to quit iterating over the sg_list, while encoding
+the sg entries, has to consider the case that the dma_len of the entry
+could be zero. This patch takes this condition to account.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20220402232744.3622565-4-m.grzeschik@pengutronix.de
+Cc: Dan Vacura <w36195@motorola.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/uvc_video.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -126,7 +126,7 @@ uvc_video_encode_isoc_sg(struct usb_requ
+ sg = sg_next(sg);
+
+ for_each_sg(sg, iter, ureq->sgt.nents - 1, i) {
+- if (!len || !buf->sg)
++ if (!len || !buf->sg || !sg_dma_len(buf->sg))
+ break;
+
+ sg_left = sg_dma_len(buf->sg) - buf->offset;
--- /dev/null
+From 61aa709ca58a0dbeeb817bfa9230c1a92979f2c6 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Sun, 3 Apr 2022 01:27:42 +0200
+Subject: usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 61aa709ca58a0dbeeb817bfa9230c1a92979f2c6 upstream.
+
+The function uvcg_queue_next_buffer is used different than its name
+suggests. The return value nextbuf is never used by any caller. This
+patch reworks the function to its actual purpose, by removing the unused
+code and renaming it. The function name uvcg_complete_buffer makes it
+more clear that it is actually marking the current video buffer as
+complete.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20220402232744.3622565-2-m.grzeschik@pengutronix.de
+Cc: Dan Vacura <w36195@motorola.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/uvc_queue.c | 13 ++-----------
+ drivers/usb/gadget/function/uvc_queue.h | 2 +-
+ drivers/usb/gadget/function/uvc_video.c | 6 +++---
+ 3 files changed, 6 insertions(+), 15 deletions(-)
+
+--- a/drivers/usb/gadget/function/uvc_queue.c
++++ b/drivers/usb/gadget/function/uvc_queue.c
+@@ -335,24 +335,17 @@ int uvcg_queue_enable(struct uvc_video_q
+ }
+
+ /* called with &queue_irqlock held.. */
+-struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue,
++void uvcg_complete_buffer(struct uvc_video_queue *queue,
+ struct uvc_buffer *buf)
+ {
+- struct uvc_buffer *nextbuf;
+-
+ if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
+ buf->length != buf->bytesused) {
+ buf->state = UVC_BUF_STATE_QUEUED;
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
+- return buf;
++ return;
+ }
+
+ list_del(&buf->queue);
+- if (!list_empty(&queue->irqqueue))
+- nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
+- queue);
+- else
+- nextbuf = NULL;
+
+ buf->buf.field = V4L2_FIELD_NONE;
+ buf->buf.sequence = queue->sequence++;
+@@ -360,8 +353,6 @@ struct uvc_buffer *uvcg_queue_next_buffe
+
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
+-
+- return nextbuf;
+ }
+
+ struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue)
+--- a/drivers/usb/gadget/function/uvc_queue.h
++++ b/drivers/usb/gadget/function/uvc_queue.h
+@@ -93,7 +93,7 @@ void uvcg_queue_cancel(struct uvc_video_
+
+ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable);
+
+-struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue,
++void uvcg_complete_buffer(struct uvc_video_queue *queue,
+ struct uvc_buffer *buf);
+
+ struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue);
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -83,7 +83,7 @@ uvc_video_encode_bulk(struct usb_request
+ if (buf->bytesused == video->queue.buf_used) {
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+- uvcg_queue_next_buffer(&video->queue, buf);
++ uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
+
+ video->payload_size = 0;
+@@ -154,7 +154,7 @@ uvc_video_encode_isoc_sg(struct usb_requ
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+ buf->offset = 0;
+- uvcg_queue_next_buffer(&video->queue, buf);
++ uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
+ }
+ }
+@@ -181,7 +181,7 @@ uvc_video_encode_isoc(struct usb_request
+ if (buf->bytesused == video->queue.buf_used) {
+ video->queue.buf_used = 0;
+ buf->state = UVC_BUF_STATE_DONE;
+- uvcg_queue_next_buffer(&video->queue, buf);
++ uvcg_complete_buffer(&video->queue, buf);
+ video->fid ^= UVC_STREAM_FID;
+ }
+ }
--- /dev/null
+From f262ce66d40cc6858d1fcb11e7b7f960448a4f38 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Fri, 22 Oct 2021 11:32:22 +0200
+Subject: usb: gadget: uvc: use on returned header len in video_encode_isoc_sg
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit f262ce66d40cc6858d1fcb11e7b7f960448a4f38 upstream.
+
+The function uvc_video_encode_header function returns the number of
+bytes used for the header. We change the video_encode_isoc_sg function
+to use the returned header_len rather than UVCG_REQUEST_HEADER_LEN and
+make the encode function more flexible.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Link: https://lore.kernel.org/r/20211022093223.26493-1-m.grzeschik@pengutronix.de
+Cc: Dan Vacura <w36195@motorola.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/uvc_video.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -104,22 +104,22 @@ uvc_video_encode_isoc_sg(struct usb_requ
+ unsigned int len = video->req_size;
+ unsigned int sg_left, part = 0;
+ unsigned int i;
+- int ret;
++ int header_len;
+
+ sg = ureq->sgt.sgl;
+ sg_init_table(sg, ureq->sgt.nents);
+
+ /* Init the header. */
+- ret = uvc_video_encode_header(video, buf, ureq->header,
++ header_len = uvc_video_encode_header(video, buf, ureq->header,
+ video->req_size);
+- sg_set_buf(sg, ureq->header, UVCG_REQUEST_HEADER_LEN);
+- len -= ret;
++ sg_set_buf(sg, ureq->header, header_len);
++ len -= header_len;
+
+ if (pending <= len)
+ len = pending;
+
+ req->length = (len == pending) ?
+- len + UVCG_REQUEST_HEADER_LEN : video->req_size;
++ len + header_len : video->req_size;
+
+ /* Init the pending sgs with payload */
+ sg = sg_next(sg);
+@@ -148,7 +148,7 @@ uvc_video_encode_isoc_sg(struct usb_requ
+ req->num_sgs = i + 1;
+
+ req->length -= len;
+- video->queue.buf_used += req->length - UVCG_REQUEST_HEADER_LEN;
++ video->queue.buf_used += req->length - header_len;
+
+ if (buf->bytesused == video->queue.buf_used || !buf->sg) {
+ video->queue.buf_used = 0;