aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2013-06-12 14:11:14 -0400
committerFelipe Balbi <balbi@ti.com>2013-07-29 06:56:59 -0400
commite8adfc30ff9282a728fd8b666b6418308164c415 (patch)
tree9d2bed840c0e38cbadb2d59ad214b0f2a1033f9d /drivers/usb/dwc3
parent68d6a01bdd2a9ebae858271129d0a8d4ae865e93 (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.c14
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