diff options
author | Felipe Balbi <balbi@ti.com> | 2013-06-27 07:00:18 (GMT) |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-07-29 10:56:39 (GMT) |
commit | b0d7ffd44ba9cd2dfbf299674418193a5f9ed21a (patch) | |
tree | f94aa3f515255204fab472d80814e1fd8ead1d1e /drivers | |
parent | 2b0c49530bc5fdbde93295e5c8f26f55d0de1e04 (diff) | |
download | linux-fsl-qoriq-b0d7ffd44ba9cd2dfbf299674418193a5f9ed21a.tar.xz |
usb: dwc3: gadget: don't request IRQs in atomic
We cannot request an IRQ with spinlocks held
as that would trigger a sleeping inside
spinlock warning.
Cc: <stable@vger.kernel.org> # v3.10
Reported-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f77083f..14d28d6 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1508,6 +1508,15 @@ static int dwc3_gadget_start(struct usb_gadget *g, int irq; u32 reg; + irq = platform_get_irq(to_platform_device(dwc->dev), 0); + ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, + IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); + if (ret) { + dev_err(dwc->dev, "failed to request irq #%d --> %d\n", + irq, ret); + goto err0; + } + spin_lock_irqsave(&dwc->lock, flags); if (dwc->gadget_driver) { @@ -1515,7 +1524,7 @@ static int dwc3_gadget_start(struct usb_gadget *g, dwc->gadget.name, dwc->gadget_driver->driver.name); ret = -EBUSY; - goto err0; + goto err1; } dwc->gadget_driver = driver; @@ -1551,42 +1560,38 @@ static int dwc3_gadget_start(struct usb_gadget *g, ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); if (ret) { dev_err(dwc->dev, "failed to enable %s\n", dep->name); - goto err0; + goto err2; } dep = dwc->eps[1]; ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false); if (ret) { dev_err(dwc->dev, "failed to enable %s\n", dep->name); - goto err1; + goto err3; } /* begin to receive SETUP packets */ dwc->ep0state = EP0_SETUP_PHASE; dwc3_ep0_out_start(dwc); - irq = platform_get_irq(to_platform_device(dwc->dev), 0); - ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, - IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); - if (ret) { - dev_err(dwc->dev, "failed to request irq #%d --> %d\n", - irq, ret); - goto err1; - } - dwc3_gadget_enable_irq(dwc); spin_unlock_irqrestore(&dwc->lock, flags); return 0; -err1: +err3: __dwc3_gadget_ep_disable(dwc->eps[0]); -err0: +err2: dwc->gadget_driver = NULL; + +err1: spin_unlock_irqrestore(&dwc->lock, flags); + free_irq(irq, dwc); + +err0: return ret; } @@ -1600,9 +1605,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g, spin_lock_irqsave(&dwc->lock, flags); dwc3_gadget_disable_irq(dwc); - irq = platform_get_irq(to_platform_device(dwc->dev), 0); - free_irq(irq, dwc); - __dwc3_gadget_ep_disable(dwc->eps[0]); __dwc3_gadget_ep_disable(dwc->eps[1]); @@ -1610,6 +1612,9 @@ static int dwc3_gadget_stop(struct usb_gadget *g, spin_unlock_irqrestore(&dwc->lock, flags); + irq = platform_get_irq(to_platform_device(dwc->dev), 0); + free_irq(irq, dwc); + return 0; } |