usb: gadget: Resume usb bus on reset
When receiving reset interrupt from the usb controller, check if the bus
is suspended. If so then first resume the bus and only then reset
the usb controller.
This fixes a case of race condition when reset
interrupt is happening right after suspend interrupt. In this case
there might be a race in which the msm_otg will execute the suspend
event in the work queue after the reset interrupt finished. In this case
the bus will be suspended after the reset and no further event
(resume/reset) will arrive from host, keeping the device in LPM forever.
Change-Id: Ifd4bee52eb42c3313821a799a935539d1789d42e
CRs-Fixed: 381806, 386464
Signed-off-by: Ido Shayevitz <idos@codeaurora.org>
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 4d15c55..831e970 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2056,6 +2056,16 @@
spin_unlock(udc->lock);
+ if (udc->suspended) {
+ if (udc->udc_driver->notify_event)
+ udc->udc_driver->notify_event(udc,
+ CI13XXX_CONTROLLER_RESUME_EVENT);
+ if (udc->transceiver)
+ usb_phy_set_suspend(udc->transceiver, 0);
+ udc->driver->resume(&udc->gadget);
+ udc->suspended = 0;
+ }
+
/*stop charging upon reset */
if (udc->transceiver)
usb_phy_set_power(udc->transceiver, 0);