summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamneek Mehresh <ramneek.mehresh@freescale.com>2013-05-16 10:09:02 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-25 07:25:27 (GMT)
commit61daa2041048330fc961bf536b3d3f34ad3e40bc (patch)
tree11190339505ddb6dd918965b60e91c208243273d
parentd0d882d9517069e1493ae778ed396a0fa5898b8f (diff)
downloadlinux-61daa2041048330fc961bf536b3d3f34ad3e40bc.tar.xz
usb: gadget: Fix USB gadget drv start issue
Move synchronization delay b/w host and gadget drv from fsl_udc_resume() to fsl_otg_start_gadget() to prevent msleep() getting called from inside interrupt context. Gadget resume always gets called from inside interrupt context except during ID change. Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com> Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com>
-rw-r--r--drivers/usb/gadget/udc/fsl_udc_core.c16
-rw-r--r--drivers/usb/gadget/udc/fsl_usb2_udc.h1
-rw-r--r--drivers/usb/host/ehci-fsl.c2
-rw-r--r--drivers/usb/phy/phy-fsl-usb.c11
4 files changed, 11 insertions, 19 deletions
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c
index 5afba93..b0d0822 100644
--- a/drivers/usb/gadget/udc/fsl_udc_core.c
+++ b/drivers/usb/gadget/udc/fsl_udc_core.c
@@ -1775,7 +1775,6 @@ 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;
@@ -2611,21 +2610,6 @@ 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 d92ea5a..8471562 100644
--- a/drivers/usb/gadget/udc/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/udc/fsl_usb2_udc.h
@@ -503,7 +503,6 @@ 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
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index e670ddb..9abe30b 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -218,7 +218,7 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
/* Enable USB controller, 83xx or 8536 */
if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6)
- clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL,
+ clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL,
CONTROL_REGISTER_W1C_MASK, 0x4);
/*
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index cb3a951..836355f 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -544,8 +544,17 @@ int fsl_otg_start_gadget(struct otg_fsm *fsm, int on)
dev = otg->gadget->dev.parent;
if (on) {
- if (dev->driver->resume)
+ /* Delay gadget resume 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, controller
+ * gets programmed for gadget role. Shutting host drv after
+ * this results in controller getting reset, and it stops
+ * responding to otg events
+ */
+ if (dev->driver->resume) {
+ msleep(1000);
dev->driver->resume(dev);
+ }
} else {
if (dev->driver->suspend)
dev->driver->suspend(dev, otg_suspend_state);