diff options
author | Ramneek Mehresh <ramneek.mehresh@freescale.com> | 2013-04-11 11:35:29 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-04-29 22:44:15 (GMT) |
commit | 440d532b12856d6c09a31e62819444cf8adb6d65 (patch) | |
tree | 93296a1ebc9d900f544609d2e993da202333aaba /drivers/usb | |
parent | c8213fce19ac348bb2e77cb4226c6c31300fa768 (diff) | |
download | linux-fsl-qoriq-440d532b12856d6c09a31e62819444cf8adb6d65.tar.xz |
fsl/otg: 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>
Change-Id: I59af73acb3adbf9f3ddf6512d065d2752af63c5f
Reviewed-on: http://git.am.freescale.net:8181/1370
Reviewed-by: Li Yang-R58472 <LeoLi@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'drivers/usb')
-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 |