diff options
author | Felipe Balbi <balbi@ti.com> | 2013-06-12 14:11:14 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-07-29 06:56:59 -0400 |
commit | e8adfc30ff9282a728fd8b666b6418308164c415 (patch) | |
tree | 9d2bed840c0e38cbadb2d59ad214b0f2a1033f9d /drivers/usb/dwc3 | |
parent | 68d6a01bdd2a9ebae858271129d0a8d4ae865e93 (diff) |
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')
-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, | |||
1490 | 1490 | ||
1491 | irq = platform_get_irq(to_platform_device(dwc->dev), 0); | 1491 | irq = platform_get_irq(to_platform_device(dwc->dev), 0); |
1492 | ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, | 1492 | ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt, |
1493 | IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc); | 1493 | IRQF_SHARED, "dwc3", dwc); |
1494 | if (ret) { | 1494 | if (ret) { |
1495 | dev_err(dwc->dev, "failed to request irq #%d --> %d\n", | 1495 | dev_err(dwc->dev, "failed to request irq #%d --> %d\n", |
1496 | irq, ret); | 1496 | irq, ret); |
@@ -2447,6 +2447,7 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) | |||
2447 | struct dwc3 *dwc = _dwc; | 2447 | struct dwc3 *dwc = _dwc; |
2448 | unsigned long flags; | 2448 | unsigned long flags; |
2449 | irqreturn_t ret = IRQ_NONE; | 2449 | irqreturn_t ret = IRQ_NONE; |
2450 | u32 reg; | ||
2450 | int i; | 2451 | int i; |
2451 | 2452 | ||
2452 | spin_lock_irqsave(&dwc->lock, flags); | 2453 | spin_lock_irqsave(&dwc->lock, flags); |
@@ -2486,6 +2487,11 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) | |||
2486 | evt->count = 0; | 2487 | evt->count = 0; |
2487 | evt->flags &= ~DWC3_EVENT_PENDING; | 2488 | evt->flags &= ~DWC3_EVENT_PENDING; |
2488 | ret = IRQ_HANDLED; | 2489 | ret = IRQ_HANDLED; |
2490 | |||
2491 | /* Unmask interrupt */ | ||
2492 | reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(i)); | ||
2493 | reg &= ~DWC3_GEVNTSIZ_INTMASK; | ||
2494 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(i), reg); | ||
2489 | } | 2495 | } |
2490 | 2496 | ||
2491 | spin_unlock_irqrestore(&dwc->lock, flags); | 2497 | spin_unlock_irqrestore(&dwc->lock, flags); |
@@ -2497,6 +2503,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) | |||
2497 | { | 2503 | { |
2498 | struct dwc3_event_buffer *evt; | 2504 | struct dwc3_event_buffer *evt; |
2499 | u32 count; | 2505 | u32 count; |
2506 | u32 reg; | ||
2500 | 2507 | ||
2501 | evt = dwc->ev_buffs[buf]; | 2508 | evt = dwc->ev_buffs[buf]; |
2502 | 2509 | ||
@@ -2508,6 +2515,11 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) | |||
2508 | evt->count = count; | 2515 | evt->count = count; |
2509 | evt->flags |= DWC3_EVENT_PENDING; | 2516 | evt->flags |= DWC3_EVENT_PENDING; |
2510 | 2517 | ||
2518 | /* Mask interrupt */ | ||
2519 | reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf)); | ||
2520 | reg |= DWC3_GEVNTSIZ_INTMASK; | ||
2521 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg); | ||
2522 | |||
2511 | return IRQ_WAKE_THREAD; | 2523 | return IRQ_WAKE_THREAD; |
2512 | } | 2524 | } |
2513 | 2525 | ||