diff options
author | Ramneek Mehresh <ramneek.mehresh@freescale.com> | 2013-05-16 10:09:02 (GMT) |
---|---|---|
committer | Xie Xiaobo <xiaobo.xie@nxp.com> | 2017-09-25 07:25:27 (GMT) |
commit | 61daa2041048330fc961bf536b3d3f34ad3e40bc (patch) | |
tree | 11190339505ddb6dd918965b60e91c208243273d /drivers | |
parent | d0d882d9517069e1493ae778ed396a0fa5898b8f (diff) | |
download | linux-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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/udc/fsl_udc_core.c | 16 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/fsl_usb2_udc.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 2 | ||||
-rw-r--r-- | drivers/usb/phy/phy-fsl-usb.c | 11 |
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); |