summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2011-08-11 17:17:29 +0800
committerPeter Chen <peter.chen@freescale.com>2011-08-17 16:54:14 +0800
commit29c4a238b447957ebe2a40082f00ef36897f36a6 (patch)
tree545654ca7251a9349971ed37428a3fbd0d7793a4
parent52660b68b23fe00b98e4ef461f90b6cfff1459a1 (diff)
ENGR00154044 usb-otg: the device is invalid when usb device at otg port
Below bugs are fixes: - the device is invalid when usb device at otg port The reason is udc->suspended is incorrect when otg as host mode during boot up - The disconnect can't be detected if usb is online when booting up The reason is the vbus interrupt enable is cleared by otg switch work Signed-off-by: Peter Chen <peter.chen@freescale.com>
-rw-r--r--drivers/usb/gadget/arcotg_udc.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index ac50e8430a60..fb5e8a83a8bd 100644
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -2305,8 +2305,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
}
if (udc_controller->transceiver) {
- /* Suspend the controller until OTG enable it */
- udc_controller->suspended = 1;/* let the otg resume it */
+ if (fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)
+ udc_controller->suspended = 1;/* let the otg resume it */
+ else
+ udc_controller->suspended = 0;/* let the otg suspend it */
printk(KERN_DEBUG "Suspend udc for OTG auto detect\n");
dr_wake_up_enable(udc_controller, true);
dr_clk_gate(false);
@@ -3202,6 +3204,20 @@ static int fsl_udc_resume(struct platform_device *pdev)
udc_controller->stopped, udc_controller->suspended);
/* Do noop if the udc is already at resume state */
if (udc_controller->suspended == 0) {
+ u32 temp;
+ if (udc_controller->stopped)
+ dr_clk_gate(true);
+ usb_debounce_id_vbus();
+ if (fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID) {
+ temp = fsl_readl(&dr_regs->otgsc);
+ /* if b_session_irq_en is cleared by otg */
+ if (!(temp & OTGSC_B_SESSION_VALID_IRQ_EN)) {
+ temp |= OTGSC_B_SESSION_VALID_IRQ_EN;
+ fsl_writel(temp, &dr_regs->otgsc);
+ }
+ }
+ if (udc_controller->stopped)
+ dr_clk_gate(false);
mutex_unlock(&udc_resume_mutex);
return 0;
}