aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Saenz Julienne <nicolassaenzj@gmeil.com>2016-08-16 05:22:38 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-08-22 03:45:13 -0400
commitd6011f6fc21b4d4ab1586f01c4f62becaa0a28d7 (patch)
tree26cd4cb81813fa12e4d55f39e9e9e3b49268827b
parentf4693b08cc901912a87369c46537b94ed4084ea0 (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>
-rw-r--r--drivers/usb/dwc3/gadget.c6
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)
1433 1433
1434static int __dwc3_gadget_wakeup(struct dwc3 *dwc) 1434static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
1435{ 1435{
1436 unsigned long timeout; 1436 int retries;
1437 1437
1438 int ret; 1438 int ret;
1439 u32 reg; 1439 u32 reg;
@@ -1484,9 +1484,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
1484 } 1484 }
1485 1485
1486 /* poll until Link State changes to ON */ 1486 /* poll until Link State changes to ON */
1487 timeout = jiffies + msecs_to_jiffies(100); 1487 retries = 20000;
1488 1488
1489 while (!time_after(jiffies, timeout)) { 1489 while (retries--) {
1490 reg = dwc3_readl(dwc->regs, DWC3_DSTS); 1490 reg = dwc3_readl(dwc->regs, DWC3_DSTS);
1491 1491
1492 /* in HS, means ON */ 1492 /* in HS, means ON */