From e85ce67f5ee2ead03e18142bb7426f3c628facdf Mon Sep 17 00:00:00 2001 From: William Wu Date: Fri, 27 Jul 2018 12:40:10 +0800 Subject: [PATCH] usb: dwc2: gadget: fix frame overrun issue The frame_overrun flag is used to indicates SOF number (current_frame) overrun in DSTS and the target_frame over DSTS_SOFFN_LIMIT. Clear the frame_overrun flag only if target_frame below DSTS_SOFFN_LIMIT and current_frame less than target_frame. Change-Id: I91cf9001324a9bbbcc4bc28b335695d607fb69d4 Signed-off-by: William Wu Signed-off-by: Frank Wang --- drivers/usb/dwc2/gadget.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 3cc293a9e3c5..502d98631fd6 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -107,6 +107,23 @@ static inline bool using_desc_dma(struct dwc2_hsotg *hsotg) return hsotg->params.g_dma_desc; } +/** + * dwc2_hsotg_read_frameno - read current frame number + * @hsotg: The device instance + * + * Return the current frame number + */ +static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg) +{ + u32 dsts; + + dsts = dwc2_readl(hsotg, DSTS); + dsts &= DSTS_SOFFN_MASK; + dsts >>= DSTS_SOFFN_SHIFT; + + return dsts; +} + /** * dwc2_gadget_incr_frame_num - Increments the targeted frame number. * @hs_ep: The endpoint @@ -116,11 +133,14 @@ static inline bool using_desc_dma(struct dwc2_hsotg *hsotg) */ static inline void dwc2_gadget_incr_frame_num(struct dwc2_hsotg_ep *hs_ep) { + struct dwc2_hsotg *hsotg = hs_ep->parent; + u32 current_frame = dwc2_hsotg_read_frameno(hsotg); + hs_ep->target_frame += hs_ep->interval; if (hs_ep->target_frame > DSTS_SOFFN_LIMIT) { hs_ep->frame_overrun = true; hs_ep->target_frame &= DSTS_SOFFN_LIMIT; - } else { + } else if (current_frame <= hs_ep->target_frame) { hs_ep->frame_overrun = false; } } @@ -686,23 +706,6 @@ static unsigned int get_ep_limit(struct dwc2_hsotg_ep *hs_ep) return maxsize; } -/** - * dwc2_hsotg_read_frameno - read current frame number - * @hsotg: The device instance - * - * Return the current frame number - */ -static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg) -{ - u32 dsts; - - dsts = dwc2_readl(hsotg, DSTS); - dsts &= DSTS_SOFFN_MASK; - dsts >>= DSTS_SOFFN_SHIFT; - - return dsts; -} - /** * dwc2_gadget_get_chain_limit - get the maximum data payload value of the * DMA descriptor chain prepared for specific endpoint