diff options
author | Ramneek Mehresh <ramneek.mehresh@freescale.com> | 2013-04-11 11:35:29 (GMT) |
---|---|---|
committer | Xie Xiaobo <xiaobo.xie@nxp.com> | 2017-09-25 07:25:27 (GMT) |
commit | bb40cce21a9f174d07ea82173e5fe59cfbdbaaca (patch) | |
tree | 75f80cfcfd17a9c76ba4accf4685cd2602482626 /drivers/usb | |
parent | 14b69bb2d73140b536a29435544045fe386999fe (diff) | |
download | linux-bb40cce21a9f174d07ea82173e5fe59cfbdbaaca.tar.xz |
usb: gadget: Add host-gadget drv sync delay
Resolve synchronization issue between host and gadget drivers
upon role-reversal
Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/udc/fsl_udc_core.c | 16 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/fsl_usb2_udc.h | 1 |
2 files changed, 17 insertions, 0 deletions
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index b0d0822..5afba93 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1775,6 +1775,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; @@ -2610,6 +2611,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/udc/fsl_usb2_udc.h b/drivers/usb/gadget/udc/fsl_usb2_udc.h index 8471562..d92ea5a 100644 --- a/drivers/usb/gadget/udc/fsl_usb2_udc.h +++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h @@ -503,6 +503,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 |