diff options
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8e47eefffeee..f168eaebdef8 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
| @@ -2442,57 +2442,64 @@ static void dwc3_process_event_entry(struct dwc3 *dwc, | |||
| 2442 | } | 2442 | } |
| 2443 | } | 2443 | } |
| 2444 | 2444 | ||
| 2445 | static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) | 2445 | static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) |
| 2446 | { | 2446 | { |
| 2447 | struct dwc3 *dwc = _dwc; | 2447 | struct dwc3_event_buffer *evt; |
| 2448 | unsigned long flags; | ||
| 2449 | irqreturn_t ret = IRQ_NONE; | 2448 | irqreturn_t ret = IRQ_NONE; |
| 2449 | int left; | ||
| 2450 | u32 reg; | 2450 | u32 reg; |
| 2451 | int i; | ||
| 2452 | 2451 | ||
| 2453 | spin_lock_irqsave(&dwc->lock, flags); | 2452 | evt = dwc->ev_buffs[buf]; |
| 2453 | left = evt->count; | ||
| 2454 | 2454 | ||
| 2455 | for (i = 0; i < dwc->num_event_buffers; i++) { | 2455 | if (!(evt->flags & DWC3_EVENT_PENDING)) |
| 2456 | struct dwc3_event_buffer *evt; | 2456 | return IRQ_NONE; |
| 2457 | int left; | ||
| 2458 | 2457 | ||
| 2459 | evt = dwc->ev_buffs[i]; | 2458 | while (left > 0) { |
| 2460 | left = evt->count; | 2459 | union dwc3_event event; |
| 2461 | 2460 | ||
| 2462 | if (!(evt->flags & DWC3_EVENT_PENDING)) | 2461 | event.raw = *(u32 *) (evt->buf + evt->lpos); |
| 2463 | continue; | ||
| 2464 | 2462 | ||
| 2465 | while (left > 0) { | 2463 | dwc3_process_event_entry(dwc, &event); |
| 2466 | union dwc3_event event; | ||
| 2467 | 2464 | ||
| 2468 | event.raw = *(u32 *) (evt->buf + evt->lpos); | 2465 | /* |
| 2466 | * FIXME we wrap around correctly to the next entry as | ||
| 2467 | * almost all entries are 4 bytes in size. There is one | ||
| 2468 | * entry which has 12 bytes which is a regular entry | ||
| 2469 | * followed by 8 bytes data. ATM I don't know how | ||
| 2470 | * things are organized if we get next to the a | ||
| 2471 | * boundary so I worry about that once we try to handle | ||
| 2472 | * that. | ||
| 2473 | */ | ||
| 2474 | evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; | ||
| 2475 | left -= 4; | ||
| 2469 | 2476 | ||
| 2470 | dwc3_process_event_entry(dwc, &event); | 2477 | dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4); |
| 2478 | } | ||
| 2471 | 2479 | ||
| 2472 | /* | 2480 | evt->count = 0; |
| 2473 | * FIXME we wrap around correctly to the next entry as | 2481 | evt->flags &= ~DWC3_EVENT_PENDING; |
| 2474 | * almost all entries are 4 bytes in size. There is one | 2482 | ret = IRQ_HANDLED; |
| 2475 | * entry which has 12 bytes which is a regular entry | ||
| 2476 | * followed by 8 bytes data. ATM I don't know how | ||
| 2477 | * things are organized if we get next to the a | ||
| 2478 | * boundary so I worry about that once we try to handle | ||
| 2479 | * that. | ||
| 2480 | */ | ||
| 2481 | evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; | ||
| 2482 | left -= 4; | ||
| 2483 | 2483 | ||
| 2484 | dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(i), 4); | 2484 | /* Unmask interrupt */ |
| 2485 | } | 2485 | reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf)); |
| 2486 | reg &= ~DWC3_GEVNTSIZ_INTMASK; | ||
| 2487 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg); | ||
| 2486 | 2488 | ||
| 2487 | evt->count = 0; | 2489 | return ret; |
| 2488 | evt->flags &= ~DWC3_EVENT_PENDING; | 2490 | } |
| 2489 | ret = IRQ_HANDLED; | ||
| 2490 | 2491 | ||
| 2491 | /* Unmask interrupt */ | 2492 | static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) |
| 2492 | reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(i)); | 2493 | { |
| 2493 | reg &= ~DWC3_GEVNTSIZ_INTMASK; | 2494 | struct dwc3 *dwc = _dwc; |
| 2494 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(i), reg); | 2495 | unsigned long flags; |
| 2495 | } | 2496 | irqreturn_t ret = IRQ_NONE; |
| 2497 | int i; | ||
| 2498 | |||
| 2499 | spin_lock_irqsave(&dwc->lock, flags); | ||
| 2500 | |||
| 2501 | for (i = 0; i < dwc->num_event_buffers; i++) | ||
| 2502 | ret |= dwc3_process_event_buf(dwc, i); | ||
| 2496 | 2503 | ||
| 2497 | spin_unlock_irqrestore(&dwc->lock, flags); | 2504 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2498 | 2505 | ||
