summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkat Moganty <vmoganty@nvidia.com>2010-07-17 10:49:42 +0530
committerGary King <gking@nvidia.com>2010-07-19 13:39:44 -0700
commit26c1256a07f2143bf0765dd49454557e710bff78 (patch)
treee159fbcc802e578e30acff653ab382aa3c79971c
parentcabc1827ba228b0901c7276979e990734385e980 (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.c9
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;
}