[COMMON] usb: dwc3: wait for end of transfer
authorKisang Lee <kisang80.lee@samsung.com>
Fri, 7 Sep 2018 07:25:31 +0000 (16:25 +0900)
committerhskang <hs1218.kang@samsung.com>
Mon, 10 Sep 2018 10:38:52 +0000 (19:38 +0900)
Change-Id: I422c8c96ab01836697dc738fe8b429835e67088f
Signed-off-by: Kisang Lee <kisang80.lee@samsung.com>
drivers/usb/dwc3/gadget.c

index 394f6d6479778a4fb9cfeb5f83ee917f1d224ce6..84f6d3c1d4865b8b46fcf899404366169ea6cb8a 100644 (file)
@@ -2286,7 +2286,8 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 {
        struct dwc3             *dwc = gadget_to_dwc(g);
        unsigned long           flags;
-       /*int                   epnum;*/
+       int                     epnum;
+       u32                     tmo_eps = 0;
 
        spin_lock_irqsave(&dwc->lock, flags);
 
@@ -2295,9 +2296,9 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 
        __dwc3_gadget_stop(dwc);
 
-#if defined(WAIT_EP_CMD_CMPLT_ENABLED)
        for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
                struct dwc3_ep  *dep = dwc->eps[epnum];
+               int ret;
 
                if (!dep)
                        continue;
@@ -2305,11 +2306,25 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
                if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
                        continue;
 
-               wait_event_lock_irq(dep->wait_end_transfer,
+               ret = wait_event_interruptible_lock_irq_timeout(dep->wait_end_transfer,
                                    !(dep->flags & DWC3_EP_END_TRANSFER_PENDING),
-                                   dwc->lock);
+                                   dwc->lock, msecs_to_jiffies(5));
+
+               if (ret <= 0) {
+                       /* Timed out or interrupted! There's nothing much
+                        * we can do so we just log here and print which
+                        * endpoints timed out at the end.
+                        */
+                       tmo_eps |= 1 << epnum;
+                       dep->flags &= DWC3_EP_END_TRANSFER_PENDING;
+               }
+       }
+
+       if (tmo_eps) {
+               dev_err(dwc->dev,
+                       "end transfer timed out on endpoints 0x%x [bitmap]\n",
+                       tmo_eps);
        }
-#endif
 
 out:
        dwc->gadget_driver      = NULL;