usb: dwc3: Disable ep0 and interrupts when clearing run/stop

In dwc3_gadget_run_stop() when clearing the run/stop bit, ensure
that IRQs are masked and the ep0 in and out endpoints are disabled.
In case pullups are removed while a control transfer is in progress,
this makes sure that the control endpoints are properly cleaned up.
If and when run/stop is set again, the function already re-enables
the IRQ and ep0 when calling dwc3_gadget_restart(). While at it,
memset() the event buffers to clear stale contents when
reinitializing them in dwc3_event_buffers_setup().

Also, since calling dwc3_gadget_disable_irq() only masks the
interrupts at the controller layer, it might not catch instances
where an IRQ itself may have already been asserted but does not
arrive at the handler until after the pullups are removed. Add a
check to dwc3_interrupt() to catch this case as well.

Change-Id: Ie58979fe4b229240231760652189338ec5343a2d
Signed-off-by: Jack Pham <jackp@codeaurora.org>
This commit is contained in:
Jack Pham 2015-10-21 12:50:15 -07:00 committed by David Keitel
parent a43ebbb862
commit 869c733233
2 changed files with 12 additions and 0 deletions

View file

@ -319,6 +319,8 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc)
evt->buf, (unsigned long long) evt->dma,
evt->length);
memset(evt->buf, 0, evt->length);
evt->lpos = 0;
dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),

View file

@ -1691,6 +1691,10 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
dwc->pullups_connected = true;
} else {
dwc3_gadget_disable_irq(dwc);
__dwc3_gadget_ep_disable(dwc->eps[0]);
__dwc3_gadget_ep_disable(dwc->eps[1]);
reg &= ~DWC3_DCTL_RUN_STOP;
if (dwc->has_hibernation && !suspend)
@ -2942,6 +2946,12 @@ static void dwc3_process_event_entry(struct dwc3 *dwc,
{
trace_dwc3_event(event->raw);
/* If run/stop is cleared don't process any more events */
if (!dwc->pullups_connected) {
dbg_print_reg("SKIP_EVT_PULLUP", event->raw);
return;
}
/* Endpoint IRQ, handle it and return early */
if (event->type.is_devspec == 0) {
/* depevt */