diff options
author | Venkat Moganty <vmoganty@nvidia.com> | 2010-07-17 10:49:42 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-07-19 13:39:44 -0700 |
commit | 26c1256a07f2143bf0765dd49454557e710bff78 (patch) | |
tree | e159fbcc802e578e30acff653ab382aa3c79971c | |
parent | cabc1827ba228b0901c7276979e990734385e980 (diff) |
[tegra-udc]: Fix LP0 hang in udc suspend for OTG mode.
After long time of executing LP0 cycles some times device fails to handle the
udc irq in OTG mode. This is due to the OTG state which is changed to unknown
before the controller is completely stopped. Fixed this by setting OTG state
properly to unknown only after disabling the interrupts and stopping the
controller completely in suspend path.
Change-Id: I4baf2f29857cd35937acc67aca7c01077e362be1
Reviewed-on: http://git-master/r/4016
Reviewed-by: Narendra Damahe <ndamahe@nvidia.com>
Tested-by: Narendra Damahe <ndamahe@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | drivers/usb/gadget/fsl_udc_core.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index b1eb9a4be5c7..604998f60384 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -370,6 +370,10 @@ static void dr_controller_stop(struct fsl_udc *udc) { unsigned int tmp; + /* Clear pending interrupt status bits */ + tmp = fsl_readl(&dr_regs->usbsts); + fsl_writel(tmp, &dr_regs->usbsts); + /* disable all INTR */ fsl_writel(0, &dr_regs->usbintr); @@ -2929,8 +2933,6 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) if (udc_controller->transceiver->state != OTG_STATE_B_PERIPHERAL) { /* we are not in device mode, return */ return 0; - } else { - udc_controller->transceiver->state = OTG_STATE_UNDEFINED; } } if (udc_controller->vbus_active) @@ -2944,6 +2946,9 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) } /* stop the controller and turn off the clocks */ dr_controller_stop(udc_controller); + if (udc_controller->transceiver) { + udc_controller->transceiver->state = OTG_STATE_UNDEFINED; + } platform_udc_clk_suspend(); return 0; } |