]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
usb: dwc3: gadget: don't rely on jiffies while holding spinlock
authorNicolas Saenz Julienne <nicolassaenzj@gmeil.com>
Tue, 16 Aug 2016 09:22:38 +0000 (10:22 +0100)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Mon, 22 Aug 2016 07:45:13 +0000 (10:45 +0300)
__dwc3_gadget_wakeup() is called while holding a spinlock, then depends on
jiffies in order to timeout while polling the USB core for a link state
update. In the case the wakeup failed, the timeout will never happen and
will also cause the cpu to stall until rcu_preempt kicks in.

This switches to a "decrement variable and wait" timeout scheme.

Signed-off-by: Nicolas Saenz Julienne <nicolassaenzj@gmail.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/gadget.c

index 1f5597ef945d409282cbeb4caf6c981ea8b1cade..122e64df2f4dc173123ddbfe7ef934d8630851a2 100644 (file)
@@ -1433,7 +1433,7 @@ static int dwc3_gadget_get_frame(struct usb_gadget *g)
 
 static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
 {
-       unsigned long           timeout;
+       int                     retries;
 
        int                     ret;
        u32                     reg;
@@ -1484,9 +1484,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
        }
 
        /* poll until Link State changes to ON */
-       timeout = jiffies + msecs_to_jiffies(100);
+       retries = 20000;
 
-       while (!time_after(jiffies, timeout)) {
+       while (retries--) {
                reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 
                /* in HS, means ON */