提交 d6011f6f 编写于 作者: N Nicolas Saenz Julienne 提交者: Felipe Balbi

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: NNicolas Saenz Julienne <nicolassaenzj@gmail.com>
Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
上级 f4693b08
...@@ -1433,7 +1433,7 @@ static int dwc3_gadget_get_frame(struct usb_gadget *g) ...@@ -1433,7 +1433,7 @@ static int dwc3_gadget_get_frame(struct usb_gadget *g)
static int __dwc3_gadget_wakeup(struct dwc3 *dwc) static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
{ {
unsigned long timeout; int retries;
int ret; int ret;
u32 reg; u32 reg;
...@@ -1484,9 +1484,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc) ...@@ -1484,9 +1484,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
} }
/* poll until Link State changes to ON */ /* 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); reg = dwc3_readl(dwc->regs, DWC3_DSTS);
/* in HS, means ON */ /* in HS, means ON */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册