From e72831f9e03e087e7b5b48c0902a4473eba2876f Mon Sep 17 00:00:00 2001 From: Benoit Goby Date: Mon, 9 Aug 2010 20:49:09 -0700 Subject: [PATCH] usb: gadget: In OTG mode, power down the controller on probe The OTG driver will power it up on ID pin detection. This avoids race conditions when the device is powered on with the otg cable attached. Change-Id: I6bd5f1d73284f9b8534ef3dfb936b81a9400fa5b Signed-off-by: Benoit Goby --- drivers/usb/gadget/fsl_udc_core.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 7bbe2fb69d9d..00961da072fa 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1951,14 +1951,14 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) goto out; } - if (udc_controller->transceiver) - otg_set_peripheral(udc_controller->transceiver, &udc_controller->gadget); - /* Enable DR IRQ reg and Set usbcmd reg Run bit */ - dr_controller_run(udc_controller); - udc_controller->usb_state = USB_STATE_ATTACHED; - udc_controller->ep0_state = WAIT_FOR_SETUP; - udc_controller->ep0_dir = 0; + if (!udc_controller->transceiver) { + dr_controller_run(udc_controller); + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_state = WAIT_FOR_SETUP; + udc_controller->ep0_dir = 0; + } + printk(KERN_INFO "%s: bind to driver %s\n", udc_controller->gadget.name, driver->driver.name); @@ -1982,9 +1982,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!driver || driver != udc_controller->driver || !driver->unbind) return -EINVAL; - if (udc_controller->transceiver) - otg_set_peripheral(udc_controller->transceiver, NULL); - /* stop DR, disable intr */ dr_controller_stop(udc_controller); @@ -2560,8 +2557,13 @@ static int __init fsl_udc_probe(struct platform_device *pdev) #ifdef CONFIG_USB_OTG_UTILS udc_controller->transceiver = otg_get_transceiver(); - if (udc_controller->transceiver) - udc_controller->vbus_active = 1; + if (udc_controller->transceiver) { + dr_controller_stop(udc_controller); + fsl_udc_clk_suspend(); + udc_controller->vbus_active = 0; + udc_controller->usb_state = USB_STATE_DEFAULT; + otg_set_peripheral(udc_controller->transceiver, &udc_controller->gadget); + } #else #ifdef CONFIG_ARCH_TEGRA /* Power down the phy if cable is not connected */ @@ -2601,6 +2603,9 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) return -ENODEV; udc_controller->done = &done; + if (udc_controller->transceiver) + otg_set_peripheral(udc_controller->transceiver, NULL); + fsl_udc_clk_release(); /* DR has been stopped in usb_gadget_unregister_driver() */ -- 2.34.1