From 41ff4d6b62a90333ed70927f34bf7e076d851407 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 --- 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 a2dd5fe4553c..af21f44c2563 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -97,6 +97,23 @@ static inline bool using_dma(struct dwc2_hsotg *hsotg) return hsotg->g_using_dma; } +/** +* 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->regs + 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 @@ -107,11 +124,14 @@ static inline bool using_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 = 1; hs_ep->target_frame &= DSTS_SOFFN_LIMIT; - } else { + } else if (current_frame <= hs_ep->target_frame) { hs_ep->frame_overrun = 0; } } @@ -524,23 +544,6 @@ static unsigned 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->regs + DSTS); - dsts &= DSTS_SOFFN_MASK; - dsts >>= DSTS_SOFFN_SHIFT; - - return dsts; -} - /** * dwc2_hsotg_start_req - start a USB request from an endpoint's queue * @hsotg: The controller state.