summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorMichael Grzeschik <m.grzeschik@pengutronix.de>2021-06-28 18:53:11 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-27 16:59:19 +0300
commitfc78941d8169cba40e420eb24a88789b0406c738 (patch)
treef2778995fc0993797696a4d44962404dae39b89b /drivers/usb/gadget
parente81e7f9a0eb9536d5976acf5d95290338032a198 (diff)
downloadlinux-fc78941d8169cba40e420eb24a88789b0406c738.tar.xz
usb: gadget: uvc: decrease the interrupt load to a quarter
With usb3 we handle many more requests. Decrease the interrupt load by only enabling the interrupt every quarter of the allocated requests. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> -- v1 -> v2: - edited patch description - removed extra parantheses - added a comment for the logic - using unsigned int instead of int - reinitializing req_int_count in uvcg_video_enable v2 -> v3: - Link: https://lore.kernel.org/r/20210628155311.16762-6-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/function/uvc.h2
-rw-r--r--drivers/usb/gadget/function/uvc_video.c16
2 files changed, 18 insertions, 0 deletions
diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index 36b78f8b3cd4..255a61bd6a6a 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -101,6 +101,8 @@ struct uvc_video {
struct list_head req_free;
spinlock_t req_lock;
+ unsigned int req_int_count;
+
void (*encode) (struct usb_request *req, struct uvc_video *video,
struct uvc_buffer *buf);
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index 2cefb8bd4f15..b4a763e5f70e 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -360,6 +360,19 @@ static void uvcg_video_pump(struct work_struct *work)
video->encode(req, video, buf);
+ /* With usb3 we have more requests. This will decrease the
+ * interrupt load to a quarter but also catches the corner
+ * cases, which needs to be handled */
+ if (list_empty(&video->req_free) ||
+ buf->state == UVC_BUF_STATE_DONE ||
+ !(video->req_int_count %
+ DIV_ROUND_UP(video->uvc_num_requests, 4))) {
+ video->req_int_count = 0;
+ req->no_interrupt = 0;
+ } else {
+ req->no_interrupt = 1;
+ }
+
/* Queue the USB request */
ret = uvcg_video_ep_queue(video, req);
spin_unlock_irqrestore(&queue->irqlock, flags);
@@ -368,6 +381,7 @@ static void uvcg_video_pump(struct work_struct *work)
uvcg_queue_cancel(queue, 0);
break;
}
+ video->req_int_count++;
}
spin_lock_irqsave(&video->req_lock, flags);
@@ -416,6 +430,8 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
video->encode = video->queue.use_sg ?
uvc_video_encode_isoc_sg : uvc_video_encode_isoc;
+ video->req_int_count = 0;
+
schedule_work(&video->pump);
return ret;