diff options
-rw-r--r-- | drivers/usb/gadget/fsl_udc_core.c | 16 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.h | 1 |
2 files changed, 17 insertions, 0 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index a26ab58..403f891 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1785,6 +1785,7 @@ static void suspend_irq(struct fsl_udc *udc) static void bus_resume(struct fsl_udc *udc) { + udc->last_state = udc->usb_state; udc->usb_state = udc->resume_state; udc->resume_state = 0; @@ -2692,6 +2693,21 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) *-----------------------------------------------------------------*/ static int fsl_udc_resume(struct platform_device *pdev) { +#if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) + /* Add delay to synchronize between host and gadget drivers + * Upon role-reversal host drv is shutdown by kernel worker + * thread. By the time host drv shuts down, dr controller + * gets programmed for gadget role. Shutting host drv after this + * results in controller getting reset, and it stops responding + * to otg events + * + * This delay can be added only if this function call is not in + * interrupt context which happens only when USB device is not + * coming out of SUSPEND state + */ + if (udc_controller->last_state != USB_STATE_SUSPENDED) + msleep(1000); +#endif /* Enable DR irq reg and set controller Run */ if (udc_controller->stopped) { dr_controller_setup(udc_controller); diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index c6703bb..53f508a 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h @@ -500,6 +500,7 @@ struct fsl_udc { u32 max_pipes; /* Device max pipes */ u32 bus_reset; /* Device is bus resetting */ u32 resume_state; /* USB state to resume */ + u32 last_state; /* previous USB state */ u32 usb_state; /* USB current state */ u32 ep0_state; /* Endpoint zero state */ u32 ep0_dir; /* Endpoint zero direction: can be |