diff options
author | Nicolas Saenz Julienne <nicolassaenzj@gmeil.com> | 2016-08-16 10:22:38 +0100 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-08-22 10:45:13 +0300 |
commit | d6011f6fc21b4d4ab1586f01c4f62becaa0a28d7 (patch) | |
tree | 26cd4cb81813fa12e4d55f39e9e9e3b49268827b /drivers/usb | |
parent | f4693b08cc901912a87369c46537b94ed4084ea0 (diff) |
usb: dwc3: gadget: don't rely on jiffies while holding spinlock
__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>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1f5597ef945d..122e64df2f4d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -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 */ |