summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorRamneek Mehresh <ramneek.mehresh@freescale.com>2013-04-11 11:35:29 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-29 22:44:15 (GMT)
commit440d532b12856d6c09a31e62819444cf8adb6d65 (patch)
tree93296a1ebc9d900f544609d2e993da202333aaba /drivers/usb
parentc8213fce19ac348bb2e77cb4226c6c31300fa768 (diff)
downloadlinux-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.c16
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.h1
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