From bb40cce21a9f174d07ea82173e5fe59cfbdbaaca Mon Sep 17 00:00:00 2001 From: Ramneek Mehresh Date: Thu, 11 Apr 2013 17:05:29 +0530 Subject: usb: gadget: Add host-gadget drv sync delay Resolve synchronization issue between host and gadget drivers upon role-reversal Signed-off-by: Ramneek Mehresh Signed-off-by: yinbo.zhu 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 -- cgit v0.10.2