diff options
author | Felipe Balbi <balbi@ti.com> | 2013-06-12 22:11:14 +0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-07-29 14:56:59 +0400 |
commit | e8adfc30ff9282a728fd8b666b6418308164c415 (patch) | |
tree | 9d2bed840c0e38cbadb2d59ad214b0f2a1033f9d /drivers/usb/dwc3/gadget.c | |
parent | 68d6a01bdd2a9ebae858271129d0a8d4ae865e93 (diff) | |
download | linux-e8adfc30ff9282a728fd8b666b6418308164c415.tar.xz |
usb: dwc3: gadget: get rid of IRQF_ONESHOT
We can make use of bit 31 of the GEVNTSIZ(n)
registers to mask/unmask interrupts from that
particular interrupter.
With that feature, we can easily drop IRQF_ONESHOT
from our driver which makes it possible to
properly change IRQ priorities when using RT
patchset *and* it allows us to make use of the
scheduler to choose the proper time to handle
this IRQ thread.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 95ef20c5b53b..bdca5a255a1d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1490,7 +1490,7 @@ static int dwc3_gadget_start(struct usb_gadget *g, 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); + IRQF_SHARED, "dwc3", dwc); if (ret) { dev_err(dwc->dev, "failed to request irq #%d --> %d\n", irq, ret); @@ -2447,6 +2447,7 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) struct dwc3 *dwc = _dwc; unsigned long flags; irqreturn_t ret = IRQ_NONE; + u32 reg; int i; spin_lock_irqsave(&dwc->lock, flags); @@ -2486,6 +2487,11 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) evt->count = 0; evt->flags &= ~DWC3_EVENT_PENDING; ret = IRQ_HANDLED; + + /* Unmask interrupt */ + reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(i)); + reg &= ~DWC3_GEVNTSIZ_INTMASK; + dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(i), reg); } spin_unlock_irqrestore(&dwc->lock, flags); @@ -2497,6 +2503,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) { struct dwc3_event_buffer *evt; u32 count; + u32 reg; evt = dwc->ev_buffs[buf]; @@ -2508,6 +2515,11 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) evt->count = count; evt->flags |= DWC3_EVENT_PENDING; + /* Mask interrupt */ + reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf)); + reg |= DWC3_GEVNTSIZ_INTMASK; + dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg); + return IRQ_WAKE_THREAD; } |