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>
This commit is contained in:
Родитель
f4693b08cc
Коммит
d6011f6fc2
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче