linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
@ 2016-03-17 21:26 Pavel Machek
  2016-03-18  7:47 ` Ruslan Bilovol
  0 siblings, 1 reply; 18+ messages in thread
From: Pavel Machek @ 2016-03-17 21:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

USB gadget stops working for me on n900, if I merge

usb: gadget: bind UDC by name passed via usb_gadget_driver structure

patch.

commit 2284b29d3d9dd16490909962574d7f3fef83fd97
Author: Ruslan Bilovol <ruslan.bilovol@gmail.com>
Date:   Mon Nov 23 09:56:35 2015 +0100

    usb: gadget: bind UDC by name passed via usb_gadget_driver
    structure

    Introduce new 'udc_name' member to usb_gadget_driver structure.
        The 'udc_name' is a name of UDC that usb_gadget_driver should
	    be bound to. If udc_name is NULL, it will be bound to any
	        available UDC.

    Tested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
        Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
	    Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
	        Tested-by: Peter Chen <peter.chen@freescale.com>
		    Signed-off-by: Felipe Balbi <balbi@ti.com>


Patch is obvious enough... if there's someone who sets udc_name to
NULL. Who is supposed to do that?

(I have patch in my tree to make USB gadget work when it is not
modular).

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-17 21:26 usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure Pavel Machek
@ 2016-03-18  7:47 ` Ruslan Bilovol
  2016-03-18  9:32   ` Pavel Machek
  2016-03-18 20:20   ` Pavel Machek
  0 siblings, 2 replies; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-18  7:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Pavel

On Thu, Mar 17, 2016 at 11:26 PM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
> USB gadget stops working for me on n900, if I merge

Could you please give us more details?
Which gadget driver do you use (g_nokia?)

>
> usb: gadget: bind UDC by name passed via usb_gadget_driver structure
>
> patch.
>
> commit 2284b29d3d9dd16490909962574d7f3fef83fd97
> Author: Ruslan Bilovol <ruslan.bilovol@gmail.com>
> Date:   Mon Nov 23 09:56:35 2015 +0100
>
>     usb: gadget: bind UDC by name passed via usb_gadget_driver
>     structure
>
>     Introduce new 'udc_name' member to usb_gadget_driver structure.
>         The 'udc_name' is a name of UDC that usb_gadget_driver should
>             be bound to. If udc_name is NULL, it will be bound to any
>                 available UDC.
>
>     Tested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>         Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
>             Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>                 Tested-by: Peter Chen <peter.chen@freescale.com>
>                     Signed-off-by: Felipe Balbi <balbi@ti.com>
>
>
> Patch is obvious enough... if there's someone who sets udc_name to
> NULL. Who is supposed to do that?

That is done automatically if you use libcomposite.
There is a static usb_gadget_driver composite_driver_template structure in
composite.c that is used in usb_composite_probe later (used by libcomposite
based gadgets). Since it's statically declared, 'udc_name' member is set
to NULL automatically.

Other gadgets (not based on libcomposite) use same approach with
statically declared usb_gadget_driver structure.

>
> (I have patch in my tree to make USB gadget work when it is not
> modular).

So this can be reproduced only on builtin gadget, right?

BTW, I have N900 and can try to play with it this weekend if you'll
give us more details.

Best regards,
Ruslan

>
> Best regards,
>                                                                         Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-18  7:47 ` Ruslan Bilovol
@ 2016-03-18  9:32   ` Pavel Machek
  2016-03-18 20:20   ` Pavel Machek
  1 sibling, 0 replies; 18+ messages in thread
From: Pavel Machek @ 2016-03-18  9:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> On Thu, Mar 17, 2016 at 11:26 PM, Pavel Machek <pavel@ucw.cz> wrote:
> > Hi!
> >
> > USB gadget stops working for me on n900, if I merge
> 
> Could you please give us more details?
> Which gadget driver do you use (g_nokia?)

It seems I mis-merged the stuff. Hold on, I'm debugging it some more.

Not g_nokia:

CONFIG_USB_LIBCOMPOSITE=y
CONFIG_USB_U_ETHER=y
CONFIG_USB_F_ECM=y
CONFIG_USB_F_SUBSET=y


> > (I have patch in my tree to make USB gadget work when it is not
> > modular).
> 
> So this can be reproduced only on builtin gadget, right?
> 
> BTW, I have N900 and can try to play with it this weekend if you'll
> give us more details.

Thanks! Let me try to debug it, then I'll post .config.

Best regards,
									Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-18  7:47 ` Ruslan Bilovol
  2016-03-18  9:32   ` Pavel Machek
@ 2016-03-18 20:20   ` Pavel Machek
  2016-03-21 11:51     ` Marek Szyprowski
  1 sibling, 1 reply; 18+ messages in thread
From: Pavel Machek @ 2016-03-18 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> > USB gadget stops working for me on n900, if I merge
> 
> Could you please give us more details?
> Which gadget driver do you use (g_nokia?)

Ok, so I could get it to work with v4.5, and this patch. I'm including
my config, too. No, I don't think I'm using g_nokia.

Best regards,
								Pavel

diff --git a/.config b/.config
new file mode 100644
index 0000000..a504a94
--- /dev/null
+++ b/.config
...
+# CONFIG_USB_SWITCH_FSA9480 is not set
+# CONFIG_LATTICE_ECP3_CONFIG is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+CONFIG_NET_VENDOR_WIZNET=y
+# CONFIG_WIZNET_W5100 is not set
+# CONFIG_WIZNET_W5300 is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_MICREL_KS8995MA is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_USB_NET_DRIVERS=y
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_RTL8152 is not set
+# CONFIG_USB_LAN78XX is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+CONFIG_WLAN=y
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+# CONFIG_WLAN_VENDOR_MARVELL is not set
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# I2C HID support
+#
+# CONFIG_I2C_HID is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEFAULT_PERSIST=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_ULPI_BUS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_FOTG210_HCD is not set
+# CONFIG_USB_MAX3421_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HCD_TEST_MODE is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USBIP_CORE is not set
+CONFIG_USB_MUSB_HDRC=y
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_GADGET=y
+# CONFIG_USB_MUSB_DUAL_ROLE is not set
+
+#
+# Platform Glue Layer
+#
+# CONFIG_USB_MUSB_TUSB6010 is not set
+CONFIG_USB_MUSB_OMAP2PLUS=y
+# CONFIG_USB_MUSB_AM35X is not set
+# CONFIG_USB_MUSB_DSPS is not set
+
+#
+# MUSB DMA mode
+#
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_DWC3 is not set
+# CONFIG_USB_DWC2 is not set
+# CONFIG_USB_CHIPIDEA is not set
+# CONFIG_USB_ISP1760 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index b86a6f0..bee109f 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -542,14 +542,37 @@ err1:
 	return ret;
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
+int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
+{
+	struct usb_udc *udc = NULL;
+	int ret = -ENODEV;
+
+	mutex_lock(&udc_lock);
+	list_for_each_entry(udc, &udc_list, list) {
+		ret = strcmp(name, dev_name(&udc->dev));
+		if (!ret)
+			break;
+	}
+	if (ret) {
+		ret = -ENODEV;
+		goto out;
+	}
+	if (udc->driver) {
+		ret = -EBUSY;
+		goto out;
+	}
+	ret = udc_bind_to_driver(udc, driver);
+out:
+	mutex_unlock(&udc_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
+
+int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
 	struct usb_udc		*udc = NULL;
 	int			ret = -ENODEV;
 
-	if (!driver || !driver->bind || !driver->setup)
-		return -EINVAL;
-
 	mutex_lock(&udc_lock);
 	if (driver->udc_name) {
 		list_for_each_entry(udc, &udc_list, list) {
@@ -567,16 +590,47 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 		}
 	}
 
-	list_add_tail(&driver->pending, &gadget_driver_pending_list);
+//	list_add_tail(&driver->pending, &gadget_driver_pending_list); FIXME
 	pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
 		driver->function);
+
 	mutex_unlock(&udc_lock);
-	return 0;
+	return ret;
 found:
 	ret = udc_bind_to_driver(udc, driver);
 	mutex_unlock(&udc_lock);
 	return ret;
 }
+
+#define USB_GADGET_BIND_RETRIES		5
+#define USB_GADGET_BIND_TIMEOUT		(3 * HZ)
+static void usb_gadget_work(struct work_struct *work)
+{
+	struct usb_gadget_driver *driver = container_of(work,
+						struct usb_gadget_driver,
+						work.work);
+	int res;
+	
+	if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
+		pr_err("couldn't find an available UDC\n");
+		return;
+	}
+
+	res = __usb_gadget_probe_driver(driver);
+	if (res == -ENODEV)
+		schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
+}
+
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
+{
+	if (!driver || !driver->bind || !driver->setup)
+		return -EINVAL;
+
+	INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
+	schedule_delayed_work(&driver->work, 0);
+
+	return 0;
+}
 EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
@@ -587,6 +641,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 	if (!driver || !driver->unbind)
 		return -EINVAL;
 
+	cancel_delayed_work(&driver->work);
+
 	mutex_lock(&udc_lock);
 	list_for_each_entry(udc, &udc_list, list)
 		if (udc->driver == driver) {
@@ -747,7 +803,7 @@ static int __init usb_udc_init(void)
 	udc_class->dev_uevent = usb_udc_uevent;
 	return 0;
 }
-subsys_initcall(usb_udc_init);
+late_initcall_sync(usb_udc_init);
 
 static void __exit usb_udc_exit(void)
 {
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index d82d006..adb1e68 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1014,6 +1014,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
  * @resume: Invoked on USB resume.  May be called in_interrupt.
  * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
  *	and should be called in_interrupt.
+ * @work: Gadget work used to bind to the USB controller.
+ * @retries: Gadget retries to bind to the USB controller.
  * @driver: Driver model state for this driver.
  * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL,
  *	this driver will be bound to any available UDC.
@@ -1075,6 +1077,8 @@ struct usb_gadget_driver {
 	void			(*suspend)(struct usb_gadget *);
 	void			(*resume)(struct usb_gadget *);
 	void			(*reset)(struct usb_gadget *);
+	struct delayed_work	work;
+	int			retries;
 
 	/* FIXME support safe rmmod */
 	struct device_driver	driver;

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-18 20:20   ` Pavel Machek
@ 2016-03-21 11:51     ` Marek Szyprowski
  2016-03-23 12:21       ` Pavel Machek
  0 siblings, 1 reply; 18+ messages in thread
From: Marek Szyprowski @ 2016-03-21 11:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On 2016-03-18 21:20, Pavel Machek wrote:
> Hi!
>
>>> USB gadget stops working for me on n900, if I merge
>> Could you please give us more details?
>> Which gadget driver do you use (g_nokia?)
> Ok, so I could get it to work with v4.5, and this patch. I'm including
> my config, too. No, I don't think I'm using g_nokia.

This shows that there are some serious problems, probably with your udc 
driver, which doesn't handle deferred probe properly. Your patch 
workaround it by waiting some predefined time before registering gadget 
driver, however this is not the proper way. Please try to isolate what 
exactly is needed to get the gadget driver registered properly in your 
system or at least please provide some logs from the failed case.


>
> Best regards,
> 								Pavel
>
> diff --git a/.config b/.config
> new file mode 100644
> index 0000000..a504a94
> --- /dev/null
> +++ b/.config
> ...
> +# CONFIG_USB_SWITCH_FSA9480 is not set
> +# CONFIG_LATTICE_ECP3_CONFIG is not set
> +# CONFIG_SRAM is not set
> +# CONFIG_C2PORT is not set
> +
> +CONFIG_NET_VENDOR_WIZNET=y
> +# CONFIG_WIZNET_W5100 is not set
> +# CONFIG_WIZNET_W5300 is not set
> +# CONFIG_PHYLIB is not set
> +# CONFIG_MICREL_KS8995MA is not set
> +# CONFIG_PPP is not set
> +# CONFIG_SLIP is not set
> +CONFIG_USB_NET_DRIVERS=y
> +# CONFIG_USB_CATC is not set
> +# CONFIG_USB_KAWETH is not set
> +# CONFIG_USB_PEGASUS is not set
> +# CONFIG_USB_RTL8150 is not set
> +# CONFIG_USB_RTL8152 is not set
> +# CONFIG_USB_LAN78XX is not set
> +# CONFIG_USB_USBNET is not set
> +# CONFIG_USB_IPHETH is not set
> +CONFIG_WLAN=y
> +# CONFIG_WLAN_VENDOR_ADMTEK is not set
> +# CONFIG_WLAN_VENDOR_ATH is not set
> +# CONFIG_WLAN_VENDOR_ATMEL is not set
> +# CONFIG_WLAN_VENDOR_BROADCOM is not set
> +# CONFIG_WLAN_VENDOR_CISCO is not set
> +# CONFIG_WLAN_VENDOR_INTEL is not set
> +# CONFIG_WLAN_VENDOR_INTERSIL is not set
> +# CONFIG_WLAN_VENDOR_MARVELL is not set
> +
> +#
> +# USB HID support
> +#
> +CONFIG_USB_HID=y
> +# CONFIG_HID_PID is not set
> +# CONFIG_USB_HIDDEV is not set
> +
> +#
> +# I2C HID support
> +#
> +# CONFIG_I2C_HID is not set
> +CONFIG_USB_OHCI_LITTLE_ENDIAN=y
> +CONFIG_USB_SUPPORT=y
> +CONFIG_USB_COMMON=y
> +CONFIG_USB_ARCH_HAS_HCD=y
> +CONFIG_USB=y
> +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
> +
> +#
> +# Miscellaneous USB options
> +#
> +CONFIG_USB_DEFAULT_PERSIST=y
> +# CONFIG_USB_DYNAMIC_MINORS is not set
> +# CONFIG_USB_OTG is not set
> +# CONFIG_USB_OTG_WHITELIST is not set
> +# CONFIG_USB_OTG_BLACKLIST_HUB is not set
> +# CONFIG_USB_ULPI_BUS is not set
> +# CONFIG_USB_MON is not set
> +# CONFIG_USB_WUSB_CBAF is not set
> +
> +#
> +# USB Host Controller Drivers
> +#
> +# CONFIG_USB_C67X00_HCD is not set
> +# CONFIG_USB_XHCI_HCD is not set
> +# CONFIG_USB_EHCI_HCD is not set
> +# CONFIG_USB_OXU210HP_HCD is not set
> +# CONFIG_USB_ISP116X_HCD is not set
> +# CONFIG_USB_ISP1362_HCD is not set
> +# CONFIG_USB_FOTG210_HCD is not set
> +# CONFIG_USB_MAX3421_HCD is not set
> +# CONFIG_USB_OHCI_HCD is not set
> +# CONFIG_USB_SL811_HCD is not set
> +# CONFIG_USB_R8A66597_HCD is not set
> +# CONFIG_USB_HCD_TEST_MODE is not set
> +
> +#
> +# USB Device Class drivers
> +#
> +# CONFIG_USB_ACM is not set
> +# CONFIG_USB_PRINTER is not set
> +# CONFIG_USB_WDM is not set
> +# CONFIG_USB_TMC is not set
> +
> +#
> +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
> +#
> +
> +#
> +# also be needed; see USB_STORAGE Help for more info
> +#
> +# CONFIG_USB_STORAGE is not set
> +
> +#
> +# USB Imaging devices
> +#
> +# CONFIG_USB_MDC800 is not set
> +# CONFIG_USB_MICROTEK is not set
> +# CONFIG_USBIP_CORE is not set
> +CONFIG_USB_MUSB_HDRC=y
> +# CONFIG_USB_MUSB_HOST is not set
> +CONFIG_USB_MUSB_GADGET=y
> +# CONFIG_USB_MUSB_DUAL_ROLE is not set
> +
> +#
> +# Platform Glue Layer
> +#
> +# CONFIG_USB_MUSB_TUSB6010 is not set
> +CONFIG_USB_MUSB_OMAP2PLUS=y
> +# CONFIG_USB_MUSB_AM35X is not set
> +# CONFIG_USB_MUSB_DSPS is not set
> +
> +#
> +# MUSB DMA mode
> +#
> +CONFIG_MUSB_PIO_ONLY=y
> +# CONFIG_USB_DWC3 is not set
> +# CONFIG_USB_DWC2 is not set
> +# CONFIG_USB_CHIPIDEA is not set
> +# CONFIG_USB_ISP1760 is not set
> +
> +#
> +# USB port drivers
> +#
> +# CONFIG_USB_SERIAL is not set
> +
> diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
> index b86a6f0..bee109f 100644
> --- a/drivers/usb/gadget/udc/udc-core.c
> +++ b/drivers/usb/gadget/udc/udc-core.c
> @@ -542,14 +542,37 @@ err1:
>   	return ret;
>   }
>   
> -int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
> +int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
> +{
> +	struct usb_udc *udc = NULL;
> +	int ret = -ENODEV;
> +
> +	mutex_lock(&udc_lock);
> +	list_for_each_entry(udc, &udc_list, list) {
> +		ret = strcmp(name, dev_name(&udc->dev));
> +		if (!ret)
> +			break;
> +	}
> +	if (ret) {
> +		ret = -ENODEV;
> +		goto out;
> +	}
> +	if (udc->driver) {
> +		ret = -EBUSY;
> +		goto out;
> +	}
> +	ret = udc_bind_to_driver(udc, driver);
> +out:
> +	mutex_unlock(&udc_lock);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
> +
> +int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>   {
>   	struct usb_udc		*udc = NULL;
>   	int			ret = -ENODEV;
>   
> -	if (!driver || !driver->bind || !driver->setup)
> -		return -EINVAL;
> -
>   	mutex_lock(&udc_lock);
>   	if (driver->udc_name) {
>   		list_for_each_entry(udc, &udc_list, list) {
> @@ -567,16 +590,47 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>   		}
>   	}
>   
> -	list_add_tail(&driver->pending, &gadget_driver_pending_list);
> +//	list_add_tail(&driver->pending, &gadget_driver_pending_list); FIXME
>   	pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
>   		driver->function);
> +
>   	mutex_unlock(&udc_lock);
> -	return 0;
> +	return ret;
>   found:
>   	ret = udc_bind_to_driver(udc, driver);
>   	mutex_unlock(&udc_lock);
>   	return ret;
>   }
> +
> +#define USB_GADGET_BIND_RETRIES		5
> +#define USB_GADGET_BIND_TIMEOUT		(3 * HZ)
> +static void usb_gadget_work(struct work_struct *work)
> +{
> +	struct usb_gadget_driver *driver = container_of(work,
> +						struct usb_gadget_driver,
> +						work.work);
> +	int res;
> +	
> +	if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
> +		pr_err("couldn't find an available UDC\n");
> +		return;
> +	}
> +
> +	res = __usb_gadget_probe_driver(driver);
> +	if (res == -ENODEV)
> +		schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
> +}
> +
> +int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
> +{
> +	if (!driver || !driver->bind || !driver->setup)
> +		return -EINVAL;
> +
> +	INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
> +	schedule_delayed_work(&driver->work, 0);
> +
> +	return 0;
> +}
>   EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
>   
>   int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
> @@ -587,6 +641,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
>   	if (!driver || !driver->unbind)
>   		return -EINVAL;
>   
> +	cancel_delayed_work(&driver->work);
> +
>   	mutex_lock(&udc_lock);
>   	list_for_each_entry(udc, &udc_list, list)
>   		if (udc->driver == driver) {
> @@ -747,7 +803,7 @@ static int __init usb_udc_init(void)
>   	udc_class->dev_uevent = usb_udc_uevent;
>   	return 0;
>   }
> -subsys_initcall(usb_udc_init);
> +late_initcall_sync(usb_udc_init);
>   
>   static void __exit usb_udc_exit(void)
>   {
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index d82d006..adb1e68 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -1014,6 +1014,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
>    * @resume: Invoked on USB resume.  May be called in_interrupt.
>    * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
>    *	and should be called in_interrupt.
> + * @work: Gadget work used to bind to the USB controller.
> + * @retries: Gadget retries to bind to the USB controller.
>    * @driver: Driver model state for this driver.
>    * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL,
>    *	this driver will be bound to any available UDC.
> @@ -1075,6 +1077,8 @@ struct usb_gadget_driver {
>   	void			(*suspend)(struct usb_gadget *);
>   	void			(*resume)(struct usb_gadget *);
>   	void			(*reset)(struct usb_gadget *);
> +	struct delayed_work	work;
> +	int			retries;
>   
>   	/* FIXME support safe rmmod */
>   	struct device_driver	driver;
>

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-21 11:51     ` Marek Szyprowski
@ 2016-03-23 12:21       ` Pavel Machek
  2016-03-24  0:45         ` Ruslan Bilovol
  0 siblings, 1 reply; 18+ messages in thread
From: Pavel Machek @ 2016-03-23 12:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon 2016-03-21 12:51:51, Marek Szyprowski wrote:
> Hi
> 
> On 2016-03-18 21:20, Pavel Machek wrote:
> >Hi!
> >
> >>>USB gadget stops working for me on n900, if I merge
> >>Could you please give us more details?
> >>Which gadget driver do you use (g_nokia?)
> >Ok, so I could get it to work with v4.5, and this patch. I'm including
> >my config, too. No, I don't think I'm using g_nokia.
> 
> This shows that there are some serious problems, probably with your udc
> driver, which doesn't handle deferred probe properly. Your patch workaround
> it by waiting some predefined time before registering gadget driver, however
> this is not the proper way. Please try to isolate what exactly is needed to
> get the gadget driver registered properly in your system or at least please
> provide some logs from the failed case.

Well, Ruslan said he has n900 available, so I provided requested
information.

This is the dmesg with the hack:

[    0.623138] of_get_named_gpiod_flags: parsed 'ti,power-gpio'
property of node '/ocp/spi at 480ba00
0/wl1251 at 0[0]' - status (0)
[    0.623565] wl1251: ERROR vio regulator missing: -517
[    0.624359] musb probe HACK cf9a9e00
[    0.624420] musb probe HACK/2 cf9a9e00
[    0.624511] musb probe HACK/3 cf9a9e00
[    0.624755] HS USB OTG: no transceiver configured
[    0.624847] musb-hdrc musb-hdrc.0.auto: musb_init_controller failed
with status -517
[    0.626525] mousedev: PS/2 mouse device common for all mice
...
[    2.877441] ieee80211 phy1: Selected rate control algorithm
'minstrel'
[    2.879882] wl1251: loaded
[    2.889617] wl1251: initialized
[    2.897521] Two musb controllers?  HACK
[    2.904968] musb probe HACK cf9a9e00
[    2.912048] musb probe HACK/2 cf9a9e00
[    2.918823] musb probe HACK/3 cf9a9e00
[    2.928985] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk
combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[    2.929016] musb-hdrc: MHDRC RTL version 1.400
[    2.929046] musb-hdrc: setup fifo_mode 4
[    2.929077] musb-hdrc: 28/31 max ep, 16384/16384 memory
[    2.930511] tsc2005 spi1.0: GPIO lookup for consumer reset
[    2.930541] tsc2005 spi1.0: using device tree for GPIO lookup

In the kernel without the hack, there'll be only the first part of the
dmesg, AFAICT.

If there's an interest, I can repeat the test without the hack.

Thanks,
									Pavel


> >diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
> >index b86a6f0..bee109f 100644
> >--- a/drivers/usb/gadget/udc/udc-core.c
> >+++ b/drivers/usb/gadget/udc/udc-core.c
> >@@ -542,14 +542,37 @@ err1:
> >  	return ret;
> >  }
> >-int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
> >+int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
> >+{
> >+	struct usb_udc *udc = NULL;
> >+	int ret = -ENODEV;
> >+
> >+	mutex_lock(&udc_lock);
> >+	list_for_each_entry(udc, &udc_list, list) {
> >+		ret = strcmp(name, dev_name(&udc->dev));
> >+		if (!ret)
> >+			break;
> >+	}
> >+	if (ret) {
> >+		ret = -ENODEV;
> >+		goto out;
> >+	}
> >+	if (udc->driver) {
> >+		ret = -EBUSY;
> >+		goto out;
> >+	}
> >+	ret = udc_bind_to_driver(udc, driver);
> >+out:
> >+	mutex_unlock(&udc_lock);
> >+	return ret;
> >+}
> >+EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
> >+
> >+int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
> >  {
> >  	struct usb_udc		*udc = NULL;
> >  	int			ret = -ENODEV;
> >-	if (!driver || !driver->bind || !driver->setup)
> >-		return -EINVAL;
> >-
> >  	mutex_lock(&udc_lock);
> >  	if (driver->udc_name) {
> >  		list_for_each_entry(udc, &udc_list, list) {
> >@@ -567,16 +590,47 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
> >  		}
> >  	}
> >-	list_add_tail(&driver->pending, &gadget_driver_pending_list);
> >+//	list_add_tail(&driver->pending, &gadget_driver_pending_list); FIXME
> >  	pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
> >  		driver->function);
> >+
> >  	mutex_unlock(&udc_lock);
> >-	return 0;
> >+	return ret;
> >  found:
> >  	ret = udc_bind_to_driver(udc, driver);
> >  	mutex_unlock(&udc_lock);
> >  	return ret;
> >  }
> >+
> >+#define USB_GADGET_BIND_RETRIES		5
> >+#define USB_GADGET_BIND_TIMEOUT		(3 * HZ)
> >+static void usb_gadget_work(struct work_struct *work)
> >+{
> >+	struct usb_gadget_driver *driver = container_of(work,
> >+						struct usb_gadget_driver,
> >+						work.work);
> >+	int res;
> >+	
> >+	if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
> >+		pr_err("couldn't find an available UDC\n");
> >+		return;
> >+	}
> >+
> >+	res = __usb_gadget_probe_driver(driver);
> >+	if (res == -ENODEV)
> >+		schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
> >+}
> >+
> >+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
> >+{
> >+	if (!driver || !driver->bind || !driver->setup)
> >+		return -EINVAL;
> >+
> >+	INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
> >+	schedule_delayed_work(&driver->work, 0);
> >+
> >+	return 0;
> >+}
> >  EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
> >  int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
> >@@ -587,6 +641,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
> >  	if (!driver || !driver->unbind)
> >  		return -EINVAL;
> >+	cancel_delayed_work(&driver->work);
> >+
> >  	mutex_lock(&udc_lock);
> >  	list_for_each_entry(udc, &udc_list, list)
> >  		if (udc->driver == driver) {
> >@@ -747,7 +803,7 @@ static int __init usb_udc_init(void)
> >  	udc_class->dev_uevent = usb_udc_uevent;
> >  	return 0;
> >  }
> >-subsys_initcall(usb_udc_init);
> >+late_initcall_sync(usb_udc_init);
> >  static void __exit usb_udc_exit(void)
> >  {
> >diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> >index d82d006..adb1e68 100644
> >--- a/include/linux/usb/gadget.h
> >+++ b/include/linux/usb/gadget.h
> >@@ -1014,6 +1014,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
> >   * @resume: Invoked on USB resume.  May be called in_interrupt.
> >   * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
> >   *	and should be called in_interrupt.
> >+ * @work: Gadget work used to bind to the USB controller.
> >+ * @retries: Gadget retries to bind to the USB controller.
> >   * @driver: Driver model state for this driver.
> >   * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL,
> >   *	this driver will be bound to any available UDC.
> >@@ -1075,6 +1077,8 @@ struct usb_gadget_driver {
> >  	void			(*suspend)(struct usb_gadget *);
> >  	void			(*resume)(struct usb_gadget *);
> >  	void			(*reset)(struct usb_gadget *);
> >+	struct delayed_work	work;
> >+	int			retries;
> >  	/* FIXME support safe rmmod */
> >  	struct device_driver	driver;
> >
> 
> Best regards

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-23 12:21       ` Pavel Machek
@ 2016-03-24  0:45         ` Ruslan Bilovol
  2016-03-25  3:21           ` Ruslan Bilovol
  0 siblings, 1 reply; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-24  0:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Pavel,

I didn't use my N900 for years, it is deeply discharged and can't
boot, so I left it connected overnight to the wall adapter to let it
get some juice.

Meanwhile I looked into sources and still can't understand how
it happens.
Could you please attach your full .config and also dmesg
without hacks?

Regards,
Ruslan

On Wed, Mar 23, 2016 at 2:21 PM, Pavel Machek <pavel@ucw.cz> wrote:
> On Mon 2016-03-21 12:51:51, Marek Szyprowski wrote:
>> Hi
>>
>> On 2016-03-18 21:20, Pavel Machek wrote:
>> >Hi!
>> >
>> >>>USB gadget stops working for me on n900, if I merge
>> >>Could you please give us more details?
>> >>Which gadget driver do you use (g_nokia?)
>> >Ok, so I could get it to work with v4.5, and this patch. I'm including
>> >my config, too. No, I don't think I'm using g_nokia.
>>
>> This shows that there are some serious problems, probably with your udc
>> driver, which doesn't handle deferred probe properly. Your patch workaround
>> it by waiting some predefined time before registering gadget driver, however
>> this is not the proper way. Please try to isolate what exactly is needed to
>> get the gadget driver registered properly in your system or at least please
>> provide some logs from the failed case.
>
> Well, Ruslan said he has n900 available, so I provided requested
> information.
>
> This is the dmesg with the hack:
>
> [    0.623138] of_get_named_gpiod_flags: parsed 'ti,power-gpio'
> property of node '/ocp/spi at 480ba00
> 0/wl1251 at 0[0]' - status (0)
> [    0.623565] wl1251: ERROR vio regulator missing: -517
> [    0.624359] musb probe HACK cf9a9e00
> [    0.624420] musb probe HACK/2 cf9a9e00
> [    0.624511] musb probe HACK/3 cf9a9e00
> [    0.624755] HS USB OTG: no transceiver configured
> [    0.624847] musb-hdrc musb-hdrc.0.auto: musb_init_controller failed
> with status -517
> [    0.626525] mousedev: PS/2 mouse device common for all mice
> ...
> [    2.877441] ieee80211 phy1: Selected rate control algorithm
> 'minstrel'
> [    2.879882] wl1251: loaded
> [    2.889617] wl1251: initialized
> [    2.897521] Two musb controllers?  HACK
> [    2.904968] musb probe HACK cf9a9e00
> [    2.912048] musb probe HACK/2 cf9a9e00
> [    2.918823] musb probe HACK/3 cf9a9e00
> [    2.928985] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk
> combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
> [    2.929016] musb-hdrc: MHDRC RTL version 1.400
> [    2.929046] musb-hdrc: setup fifo_mode 4
> [    2.929077] musb-hdrc: 28/31 max ep, 16384/16384 memory
> [    2.930511] tsc2005 spi1.0: GPIO lookup for consumer reset
> [    2.930541] tsc2005 spi1.0: using device tree for GPIO lookup
>
> In the kernel without the hack, there'll be only the first part of the
> dmesg, AFAICT.
>
> If there's an interest, I can repeat the test without the hack.
>
> Thanks,
>                                                                         Pavel
>
>
>> >diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
>> >index b86a6f0..bee109f 100644
>> >--- a/drivers/usb/gadget/udc/udc-core.c
>> >+++ b/drivers/usb/gadget/udc/udc-core.c
>> >@@ -542,14 +542,37 @@ err1:
>> >     return ret;
>> >  }
>> >-int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>> >+int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
>> >+{
>> >+    struct usb_udc *udc = NULL;
>> >+    int ret = -ENODEV;
>> >+
>> >+    mutex_lock(&udc_lock);
>> >+    list_for_each_entry(udc, &udc_list, list) {
>> >+            ret = strcmp(name, dev_name(&udc->dev));
>> >+            if (!ret)
>> >+                    break;
>> >+    }
>> >+    if (ret) {
>> >+            ret = -ENODEV;
>> >+            goto out;
>> >+    }
>> >+    if (udc->driver) {
>> >+            ret = -EBUSY;
>> >+            goto out;
>> >+    }
>> >+    ret = udc_bind_to_driver(udc, driver);
>> >+out:
>> >+    mutex_unlock(&udc_lock);
>> >+    return ret;
>> >+}
>> >+EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
>> >+
>> >+int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>> >  {
>> >     struct usb_udc          *udc = NULL;
>> >     int                     ret = -ENODEV;
>> >-    if (!driver || !driver->bind || !driver->setup)
>> >-            return -EINVAL;
>> >-
>> >     mutex_lock(&udc_lock);
>> >     if (driver->udc_name) {
>> >             list_for_each_entry(udc, &udc_list, list) {
>> >@@ -567,16 +590,47 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>> >             }
>> >     }
>> >-    list_add_tail(&driver->pending, &gadget_driver_pending_list);
>> >+//  list_add_tail(&driver->pending, &gadget_driver_pending_list); FIXME
>> >     pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
>> >             driver->function);
>> >+
>> >     mutex_unlock(&udc_lock);
>> >-    return 0;
>> >+    return ret;
>> >  found:
>> >     ret = udc_bind_to_driver(udc, driver);
>> >     mutex_unlock(&udc_lock);
>> >     return ret;
>> >  }
>> >+
>> >+#define USB_GADGET_BIND_RETRIES             5
>> >+#define USB_GADGET_BIND_TIMEOUT             (3 * HZ)
>> >+static void usb_gadget_work(struct work_struct *work)
>> >+{
>> >+    struct usb_gadget_driver *driver = container_of(work,
>> >+                                            struct usb_gadget_driver,
>> >+                                            work.work);
>> >+    int res;
>> >+
>> >+    if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
>> >+            pr_err("couldn't find an available UDC\n");
>> >+            return;
>> >+    }
>> >+
>> >+    res = __usb_gadget_probe_driver(driver);
>> >+    if (res == -ENODEV)
>> >+            schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
>> >+}
>> >+
>> >+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>> >+{
>> >+    if (!driver || !driver->bind || !driver->setup)
>> >+            return -EINVAL;
>> >+
>> >+    INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
>> >+    schedule_delayed_work(&driver->work, 0);
>> >+
>> >+    return 0;
>> >+}
>> >  EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
>> >  int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
>> >@@ -587,6 +641,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
>> >     if (!driver || !driver->unbind)
>> >             return -EINVAL;
>> >+    cancel_delayed_work(&driver->work);
>> >+
>> >     mutex_lock(&udc_lock);
>> >     list_for_each_entry(udc, &udc_list, list)
>> >             if (udc->driver == driver) {
>> >@@ -747,7 +803,7 @@ static int __init usb_udc_init(void)
>> >     udc_class->dev_uevent = usb_udc_uevent;
>> >     return 0;
>> >  }
>> >-subsys_initcall(usb_udc_init);
>> >+late_initcall_sync(usb_udc_init);
>> >  static void __exit usb_udc_exit(void)
>> >  {
>> >diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
>> >index d82d006..adb1e68 100644
>> >--- a/include/linux/usb/gadget.h
>> >+++ b/include/linux/usb/gadget.h
>> >@@ -1014,6 +1014,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
>> >   * @resume: Invoked on USB resume.  May be called in_interrupt.
>> >   * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
>> >   * and should be called in_interrupt.
>> >+ * @work: Gadget work used to bind to the USB controller.
>> >+ * @retries: Gadget retries to bind to the USB controller.
>> >   * @driver: Driver model state for this driver.
>> >   * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL,
>> >   * this driver will be bound to any available UDC.
>> >@@ -1075,6 +1077,8 @@ struct usb_gadget_driver {
>> >     void                    (*suspend)(struct usb_gadget *);
>> >     void                    (*resume)(struct usb_gadget *);
>> >     void                    (*reset)(struct usb_gadget *);
>> >+    struct delayed_work     work;
>> >+    int                     retries;
>> >     /* FIXME support safe rmmod */
>> >     struct device_driver    driver;
>> >
>>
>> Best regards
>
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-24  0:45         ` Ruslan Bilovol
@ 2016-03-25  3:21           ` Ruslan Bilovol
  2016-03-25 21:09             ` Pavel Machek
                               ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-25  3:21 UTC (permalink / raw)
  To: linux-arm-kernel

OK, so at last I finished charging of my N900; found 1.8V USB
to UART adapter and soldered it to the phone.

I managed to boot N900 with working USB gadget (builtin g_ether)
in boardfile mode, can ping it from PC and transfer data. I don't
see any issue (except of musb name issue in twl phy driver, I've
already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )

Pavel, I still don't see how you've got your issue, please share
more detials

Regards,
Ruslan

On Thu, Mar 24, 2016 at 2:45 AM, Ruslan Bilovol
<ruslan.bilovol@gmail.com> wrote:
> Hi Pavel,
>
> I didn't use my N900 for years, it is deeply discharged and can't
> boot, so I left it connected overnight to the wall adapter to let it
> get some juice.
>
> Meanwhile I looked into sources and still can't understand how
> it happens.
> Could you please attach your full .config and also dmesg
> without hacks?
>
> Regards,
> Ruslan
>
> On Wed, Mar 23, 2016 at 2:21 PM, Pavel Machek <pavel@ucw.cz> wrote:
>> On Mon 2016-03-21 12:51:51, Marek Szyprowski wrote:
>>> Hi
>>>
>>> On 2016-03-18 21:20, Pavel Machek wrote:
>>> >Hi!
>>> >
>>> >>>USB gadget stops working for me on n900, if I merge
>>> >>Could you please give us more details?
>>> >>Which gadget driver do you use (g_nokia?)
>>> >Ok, so I could get it to work with v4.5, and this patch. I'm including
>>> >my config, too. No, I don't think I'm using g_nokia.
>>>
>>> This shows that there are some serious problems, probably with your udc
>>> driver, which doesn't handle deferred probe properly. Your patch workaround
>>> it by waiting some predefined time before registering gadget driver, however
>>> this is not the proper way. Please try to isolate what exactly is needed to
>>> get the gadget driver registered properly in your system or at least please
>>> provide some logs from the failed case.
>>
>> Well, Ruslan said he has n900 available, so I provided requested
>> information.
>>
>> This is the dmesg with the hack:
>>
>> [    0.623138] of_get_named_gpiod_flags: parsed 'ti,power-gpio'
>> property of node '/ocp/spi at 480ba00
>> 0/wl1251 at 0[0]' - status (0)
>> [    0.623565] wl1251: ERROR vio regulator missing: -517
>> [    0.624359] musb probe HACK cf9a9e00
>> [    0.624420] musb probe HACK/2 cf9a9e00
>> [    0.624511] musb probe HACK/3 cf9a9e00
>> [    0.624755] HS USB OTG: no transceiver configured
>> [    0.624847] musb-hdrc musb-hdrc.0.auto: musb_init_controller failed
>> with status -517
>> [    0.626525] mousedev: PS/2 mouse device common for all mice
>> ...
>> [    2.877441] ieee80211 phy1: Selected rate control algorithm
>> 'minstrel'
>> [    2.879882] wl1251: loaded
>> [    2.889617] wl1251: initialized
>> [    2.897521] Two musb controllers?  HACK
>> [    2.904968] musb probe HACK cf9a9e00
>> [    2.912048] musb probe HACK/2 cf9a9e00
>> [    2.918823] musb probe HACK/3 cf9a9e00
>> [    2.928985] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk
>> combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
>> [    2.929016] musb-hdrc: MHDRC RTL version 1.400
>> [    2.929046] musb-hdrc: setup fifo_mode 4
>> [    2.929077] musb-hdrc: 28/31 max ep, 16384/16384 memory
>> [    2.930511] tsc2005 spi1.0: GPIO lookup for consumer reset
>> [    2.930541] tsc2005 spi1.0: using device tree for GPIO lookup
>>
>> In the kernel without the hack, there'll be only the first part of the
>> dmesg, AFAICT.
>>
>> If there's an interest, I can repeat the test without the hack.
>>
>> Thanks,
>>                                                                         Pavel
>>
>>
>>> >diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
>>> >index b86a6f0..bee109f 100644
>>> >--- a/drivers/usb/gadget/udc/udc-core.c
>>> >+++ b/drivers/usb/gadget/udc/udc-core.c
>>> >@@ -542,14 +542,37 @@ err1:
>>> >     return ret;
>>> >  }
>>> >-int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>>> >+int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver)
>>> >+{
>>> >+    struct usb_udc *udc = NULL;
>>> >+    int ret = -ENODEV;
>>> >+
>>> >+    mutex_lock(&udc_lock);
>>> >+    list_for_each_entry(udc, &udc_list, list) {
>>> >+            ret = strcmp(name, dev_name(&udc->dev));
>>> >+            if (!ret)
>>> >+                    break;
>>> >+    }
>>> >+    if (ret) {
>>> >+            ret = -ENODEV;
>>> >+            goto out;
>>> >+    }
>>> >+    if (udc->driver) {
>>> >+            ret = -EBUSY;
>>> >+            goto out;
>>> >+    }
>>> >+    ret = udc_bind_to_driver(udc, driver);
>>> >+out:
>>> >+    mutex_unlock(&udc_lock);
>>> >+    return ret;
>>> >+}
>>> >+EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
>>> >+
>>> >+int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>>> >  {
>>> >     struct usb_udc          *udc = NULL;
>>> >     int                     ret = -ENODEV;
>>> >-    if (!driver || !driver->bind || !driver->setup)
>>> >-            return -EINVAL;
>>> >-
>>> >     mutex_lock(&udc_lock);
>>> >     if (driver->udc_name) {
>>> >             list_for_each_entry(udc, &udc_list, list) {
>>> >@@ -567,16 +590,47 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>>> >             }
>>> >     }
>>> >-    list_add_tail(&driver->pending, &gadget_driver_pending_list);
>>> >+//  list_add_tail(&driver->pending, &gadget_driver_pending_list); FIXME
>>> >     pr_info("udc-core: couldn't find an available UDC - added [%s] to list of pending drivers\n",
>>> >             driver->function);
>>> >+
>>> >     mutex_unlock(&udc_lock);
>>> >-    return 0;
>>> >+    return ret;
>>> >  found:
>>> >     ret = udc_bind_to_driver(udc, driver);
>>> >     mutex_unlock(&udc_lock);
>>> >     return ret;
>>> >  }
>>> >+
>>> >+#define USB_GADGET_BIND_RETRIES             5
>>> >+#define USB_GADGET_BIND_TIMEOUT             (3 * HZ)
>>> >+static void usb_gadget_work(struct work_struct *work)
>>> >+{
>>> >+    struct usb_gadget_driver *driver = container_of(work,
>>> >+                                            struct usb_gadget_driver,
>>> >+                                            work.work);
>>> >+    int res;
>>> >+
>>> >+    if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
>>> >+            pr_err("couldn't find an available UDC\n");
>>> >+            return;
>>> >+    }
>>> >+
>>> >+    res = __usb_gadget_probe_driver(driver);
>>> >+    if (res == -ENODEV)
>>> >+            schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
>>> >+}
>>> >+
>>> >+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>>> >+{
>>> >+    if (!driver || !driver->bind || !driver->setup)
>>> >+            return -EINVAL;
>>> >+
>>> >+    INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
>>> >+    schedule_delayed_work(&driver->work, 0);
>>> >+
>>> >+    return 0;
>>> >+}
>>> >  EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
>>> >  int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
>>> >@@ -587,6 +641,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
>>> >     if (!driver || !driver->unbind)
>>> >             return -EINVAL;
>>> >+    cancel_delayed_work(&driver->work);
>>> >+
>>> >     mutex_lock(&udc_lock);
>>> >     list_for_each_entry(udc, &udc_list, list)
>>> >             if (udc->driver == driver) {
>>> >@@ -747,7 +803,7 @@ static int __init usb_udc_init(void)
>>> >     udc_class->dev_uevent = usb_udc_uevent;
>>> >     return 0;
>>> >  }
>>> >-subsys_initcall(usb_udc_init);
>>> >+late_initcall_sync(usb_udc_init);
>>> >  static void __exit usb_udc_exit(void)
>>> >  {
>>> >diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
>>> >index d82d006..adb1e68 100644
>>> >--- a/include/linux/usb/gadget.h
>>> >+++ b/include/linux/usb/gadget.h
>>> >@@ -1014,6 +1014,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
>>> >   * @resume: Invoked on USB resume.  May be called in_interrupt.
>>> >   * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
>>> >   * and should be called in_interrupt.
>>> >+ * @work: Gadget work used to bind to the USB controller.
>>> >+ * @retries: Gadget retries to bind to the USB controller.
>>> >   * @driver: Driver model state for this driver.
>>> >   * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL,
>>> >   * this driver will be bound to any available UDC.
>>> >@@ -1075,6 +1077,8 @@ struct usb_gadget_driver {
>>> >     void                    (*suspend)(struct usb_gadget *);
>>> >     void                    (*resume)(struct usb_gadget *);
>>> >     void                    (*reset)(struct usb_gadget *);
>>> >+    struct delayed_work     work;
>>> >+    int                     retries;
>>> >     /* FIXME support safe rmmod */
>>> >     struct device_driver    driver;
>>> >
>>>
>>> Best regards
>>
>> --
>> (english) http://www.livejournal.com/~pavelmachek
>> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-25  3:21           ` Ruslan Bilovol
@ 2016-03-25 21:09             ` Pavel Machek
  2016-03-26 21:32               ` Ruslan Bilovol
  2016-03-25 21:15             ` Pavel Machek
  2016-03-25 21:30             ` Pavel Machek
  2 siblings, 1 reply; 18+ messages in thread
From: Pavel Machek @ 2016-03-25 21:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> OK, so at last I finished charging of my N900; found 1.8V USB
> to UART adapter and soldered it to the phone.
> 
> I managed to boot N900 with working USB gadget (builtin g_ether)
> in boardfile mode, can ping it from PC and transfer data. I don't
> see any issue (except of musb name issue in twl phy driver, I've
> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
> 
> Pavel, I still don't see how you've got your issue, please share
> more detials

Ok, let me try. I undid all the changes in drivers/phy drivers/usb and
include/linux/usb . I have all the gadget stuff built-in, so that I
could use nfsroot, but this is boot from mmcblk.

gzipped config is attached.

PC is unable to work with the gadget:

[256526.716099] usb 2-1: new full-speed USB device number 52 using
uhci_hcd
[256526.832091] usb 2-1: device descriptor read/64, error -32
[256527.052095] usb 2-1: device descriptor read/64, error -32
[256527.268160] usb 2-1: new full-speed USB device number 53 using
uhci_hcd
[256527.388121] usb 2-1: device descriptor read/64, error -32
[256527.608116] usb 2-1: device descriptor read/64, error -32
[256527.824170] usb 2-1: new full-speed USB device number 54 using
uhci_hcd
[256527.851175] usb 2-1: device descriptor read/8, error -32
[256527.975175] usb 2-1: device descriptor read/8, error -32
[256528.188133] usb 2-1: new full-speed USB device number 55 using
uhci_hcd
[256528.218184] usb 2-1: device descriptor read/8, error -32
[256528.343183] usb 2-1: device descriptor read/8, error -32
[256528.444314] usb usb2-port1: unable to enumerate USB device

Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
devicetree boot.

Best regards,

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: config.gz
Type: application/gzip
Size: 24252 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160325/4926a928/attachment-0002.gz>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: delme.gz
Type: application/gzip
Size: 9443 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160325/4926a928/attachment-0003.gz>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-25  3:21           ` Ruslan Bilovol
  2016-03-25 21:09             ` Pavel Machek
@ 2016-03-25 21:15             ` Pavel Machek
  2016-03-26 21:41               ` Ruslan Bilovol
  2016-03-25 21:30             ` Pavel Machek
  2 siblings, 1 reply; 18+ messages in thread
From: Pavel Machek @ 2016-03-25 21:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> OK, so at last I finished charging of my N900; found 1.8V USB
> to UART adapter and soldered it to the phone.
> 
> I managed to boot N900 with working USB gadget (builtin g_ether)
> in boardfile mode, can ping it from PC and transfer data. I don't
> see any issue (except of musb name issue in twl phy driver, I've
> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )

I tried to add that one, too, and no change. Can I get your .config?

Thanks and best regards,
								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-25  3:21           ` Ruslan Bilovol
  2016-03-25 21:09             ` Pavel Machek
  2016-03-25 21:15             ` Pavel Machek
@ 2016-03-25 21:30             ` Pavel Machek
  2 siblings, 0 replies; 18+ messages in thread
From: Pavel Machek @ 2016-03-25 21:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> OK, so at last I finished charging of my N900; found 1.8V USB
> to UART adapter and soldered it to the phone.
> 
> I managed to boot N900 with working USB gadget (builtin g_ether)
> in boardfile mode, can ping it from PC and transfer data. I don't
> see any issue (except of musb name issue in twl phy driver, I've
> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
> 
> Pavel, I still don't see how you've got your issue, please share
> more detials

And for completenes, this is (reverted) patch that fixes the issue for
me. Hmm. That looks a bit too big.

Doing the revert, and PC is happy: first we boot from NOLO, then Linux
boots and we detect USB gadget.

Best regards,
								Pavel

[258134.206143] usb 1-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=5
[258134.206149] usb 1-1: Product: Nokia N900 (Update mode)
[258134.206154] usb 1-1: Manufacturer: Nokia
[258134.206158] usb 1-1: SerialNumber: 4D554D333032393332
[258135.695868] usb 1-1: USB disconnect, device number 97
[258144.192099] usb 1-1: new high-speed USB device number 98 using
ehci-pci
[258144.326465] usb 1-1: New USB device found, idVendor=0421,
idProduct=01c7
[258144.326474] usb 1-1: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[258144.326479] usb 1-1: Product: N900 (Storage Mode)
[258144.326482] usb 1-1: Manufacturer: Nokia
[258144.326486] usb 1-1: SerialNumber: 372041756775
[258144.330518] usb-storage 1-1:1.0: USB Mass Storage device detected
[258144.331737] scsi host14: usb-storage 1-1:1.0
[258145.333287] scsi 14:0:0:0: Direct-Access     Nokia    N900
031 PQ: 0 ANSI: 2
[258145.337226] sd 14:0:0:0: Attached scsi generic sg1 type 0
[258145.343359] sd 14:0:0:0: [sdb] Attached SCSI removable disk
[258145.343717] scsi 14:0:0:1: Direct-Access     Nokia    N900
031 PQ: 0 ANSI: 2
[258145.347245] sd 14:0:0:1: Attached scsi generic sg2 type 0
[258145.352379] sd 14:0:0:1: [sdc] Attached SCSI removable disk
pavel at duo:/data/l/linux-n900$



Best regards,
								Pavel

diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 9708cf5..ce18f57 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -34,7 +34,7 @@
 #include <linux/usb/otg.h>
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/musb.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/usb/ulpi.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
@@ -148,10 +148,10 @@
  * If VBUS is valid or ID is ground, then we know a
  * cable is present and we need to be runtime-enabled
  */
-static inline bool cable_present(enum musb_vbus_id_status stat)
+static inline bool cable_present(enum omap_musb_vbus_id_status stat)
 {
-	return stat == MUSB_VBUS_VALID ||
-		stat == MUSB_ID_GROUND;
+	return stat == OMAP_MUSB_VBUS_VALID ||
+		stat == OMAP_MUSB_ID_GROUND;
 }
 
 struct twl4030_usb {
@@ -170,7 +170,7 @@ struct twl4030_usb {
 	enum twl4030_usb_mode	usb_mode;
 
 	int			irq;
-	enum musb_vbus_id_status linkstat;
+	enum omap_musb_vbus_id_status linkstat;
 	bool			vbus_supplied;
 
 	struct delayed_work	id_workaround_work;
@@ -276,11 +276,11 @@ static bool twl4030_is_driving_vbus(struct twl4030_usb *twl)
 	return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false;
 }
 
-static enum musb_vbus_id_status
+static enum omap_musb_vbus_id_status
 	twl4030_usb_linkstat(struct twl4030_usb *twl)
 {
 	int	status;
-	enum musb_vbus_id_status linkstat = MUSB_UNKNOWN;
+	enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN;
 
 	twl->vbus_supplied = false;
 
@@ -306,14 +306,14 @@ static enum musb_vbus_id_status
 		}
 
 		if (status & BIT(2))
-			linkstat = MUSB_ID_GROUND;
+			linkstat = OMAP_MUSB_ID_GROUND;
 		else if (status & BIT(7))
-			linkstat = MUSB_VBUS_VALID;
+			linkstat = OMAP_MUSB_VBUS_VALID;
 		else
-			linkstat = MUSB_VBUS_OFF;
+			linkstat = OMAP_MUSB_VBUS_OFF;
 	} else {
-		if (twl->linkstat != MUSB_UNKNOWN)
-			linkstat = MUSB_VBUS_OFF;
+		if (twl->linkstat != OMAP_MUSB_UNKNOWN)
+			linkstat = OMAP_MUSB_VBUS_OFF;
 	}
 
 	dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
@@ -532,47 +532,10 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev,
 }
 static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
 
-static ssize_t twl4030_test_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct twl4030_usb *twl = dev_get_drvdata(dev);
-	int ret = -EINVAL;
-
-	mutex_lock(&twl->lock);
-	ret = sprintf(buf, "%s\n", "hello, world");
-	mutex_unlock(&twl->lock);
-
-	return ret;
-}
-
-static int twl4030_shutdown(struct twl4030_usb *twl);
-
-static ssize_t twl4030_test_store(struct device *dev,
-		 struct device_attribute *attr, const char *buf, size_t count)
-{
-	unsigned long tmp;
-
-	struct twl4030_usb *twl = dev_get_drvdata(dev);
-
-	mutex_lock(&twl->lock);
-	sscanf(buf, "%lX", &tmp);
-	printk("TWL HACK: tmp = 0x%lX\n", tmp);
-	mutex_unlock(&twl->lock);
-
-	if (tmp == 0xdead) {
-		printk("TWL HACK: killing hardware\n");
-		printk("TWL HACK: killing hardware = %d\n", twl4030_shutdown(twl));
-	}
-	
-	return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(test, 0664, twl4030_test_show, twl4030_test_store);
-
 static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 {
 	struct twl4030_usb *twl = _twl;
-	enum musb_vbus_id_status status;
+	enum omap_musb_vbus_id_status status;
 	bool status_changed = false;
 
 	status = twl4030_usb_linkstat(twl);
@@ -604,11 +567,11 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 			pm_runtime_mark_last_busy(twl->dev);
 			pm_runtime_put_autosuspend(twl->dev);
 		}
-		musb_mailbox(status);
+		omap_musb_mailbox(status);
 	}
 
 	/* don't schedule during sleep - irq works right then */
-	if (status == MUSB_ID_GROUND && pm_runtime_active(twl->dev)) {
+	if (status == OMAP_MUSB_ID_GROUND && pm_runtime_active(twl->dev)) {
 		cancel_delayed_work(&twl->id_workaround_work);
 		schedule_delayed_work(&twl->id_workaround_work, HZ);
 	}
@@ -707,7 +670,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	twl->dev		= &pdev->dev;
 	twl->irq		= platform_get_irq(pdev, 0);
 	twl->vbus_supplied	= false;
-	twl->linkstat		= MUSB_UNKNOWN;
+	twl->linkstat		= OMAP_MUSB_UNKNOWN;
 
 	twl->phy.dev		= twl->dev;
 	twl->phy.label		= "twl4030";
@@ -747,15 +710,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	if (device_create_file(&pdev->dev, &dev_attr_vbus))
 		dev_warn(&pdev->dev, "could not create sysfs file\n");
 
-	if (device_create_file(&pdev->dev, &dev_attr_test))
-		dev_warn(&pdev->dev, "could not create sysfs file #2\n");
-	
 	ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
 
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
 	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
 
 	/* Our job is to use irqs and status from the power module
 	 * to keep the transceiver disabled when nothing's connected.
@@ -775,7 +734,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	}
 
 	if (pdata)
-		err = phy_create_lookup(phy, "usb", "musb-hdrc.0");
+		err = phy_create_lookup(phy, "usb", "musb-hdrc.0.auto");
 	if (err)
 		return err;
 
@@ -786,24 +745,18 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int twl4030_shutdown(struct twl4030_usb *twl)
+static int twl4030_usb_remove(struct platform_device *pdev)
 {
+	struct twl4030_usb *twl = platform_get_drvdata(pdev);
 	int val;
 
-	usb_remove_phy(&twl->phy);
 	pm_runtime_get_sync(twl->dev);
 	cancel_delayed_work(&twl->id_workaround_work);
+	device_remove_file(twl->dev, &dev_attr_vbus);
 
 	/* set transceiver mode to power on defaults */
 	twl4030_usb_set_mode(twl, -1);
 
-	/* idle ulpi before powering off */
-	if (cable_present(twl->linkstat))
-	pm_runtime_put_noidle(twl->dev);
-	pm_runtime_mark_last_busy(twl->dev);
-	pm_runtime_put_sync_suspend(twl->dev);
-	pm_runtime_disable(twl->dev);
-
 	/* autogate 60MHz ULPI clock,
 	 * clear dpll clock request for i2c access,
 	 * disable 32KHz
@@ -818,18 +771,12 @@ static int twl4030_shutdown(struct twl4030_usb *twl)
 	/* disable complete OTG block */
 	twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
 
-	return 0;
-}
-
-
-static int twl4030_usb_remove(struct platform_device *pdev)
-{
-	struct twl4030_usb *twl = platform_get_drvdata(pdev);
+	if (cable_present(twl->linkstat))
+		pm_runtime_put_noidle(twl->dev);
+	pm_runtime_mark_last_busy(twl->dev);
+	pm_runtime_put(twl->dev);
 
-	device_remove_file(twl->dev, &dev_attr_vbus);
-	device_remove_file(twl->dev, &dev_attr_test);
-	
-	return twl4030_shutdown(twl);
+	return 0;
 }
 
 #ifdef CONFIG_OF
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index bf90753..5c0adb9 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -269,7 +269,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
 	}
 
 	dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
-	of_node_put(child);	
 
 	/*
 	 * Configure the USB port as device or host according to the static
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 4589621..f660afb 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -546,11 +546,14 @@ out:
 }
 EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
 
-int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
 	struct usb_udc		*udc = NULL;
 	int			ret;
 
+	if (!driver || !driver->bind || !driver->setup)
+		return -EINVAL;
+
 	mutex_lock(&udc_lock);
 	list_for_each_entry(udc, &udc_list, list) {
 		/* For now we take the first one */
@@ -558,6 +561,7 @@ int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 			goto found;
 	}
 
+	pr_debug("couldn't find an available UDC\n");
 	mutex_unlock(&udc_lock);
 	return -ENODEV;
 found:
@@ -565,36 +569,6 @@ found:
 	mutex_unlock(&udc_lock);
 	return ret;
 }
-
-#define USB_GADGET_BIND_RETRIES		5
-#define USB_GADGET_BIND_TIMEOUT		(3 * HZ)
-static void usb_gadget_work(struct work_struct *work)
-{
-	struct usb_gadget_driver *driver = container_of(work,
-						struct usb_gadget_driver,
-						work.work);
-	int res;
-	
-	if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
-		pr_err("couldn't find an available UDC\n");
-		return;
-	}
-
-	res = __usb_gadget_probe_driver(driver);
-	if (res == -ENODEV)
-		schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
-}
-
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
-{
-	if (!driver || !driver->bind || !driver->setup)
-		return -EINVAL;
-
-	INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
-	schedule_delayed_work(&driver->work, 0);
-
-	return 0;
-}
 EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
@@ -605,8 +579,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 	if (!driver || !driver->unbind)
 		return -EINVAL;
 
-	cancel_delayed_work(&driver->work);
-
 	mutex_lock(&udc_lock);
 	list_for_each_entry(udc, &udc_list, list)
 		if (udc->driver == driver) {
@@ -763,7 +735,7 @@ static int __init usb_udc_init(void)
 	udc_class->dev_uevent = usb_udc_uevent;
 	return 0;
 }
-late_initcall_sync(usb_udc_init);
+subsys_initcall(usb_udc_init);
 
 static void __exit usb_udc_exit(void)
 {
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index dd120ec..ee9ff70 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1705,23 +1705,6 @@ EXPORT_SYMBOL_GPL(musb_dma_completion);
 #define use_dma			0
 #endif
 
-static void (*musb_phy_callback)(enum musb_vbus_id_status status);
-
-/*
- * musb_mailbox - optional phy notifier function
- * @status phy state change
- *
- * Optionally gets called from the USB PHY. Note that the USB PHY must be
- * disabled at the point the phy_callback is registered or unregistered.
- */
-void musb_mailbox(enum musb_vbus_id_status status)
-{
-	if (musb_phy_callback)
-		musb_phy_callback(status);
-
-};
-EXPORT_SYMBOL_GPL(musb_mailbox);
-
 /*-------------------------------------------------------------------------*/
 
 static ssize_t
@@ -2134,9 +2117,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->xceiv->io_ops = &musb_ulpi_access;
 	}
 
-	if (musb->ops->phy_callback)
-		musb_phy_callback = musb->ops->phy_callback;
-
 	pm_runtime_get_sync(musb->controller);
 
 	if (use_dma && dev->dma_mask) {
@@ -2315,7 +2295,6 @@ static int musb_remove(struct platform_device *pdev)
 	 */
 	musb_exit_debugfs(musb);
 	musb_shutdown(pdev);
-	musb_phy_callback = NULL;
 
 	if (musb->dma_controller)
 		musb_dma_controller_destroy(musb->dma_controller);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index fd215fb..2337d7a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -168,7 +168,6 @@ struct musb_io;
  * @adjust_channel_params: pre check for standard dma channel_program func
  * @pre_root_reset_end: called before the root usb port reset flag gets cleared
  * @post_root_reset_end: called after the root usb port reset flag gets cleared
- * @phy_callback: optional callback function for the phy to call
  */
 struct musb_platform_ops {
 
@@ -215,7 +214,6 @@ struct musb_platform_ops {
 				dma_addr_t *dma_addr, u32 *len);
 	void	(*pre_root_reset_end)(struct musb *musb);
 	void	(*post_root_reset_end)(struct musb *musb);
-	void	(*phy_callback)(enum musb_vbus_id_status status);
 };
 
 /*
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index c84e0322..1bd9232 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -36,7 +36,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
 #include <linux/delay.h>
-#include <linux/usb/musb.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/phy/omap_control_phy.h>
 #include <linux/of_platform.h>
 
@@ -46,7 +46,7 @@
 struct omap2430_glue {
 	struct device		*dev;
 	struct platform_device	*musb;
-	enum musb_vbus_id_status status;
+	enum omap_musb_vbus_id_status status;
 	struct work_struct	omap_musb_mailbox_work;
 	struct device		*control_otghs;
 };
@@ -234,7 +234,7 @@ static inline void omap2430_low_level_init(struct musb *musb)
 	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 }
 
-static void omap2430_musb_mailbox(enum musb_vbus_id_status status)
+void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 {
 	struct omap2430_glue	*glue = _glue;
 
@@ -251,6 +251,7 @@ static void omap2430_musb_mailbox(enum musb_vbus_id_status status)
 
 	schedule_work(&glue->omap_musb_mailbox_work);
 }
+EXPORT_SYMBOL_GPL(omap_musb_mailbox);
 
 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
@@ -261,7 +262,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 	struct usb_otg *otg = musb->xceiv->otg;
 
 	switch (glue->status) {
-	case MUSB_ID_GROUND:
+	case OMAP_MUSB_ID_GROUND:
 		dev_dbg(dev, "ID GND\n");
 
 		otg->default_a = true;
@@ -275,7 +276,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 		}
 		break;
 
-	case MUSB_VBUS_VALID:
+	case OMAP_MUSB_VBUS_VALID:
 		dev_dbg(dev, "VBUS Connect\n");
 
 		otg->default_a = false;
@@ -286,8 +287,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
 		break;
 
-	case MUSB_ID_FLOAT:
-	case MUSB_VBUS_OFF:
+	case OMAP_MUSB_ID_FLOAT:
+	case OMAP_MUSB_VBUS_OFF:
 		dev_dbg(dev, "VBUS Disconnect\n");
 
 		musb->xceiv->last_event = USB_EVENT_NONE;
@@ -429,7 +430,7 @@ static int omap2430_musb_init(struct musb *musb)
 
 	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
-	if (glue->status != MUSB_UNKNOWN)
+	if (glue->status != OMAP_MUSB_UNKNOWN)
 		omap_musb_set_mailbox(glue);
 
 	phy_init(musb->phy);
@@ -454,7 +455,7 @@ static void omap2430_musb_enable(struct musb *musb)
 
 	switch (glue->status) {
 
-	case MUSB_ID_GROUND:
+	case OMAP_MUSB_ID_GROUND:
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
 		if (data->interface_type != MUSB_INTERFACE_UTMI)
 			break;
@@ -473,7 +474,7 @@ static void omap2430_musb_enable(struct musb *musb)
 		}
 		break;
 
-	case MUSB_VBUS_VALID:
+	case OMAP_MUSB_VBUS_VALID:
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
 		break;
 
@@ -487,7 +488,7 @@ static void omap2430_musb_disable(struct musb *musb)
 	struct device *dev = musb->controller;
 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 
-	if (glue->status != MUSB_UNKNOWN)
+	if (glue->status != OMAP_MUSB_UNKNOWN)
 		omap_control_usb_set_mode(glue->control_otghs,
 			USB_MODE_DISCONNECT);
 }
@@ -519,8 +520,6 @@ static const struct musb_platform_ops omap2430_ops = {
 
 	.enable		= omap2430_musb_enable,
 	.disable	= omap2430_musb_disable,
-
-	.phy_callback	= omap2430_musb_mailbox,
 };
 
 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
@@ -552,7 +551,7 @@ static int omap2430_probe(struct platform_device *pdev)
 
 	glue->dev			= &pdev->dev;
 	glue->musb			= musb;
-	glue->status			= MUSB_UNKNOWN;
+	glue->status			= OMAP_MUSB_UNKNOWN;
 	glue->control_otghs = ERR_PTR(-ENODEV);
 
 	if (np) {
@@ -664,11 +663,8 @@ static int omap2430_remove(struct platform_device *pdev)
 {
 	struct omap2430_glue		*glue = platform_get_drvdata(pdev);
 
-	pm_runtime_get_sync(glue->dev);
 	cancel_work_sync(&glue->omap_musb_mailbox_work);
 	platform_device_unregister(glue->musb);
-	pm_runtime_put_sync(glue->dev);
-	pm_runtime_disable(glue->dev);
 
 	return 0;
 }
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 014dbbd7..1274185 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <linux/usb/musb.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/usb/phy_companion.h>
 #include <linux/phy/omap_usb.h>
 #include <linux/i2c/twl.h>
@@ -102,7 +102,7 @@ struct twl6030_usb {
 
 	int			irq1;
 	int			irq2;
-	enum musb_vbus_id_status linkstat;
+	enum omap_musb_vbus_id_status linkstat;
 	u8			asleep;
 	bool			vbus_enable;
 	const char		*regulator;
@@ -189,13 +189,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev,
 	spin_lock_irqsave(&twl->lock, flags);
 
 	switch (twl->linkstat) {
-	case MUSB_VBUS_VALID:
+	case OMAP_MUSB_VBUS_VALID:
 	       ret = snprintf(buf, PAGE_SIZE, "vbus\n");
 	       break;
-	case MUSB_ID_GROUND:
+	case OMAP_MUSB_ID_GROUND:
 	       ret = snprintf(buf, PAGE_SIZE, "id\n");
 	       break;
-	case MUSB_VBUS_OFF:
+	case OMAP_MUSB_VBUS_OFF:
 	       ret = snprintf(buf, PAGE_SIZE, "none\n");
 	       break;
 	default:
@@ -210,7 +210,7 @@ static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL);
 static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 {
 	struct twl6030_usb *twl = _twl;
-	enum musb_vbus_id_status status = MUSB_UNKNOWN;
+	enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
 	u8 vbus_state, hw_state;
 	int ret;
 
@@ -225,14 +225,14 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 				dev_err(twl->dev, "Failed to enable usb3v3\n");
 
 			twl->asleep = 1;
-			status = MUSB_VBUS_VALID;
+			status = OMAP_MUSB_VBUS_VALID;
 			twl->linkstat = status;
-			musb_mailbox(status);
+			omap_musb_mailbox(status);
 		} else {
-			if (twl->linkstat != MUSB_UNKNOWN) {
-				status = MUSB_VBUS_OFF;
+			if (twl->linkstat != OMAP_MUSB_UNKNOWN) {
+				status = OMAP_MUSB_VBUS_OFF;
 				twl->linkstat = status;
-				musb_mailbox(status);
+				omap_musb_mailbox(status);
 				if (twl->asleep) {
 					regulator_disable(twl->usb3v3);
 					twl->asleep = 0;
@@ -248,7 +248,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
 {
 	struct twl6030_usb *twl = _twl;
-	enum musb_vbus_id_status status = MUSB_UNKNOWN;
+	enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
 	u8 hw_state;
 	int ret;
 
@@ -262,9 +262,9 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
 		twl->asleep = 1;
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR);
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET);
-		status = MUSB_ID_GROUND;
+		status = OMAP_MUSB_ID_GROUND;
 		twl->linkstat = status;
-		musb_mailbox(status);
+		omap_musb_mailbox(status);
 	} else  {
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR);
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
@@ -334,7 +334,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
 	twl->dev		= &pdev->dev;
 	twl->irq1		= platform_get_irq(pdev, 0);
 	twl->irq2		= platform_get_irq(pdev, 1);
-	twl->linkstat		= MUSB_UNKNOWN;
+	twl->linkstat		= OMAP_MUSB_UNKNOWN;
 
 	twl->comparator.set_vbus	= twl6030_set_vbus;
 	twl->comparator.start_srp	= twl6030_start_srp;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e5af629..3d583a1 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1011,8 +1011,6 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
  * @resume: Invoked on USB resume.  May be called in_interrupt.
  * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
  *	and should be called in_interrupt.
- * @work: Gadget work used to bind to the USB controller.
- * @retries: Gadget retries to bind to the USB controller.
  * @driver: Driver model state for this driver.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
@@ -1071,8 +1069,6 @@ struct usb_gadget_driver {
 	void			(*suspend)(struct usb_gadget *);
 	void			(*resume)(struct usb_gadget *);
 	void			(*reset)(struct usb_gadget *);
-	struct delayed_work	work;
-	int			retries;
 
 	/* FIXME support safe rmmod */
 	struct device_driver	driver;
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index 96ddfb7..fa6dc13 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -133,21 +133,6 @@ struct musb_hdrc_platform_data {
 	const void	*platform_ops;
 };
 
-enum musb_vbus_id_status {
-	MUSB_UNKNOWN = 0,
-	MUSB_ID_GROUND,
-	MUSB_ID_FLOAT,
-	MUSB_VBUS_VALID,
-	MUSB_VBUS_OFF,
-};
-
-#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
-void musb_mailbox(enum musb_vbus_id_status status);
-#else
-static inline void musb_mailbox(enum musb_vbus_id_status status)
-{
-}
-#endif
 
 /* TUSB 6010 support */
 




diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 9708cf5..ce18f57 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -34,7 +34,7 @@
 #include <linux/usb/otg.h>
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
-#include <linux/usb/musb.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/usb/ulpi.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
@@ -148,10 +148,10 @@
  * If VBUS is valid or ID is ground, then we know a
  * cable is present and we need to be runtime-enabled
  */
-static inline bool cable_present(enum musb_vbus_id_status stat)
+static inline bool cable_present(enum omap_musb_vbus_id_status stat)
 {
-	return stat == MUSB_VBUS_VALID ||
-		stat == MUSB_ID_GROUND;
+	return stat == OMAP_MUSB_VBUS_VALID ||
+		stat == OMAP_MUSB_ID_GROUND;
 }
 
 struct twl4030_usb {
@@ -170,7 +170,7 @@ struct twl4030_usb {
 	enum twl4030_usb_mode	usb_mode;
 
 	int			irq;
-	enum musb_vbus_id_status linkstat;
+	enum omap_musb_vbus_id_status linkstat;
 	bool			vbus_supplied;
 
 	struct delayed_work	id_workaround_work;
@@ -276,11 +276,11 @@ static bool twl4030_is_driving_vbus(struct twl4030_usb *twl)
 	return (ret & (ULPI_OTG_DRVVBUS | ULPI_OTG_CHRGVBUS)) ? true : false;
 }
 
-static enum musb_vbus_id_status
+static enum omap_musb_vbus_id_status
 	twl4030_usb_linkstat(struct twl4030_usb *twl)
 {
 	int	status;
-	enum musb_vbus_id_status linkstat = MUSB_UNKNOWN;
+	enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN;
 
 	twl->vbus_supplied = false;
 
@@ -306,14 +306,14 @@ static enum musb_vbus_id_status
 		}
 
 		if (status & BIT(2))
-			linkstat = MUSB_ID_GROUND;
+			linkstat = OMAP_MUSB_ID_GROUND;
 		else if (status & BIT(7))
-			linkstat = MUSB_VBUS_VALID;
+			linkstat = OMAP_MUSB_VBUS_VALID;
 		else
-			linkstat = MUSB_VBUS_OFF;
+			linkstat = OMAP_MUSB_VBUS_OFF;
 	} else {
-		if (twl->linkstat != MUSB_UNKNOWN)
-			linkstat = MUSB_VBUS_OFF;
+		if (twl->linkstat != OMAP_MUSB_UNKNOWN)
+			linkstat = OMAP_MUSB_VBUS_OFF;
 	}
 
 	dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n",
@@ -532,47 +532,10 @@ static ssize_t twl4030_usb_vbus_show(struct device *dev,
 }
 static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL);
 
-static ssize_t twl4030_test_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct twl4030_usb *twl = dev_get_drvdata(dev);
-	int ret = -EINVAL;
-
-	mutex_lock(&twl->lock);
-	ret = sprintf(buf, "%s\n", "hello, world");
-	mutex_unlock(&twl->lock);
-
-	return ret;
-}
-
-static int twl4030_shutdown(struct twl4030_usb *twl);
-
-static ssize_t twl4030_test_store(struct device *dev,
-		 struct device_attribute *attr, const char *buf, size_t count)
-{
-	unsigned long tmp;
-
-	struct twl4030_usb *twl = dev_get_drvdata(dev);
-
-	mutex_lock(&twl->lock);
-	sscanf(buf, "%lX", &tmp);
-	printk("TWL HACK: tmp = 0x%lX\n", tmp);
-	mutex_unlock(&twl->lock);
-
-	if (tmp == 0xdead) {
-		printk("TWL HACK: killing hardware\n");
-		printk("TWL HACK: killing hardware = %d\n", twl4030_shutdown(twl));
-	}
-	
-	return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(test, 0664, twl4030_test_show, twl4030_test_store);
-
 static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 {
 	struct twl4030_usb *twl = _twl;
-	enum musb_vbus_id_status status;
+	enum omap_musb_vbus_id_status status;
 	bool status_changed = false;
 
 	status = twl4030_usb_linkstat(twl);
@@ -604,11 +567,11 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl)
 			pm_runtime_mark_last_busy(twl->dev);
 			pm_runtime_put_autosuspend(twl->dev);
 		}
-		musb_mailbox(status);
+		omap_musb_mailbox(status);
 	}
 
 	/* don't schedule during sleep - irq works right then */
-	if (status == MUSB_ID_GROUND && pm_runtime_active(twl->dev)) {
+	if (status == OMAP_MUSB_ID_GROUND && pm_runtime_active(twl->dev)) {
 		cancel_delayed_work(&twl->id_workaround_work);
 		schedule_delayed_work(&twl->id_workaround_work, HZ);
 	}
@@ -707,7 +670,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	twl->dev		= &pdev->dev;
 	twl->irq		= platform_get_irq(pdev, 0);
 	twl->vbus_supplied	= false;
-	twl->linkstat		= MUSB_UNKNOWN;
+	twl->linkstat		= OMAP_MUSB_UNKNOWN;
 
 	twl->phy.dev		= twl->dev;
 	twl->phy.label		= "twl4030";
@@ -747,15 +710,11 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	if (device_create_file(&pdev->dev, &dev_attr_vbus))
 		dev_warn(&pdev->dev, "could not create sysfs file\n");
 
-	if (device_create_file(&pdev->dev, &dev_attr_test))
-		dev_warn(&pdev->dev, "could not create sysfs file #2\n");
-	
 	ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
 
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
 	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
 
 	/* Our job is to use irqs and status from the power module
 	 * to keep the transceiver disabled when nothing's connected.
@@ -775,7 +734,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	}
 
 	if (pdata)
-		err = phy_create_lookup(phy, "usb", "musb-hdrc.0");
+		err = phy_create_lookup(phy, "usb", "musb-hdrc.0.auto");
 	if (err)
 		return err;
 
@@ -786,24 +745,18 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int twl4030_shutdown(struct twl4030_usb *twl)
+static int twl4030_usb_remove(struct platform_device *pdev)
 {
+	struct twl4030_usb *twl = platform_get_drvdata(pdev);
 	int val;
 
-	usb_remove_phy(&twl->phy);
 	pm_runtime_get_sync(twl->dev);
 	cancel_delayed_work(&twl->id_workaround_work);
+	device_remove_file(twl->dev, &dev_attr_vbus);
 
 	/* set transceiver mode to power on defaults */
 	twl4030_usb_set_mode(twl, -1);
 
-	/* idle ulpi before powering off */
-	if (cable_present(twl->linkstat))
-	pm_runtime_put_noidle(twl->dev);
-	pm_runtime_mark_last_busy(twl->dev);
-	pm_runtime_put_sync_suspend(twl->dev);
-	pm_runtime_disable(twl->dev);
-
 	/* autogate 60MHz ULPI clock,
 	 * clear dpll clock request for i2c access,
 	 * disable 32KHz
@@ -818,18 +771,12 @@ static int twl4030_shutdown(struct twl4030_usb *twl)
 	/* disable complete OTG block */
 	twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
 
-	return 0;
-}
-
-
-static int twl4030_usb_remove(struct platform_device *pdev)
-{
-	struct twl4030_usb *twl = platform_get_drvdata(pdev);
+	if (cable_present(twl->linkstat))
+		pm_runtime_put_noidle(twl->dev);
+	pm_runtime_mark_last_busy(twl->dev);
+	pm_runtime_put(twl->dev);
 
-	device_remove_file(twl->dev, &dev_attr_vbus);
-	device_remove_file(twl->dev, &dev_attr_test);
-	
-	return twl4030_shutdown(twl);
+	return 0;
 }
 
 #ifdef CONFIG_OF
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index bf90753..5c0adb9 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -269,7 +269,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
 	}
 
 	dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
-	of_node_put(child);	
 
 	/*
 	 * Configure the USB port as device or host according to the static
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 4589621..f660afb 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -546,11 +546,14 @@ out:
 }
 EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
 
-int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 {
 	struct usb_udc		*udc = NULL;
 	int			ret;
 
+	if (!driver || !driver->bind || !driver->setup)
+		return -EINVAL;
+
 	mutex_lock(&udc_lock);
 	list_for_each_entry(udc, &udc_list, list) {
 		/* For now we take the first one */
@@ -558,6 +561,7 @@ int __usb_gadget_probe_driver(struct usb_gadget_driver *driver)
 			goto found;
 	}
 
+	pr_debug("couldn't find an available UDC\n");
 	mutex_unlock(&udc_lock);
 	return -ENODEV;
 found:
@@ -565,36 +569,6 @@ found:
 	mutex_unlock(&udc_lock);
 	return ret;
 }
-
-#define USB_GADGET_BIND_RETRIES		5
-#define USB_GADGET_BIND_TIMEOUT		(3 * HZ)
-static void usb_gadget_work(struct work_struct *work)
-{
-	struct usb_gadget_driver *driver = container_of(work,
-						struct usb_gadget_driver,
-						work.work);
-	int res;
-	
-	if (driver->retries++ > USB_GADGET_BIND_RETRIES) {
-		pr_err("couldn't find an available UDC\n");
-		return;
-	}
-
-	res = __usb_gadget_probe_driver(driver);
-	if (res == -ENODEV)
-		schedule_delayed_work(&driver->work, USB_GADGET_BIND_TIMEOUT);
-}
-
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
-{
-	if (!driver || !driver->bind || !driver->setup)
-		return -EINVAL;
-
-	INIT_DELAYED_WORK(&driver->work, usb_gadget_work);
-	schedule_delayed_work(&driver->work, 0);
-
-	return 0;
-}
 EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
@@ -605,8 +579,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 	if (!driver || !driver->unbind)
 		return -EINVAL;
 
-	cancel_delayed_work(&driver->work);
-
 	mutex_lock(&udc_lock);
 	list_for_each_entry(udc, &udc_list, list)
 		if (udc->driver == driver) {
@@ -763,7 +735,7 @@ static int __init usb_udc_init(void)
 	udc_class->dev_uevent = usb_udc_uevent;
 	return 0;
 }
-late_initcall_sync(usb_udc_init);
+subsys_initcall(usb_udc_init);
 
 static void __exit usb_udc_exit(void)
 {
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index dd120ec..ee9ff70 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1705,23 +1705,6 @@ EXPORT_SYMBOL_GPL(musb_dma_completion);
 #define use_dma			0
 #endif
 
-static void (*musb_phy_callback)(enum musb_vbus_id_status status);
-
-/*
- * musb_mailbox - optional phy notifier function
- * @status phy state change
- *
- * Optionally gets called from the USB PHY. Note that the USB PHY must be
- * disabled at the point the phy_callback is registered or unregistered.
- */
-void musb_mailbox(enum musb_vbus_id_status status)
-{
-	if (musb_phy_callback)
-		musb_phy_callback(status);
-
-};
-EXPORT_SYMBOL_GPL(musb_mailbox);
-
 /*-------------------------------------------------------------------------*/
 
 static ssize_t
@@ -2134,9 +2117,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->xceiv->io_ops = &musb_ulpi_access;
 	}
 
-	if (musb->ops->phy_callback)
-		musb_phy_callback = musb->ops->phy_callback;
-
 	pm_runtime_get_sync(musb->controller);
 
 	if (use_dma && dev->dma_mask) {
@@ -2315,7 +2295,6 @@ static int musb_remove(struct platform_device *pdev)
 	 */
 	musb_exit_debugfs(musb);
 	musb_shutdown(pdev);
-	musb_phy_callback = NULL;
 
 	if (musb->dma_controller)
 		musb_dma_controller_destroy(musb->dma_controller);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index fd215fb..2337d7a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -168,7 +168,6 @@ struct musb_io;
  * @adjust_channel_params: pre check for standard dma channel_program func
  * @pre_root_reset_end: called before the root usb port reset flag gets cleared
  * @post_root_reset_end: called after the root usb port reset flag gets cleared
- * @phy_callback: optional callback function for the phy to call
  */
 struct musb_platform_ops {
 
@@ -215,7 +214,6 @@ struct musb_platform_ops {
 				dma_addr_t *dma_addr, u32 *len);
 	void	(*pre_root_reset_end)(struct musb *musb);
 	void	(*post_root_reset_end)(struct musb *musb);
-	void	(*phy_callback)(enum musb_vbus_id_status status);
 };
 
 /*
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index c84e0322..1bd9232 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -36,7 +36,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
 #include <linux/delay.h>
-#include <linux/usb/musb.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/phy/omap_control_phy.h>
 #include <linux/of_platform.h>
 
@@ -46,7 +46,7 @@
 struct omap2430_glue {
 	struct device		*dev;
 	struct platform_device	*musb;
-	enum musb_vbus_id_status status;
+	enum omap_musb_vbus_id_status status;
 	struct work_struct	omap_musb_mailbox_work;
 	struct device		*control_otghs;
 };
@@ -234,7 +234,7 @@ static inline void omap2430_low_level_init(struct musb *musb)
 	musb_writel(musb->mregs, OTG_FORCESTDBY, l);
 }
 
-static void omap2430_musb_mailbox(enum musb_vbus_id_status status)
+void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 {
 	struct omap2430_glue	*glue = _glue;
 
@@ -251,6 +251,7 @@ static void omap2430_musb_mailbox(enum musb_vbus_id_status status)
 
 	schedule_work(&glue->omap_musb_mailbox_work);
 }
+EXPORT_SYMBOL_GPL(omap_musb_mailbox);
 
 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
@@ -261,7 +262,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 	struct usb_otg *otg = musb->xceiv->otg;
 
 	switch (glue->status) {
-	case MUSB_ID_GROUND:
+	case OMAP_MUSB_ID_GROUND:
 		dev_dbg(dev, "ID GND\n");
 
 		otg->default_a = true;
@@ -275,7 +276,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 		}
 		break;
 
-	case MUSB_VBUS_VALID:
+	case OMAP_MUSB_VBUS_VALID:
 		dev_dbg(dev, "VBUS Connect\n");
 
 		otg->default_a = false;
@@ -286,8 +287,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
 		break;
 
-	case MUSB_ID_FLOAT:
-	case MUSB_VBUS_OFF:
+	case OMAP_MUSB_ID_FLOAT:
+	case OMAP_MUSB_VBUS_OFF:
 		dev_dbg(dev, "VBUS Disconnect\n");
 
 		musb->xceiv->last_event = USB_EVENT_NONE;
@@ -429,7 +430,7 @@ static int omap2430_musb_init(struct musb *musb)
 
 	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
-	if (glue->status != MUSB_UNKNOWN)
+	if (glue->status != OMAP_MUSB_UNKNOWN)
 		omap_musb_set_mailbox(glue);
 
 	phy_init(musb->phy);
@@ -454,7 +455,7 @@ static void omap2430_musb_enable(struct musb *musb)
 
 	switch (glue->status) {
 
-	case MUSB_ID_GROUND:
+	case OMAP_MUSB_ID_GROUND:
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
 		if (data->interface_type != MUSB_INTERFACE_UTMI)
 			break;
@@ -473,7 +474,7 @@ static void omap2430_musb_enable(struct musb *musb)
 		}
 		break;
 
-	case MUSB_VBUS_VALID:
+	case OMAP_MUSB_VBUS_VALID:
 		omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
 		break;
 
@@ -487,7 +488,7 @@ static void omap2430_musb_disable(struct musb *musb)
 	struct device *dev = musb->controller;
 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
 
-	if (glue->status != MUSB_UNKNOWN)
+	if (glue->status != OMAP_MUSB_UNKNOWN)
 		omap_control_usb_set_mode(glue->control_otghs,
 			USB_MODE_DISCONNECT);
 }
@@ -519,8 +520,6 @@ static const struct musb_platform_ops omap2430_ops = {
 
 	.enable		= omap2430_musb_enable,
 	.disable	= omap2430_musb_disable,
-
-	.phy_callback	= omap2430_musb_mailbox,
 };
 
 static u64 omap2430_dmamask = DMA_BIT_MASK(32);
@@ -552,7 +551,7 @@ static int omap2430_probe(struct platform_device *pdev)
 
 	glue->dev			= &pdev->dev;
 	glue->musb			= musb;
-	glue->status			= MUSB_UNKNOWN;
+	glue->status			= OMAP_MUSB_UNKNOWN;
 	glue->control_otghs = ERR_PTR(-ENODEV);
 
 	if (np) {
@@ -664,11 +663,8 @@ static int omap2430_remove(struct platform_device *pdev)
 {
 	struct omap2430_glue		*glue = platform_get_drvdata(pdev);
 
-	pm_runtime_get_sync(glue->dev);
 	cancel_work_sync(&glue->omap_musb_mailbox_work);
 	platform_device_unregister(glue->musb);
-	pm_runtime_put_sync(glue->dev);
-	pm_runtime_disable(glue->dev);
 
 	return 0;
 }
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 014dbbd7..1274185 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <linux/usb/musb.h>
+#include <linux/usb/musb-omap.h>
 #include <linux/usb/phy_companion.h>
 #include <linux/phy/omap_usb.h>
 #include <linux/i2c/twl.h>
@@ -102,7 +102,7 @@ struct twl6030_usb {
 
 	int			irq1;
 	int			irq2;
-	enum musb_vbus_id_status linkstat;
+	enum omap_musb_vbus_id_status linkstat;
 	u8			asleep;
 	bool			vbus_enable;
 	const char		*regulator;
@@ -189,13 +189,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev,
 	spin_lock_irqsave(&twl->lock, flags);
 
 	switch (twl->linkstat) {
-	case MUSB_VBUS_VALID:
+	case OMAP_MUSB_VBUS_VALID:
 	       ret = snprintf(buf, PAGE_SIZE, "vbus\n");
 	       break;
-	case MUSB_ID_GROUND:
+	case OMAP_MUSB_ID_GROUND:
 	       ret = snprintf(buf, PAGE_SIZE, "id\n");
 	       break;
-	case MUSB_VBUS_OFF:
+	case OMAP_MUSB_VBUS_OFF:
 	       ret = snprintf(buf, PAGE_SIZE, "none\n");
 	       break;
 	default:
@@ -210,7 +210,7 @@ static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL);
 static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 {
 	struct twl6030_usb *twl = _twl;
-	enum musb_vbus_id_status status = MUSB_UNKNOWN;
+	enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
 	u8 vbus_state, hw_state;
 	int ret;
 
@@ -225,14 +225,14 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 				dev_err(twl->dev, "Failed to enable usb3v3\n");
 
 			twl->asleep = 1;
-			status = MUSB_VBUS_VALID;
+			status = OMAP_MUSB_VBUS_VALID;
 			twl->linkstat = status;
-			musb_mailbox(status);
+			omap_musb_mailbox(status);
 		} else {
-			if (twl->linkstat != MUSB_UNKNOWN) {
-				status = MUSB_VBUS_OFF;
+			if (twl->linkstat != OMAP_MUSB_UNKNOWN) {
+				status = OMAP_MUSB_VBUS_OFF;
 				twl->linkstat = status;
-				musb_mailbox(status);
+				omap_musb_mailbox(status);
 				if (twl->asleep) {
 					regulator_disable(twl->usb3v3);
 					twl->asleep = 0;
@@ -248,7 +248,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl)
 static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
 {
 	struct twl6030_usb *twl = _twl;
-	enum musb_vbus_id_status status = MUSB_UNKNOWN;
+	enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN;
 	u8 hw_state;
 	int ret;
 
@@ -262,9 +262,9 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl)
 		twl->asleep = 1;
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR);
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET);
-		status = MUSB_ID_GROUND;
+		status = OMAP_MUSB_ID_GROUND;
 		twl->linkstat = status;
-		musb_mailbox(status);
+		omap_musb_mailbox(status);
 	} else  {
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR);
 		twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET);
@@ -334,7 +334,7 @@ static int twl6030_usb_probe(struct platform_device *pdev)
 	twl->dev		= &pdev->dev;
 	twl->irq1		= platform_get_irq(pdev, 0);
 	twl->irq2		= platform_get_irq(pdev, 1);
-	twl->linkstat		= MUSB_UNKNOWN;
+	twl->linkstat		= OMAP_MUSB_UNKNOWN;
 
 	twl->comparator.set_vbus	= twl6030_set_vbus;
 	twl->comparator.start_srp	= twl6030_start_srp;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e5af629..3d583a1 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1011,8 +1011,6 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
  * @resume: Invoked on USB resume.  May be called in_interrupt.
  * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
  *	and should be called in_interrupt.
- * @work: Gadget work used to bind to the USB controller.
- * @retries: Gadget retries to bind to the USB controller.
  * @driver: Driver model state for this driver.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
@@ -1071,8 +1069,6 @@ struct usb_gadget_driver {
 	void			(*suspend)(struct usb_gadget *);
 	void			(*resume)(struct usb_gadget *);
 	void			(*reset)(struct usb_gadget *);
-	struct delayed_work	work;
-	int			retries;
 
 	/* FIXME support safe rmmod */
 	struct device_driver	driver;
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index 96ddfb7..fa6dc13 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -133,21 +133,6 @@ struct musb_hdrc_platform_data {
 	const void	*platform_ops;
 };
 
-enum musb_vbus_id_status {
-	MUSB_UNKNOWN = 0,
-	MUSB_ID_GROUND,
-	MUSB_ID_FLOAT,
-	MUSB_VBUS_VALID,
-	MUSB_VBUS_OFF,
-};
-
-#if IS_ENABLED(CONFIG_USB_MUSB_HDRC)
-void musb_mailbox(enum musb_vbus_id_status status);
-#else
-static inline void musb_mailbox(enum musb_vbus_id_status status)
-{
-}
-#endif
 
 /* TUSB 6010 support */
 

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-25 21:09             ` Pavel Machek
@ 2016-03-26 21:32               ` Ruslan Bilovol
  2016-03-26 21:59                 ` Ruslan Bilovol
  2016-03-27 20:26                 ` Pavel Machek
  0 siblings, 2 replies; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-26 21:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Fri, Mar 25, 2016 at 11:09 PM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
>> OK, so at last I finished charging of my N900; found 1.8V USB
>> to UART adapter and soldered it to the phone.
>>
>> I managed to boot N900 with working USB gadget (builtin g_ether)
>> in boardfile mode, can ping it from PC and transfer data. I don't
>> see any issue (except of musb name issue in twl phy driver, I've
>> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
>>
>> Pavel, I still don't see how you've got your issue, please share
>> more detials
>
> Ok, let me try. I undid all the changes in drivers/phy drivers/usb and
> include/linux/usb . I have all the gadget stuff built-in, so that I
> could use nfsroot, but this is boot from mmcblk.

So do you mean you use original rootfs that was shipeed with N900?

>
> gzipped config is attached.

Thanks, I'll try that

>
> PC is unable to work with the gadget:
>
> [256526.716099] usb 2-1: new full-speed USB device number 52 using
> uhci_hcd
> [256526.832091] usb 2-1: device descriptor read/64, error -32
> [256527.052095] usb 2-1: device descriptor read/64, error -32
> [256527.268160] usb 2-1: new full-speed USB device number 53 using
> uhci_hcd
> [256527.388121] usb 2-1: device descriptor read/64, error -32
> [256527.608116] usb 2-1: device descriptor read/64, error -32
> [256527.824170] usb 2-1: new full-speed USB device number 54 using
> uhci_hcd
> [256527.851175] usb 2-1: device descriptor read/8, error -32
> [256527.975175] usb 2-1: device descriptor read/8, error -32
> [256528.188133] usb 2-1: new full-speed USB device number 55 using
> uhci_hcd
> [256528.218184] usb 2-1: device descriptor read/8, error -32
> [256528.343183] usb 2-1: device descriptor read/8, error -32
> [256528.444314] usb usb2-port1: unable to enumerate USB device
>
> Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
> the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
> devicetree boot.

Hmm.. don't see anything strange in the boot log related to USB,
I'll try your config

Best regards
Ruslan

>
> Best regards,
>
>                                                                         Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-25 21:15             ` Pavel Machek
@ 2016-03-26 21:41               ` Ruslan Bilovol
  0 siblings, 0 replies; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-26 21:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi

On Fri, Mar 25, 2016 at 11:15 PM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
>> OK, so at last I finished charging of my N900; found 1.8V USB
>> to UART adapter and soldered it to the phone.
>>
>> I managed to boot N900 with working USB gadget (builtin g_ether)
>> in boardfile mode, can ping it from PC and transfer data. I don't
>> see any issue (except of musb name issue in twl phy driver, I've
>> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
>
> I tried to add that one, too, and no change. Can I get your .config?

Since you use DT boot, this patch will not have any effect.
See my config attached.

Please note that I'm building simple rootfs cpio binary into the kernel
so you may need to change CONFIG_INITRAMFS_SOURCE value

Best regards,
Ruslan

>
> Thanks and best regards,
>                                                                 Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/x-gzip
Size: 25848 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20160326/6f3e20f8/attachment-0001.bin>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-26 21:32               ` Ruslan Bilovol
@ 2016-03-26 21:59                 ` Ruslan Bilovol
  2016-03-27 20:26                 ` Pavel Machek
  1 sibling, 0 replies; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-26 21:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Mar 26, 2016 at 11:32 PM, Ruslan Bilovol
<ruslan.bilovol@gmail.com> wrote:
> Hi
>
> On Fri, Mar 25, 2016 at 11:09 PM, Pavel Machek <pavel@ucw.cz> wrote:
>> Hi!
>>
>>> OK, so at last I finished charging of my N900; found 1.8V USB
>>> to UART adapter and soldered it to the phone.
>>>
>>> I managed to boot N900 with working USB gadget (builtin g_ether)
>>> in boardfile mode, can ping it from PC and transfer data. I don't
>>> see any issue (except of musb name issue in twl phy driver, I've
>>> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
>>>
>>> Pavel, I still don't see how you've got your issue, please share
>>> more detials
>>
>> Ok, let me try. I undid all the changes in drivers/phy drivers/usb and
>> include/linux/usb . I have all the gadget stuff built-in, so that I
>> could use nfsroot, but this is boot from mmcblk.
>
> So do you mean you use original rootfs that was shipeed with N900?
>
>>
>> gzipped config is attached.
>
> Thanks, I'll try that
>
>>
>> PC is unable to work with the gadget:
>>
>> [256526.716099] usb 2-1: new full-speed USB device number 52 using
>> uhci_hcd
>> [256526.832091] usb 2-1: device descriptor read/64, error -32
>> [256527.052095] usb 2-1: device descriptor read/64, error -32
>> [256527.268160] usb 2-1: new full-speed USB device number 53 using
>> uhci_hcd
>> [256527.388121] usb 2-1: device descriptor read/64, error -32
>> [256527.608116] usb 2-1: device descriptor read/64, error -32
>> [256527.824170] usb 2-1: new full-speed USB device number 54 using
>> uhci_hcd
>> [256527.851175] usb 2-1: device descriptor read/8, error -32
>> [256527.975175] usb 2-1: device descriptor read/8, error -32
>> [256528.188133] usb 2-1: new full-speed USB device number 55 using
>> uhci_hcd
>> [256528.218184] usb 2-1: device descriptor read/8, error -32
>> [256528.343183] usb 2-1: device descriptor read/8, error -32
>> [256528.444314] usb usb2-port1: unable to enumerate USB device
>>
>> Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
>> the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
>> devicetree boot.
>
> Hmm.. don't see anything strange in the boot log related to USB,
> I'll try your config

After looking into your config and boot log again, I see you use kernel
4.4, whereas the patch you've told about ("usb: gadget: bind UDC by name
passed via usb_gadget_driver structure") was merged only into 4.5 kernel.
Could you please try vanilla v4.5 with your config and see if it helps?

Best regards,
Ruslan Bilovol

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-26 21:32               ` Ruslan Bilovol
  2016-03-26 21:59                 ` Ruslan Bilovol
@ 2016-03-27 20:26                 ` Pavel Machek
  2016-03-27 21:44                   ` Ruslan Bilovol
  1 sibling, 1 reply; 18+ messages in thread
From: Pavel Machek @ 2016-03-27 20:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> >> I managed to boot N900 with working USB gadget (builtin g_ether)
> >> in boardfile mode, can ping it from PC and transfer data. I don't
> >> see any issue (except of musb name issue in twl phy driver, I've
> >> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
> >>
> >> Pavel, I still don't see how you've got your issue, please share
> >> more detials
> >
> > Ok, let me try. I undid all the changes in drivers/phy drivers/usb and
> > include/linux/usb . I have all the gadget stuff built-in, so that I
> > could use nfsroot, but this is boot from mmcblk.
> 
> So do you mean you use original rootfs that was shipeed with N900?

No. I'm using Debian ARM root. It includes useful X and even phone
functions. https://gitlab.com/tui/tui .

> > gzipped config is attached.
> 
> Thanks, I'll try that

Thanks.

> > Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
> > the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
> > devicetree boot.
> 
> Hmm.. don't see anything strange in the boot log related to USB,
> I'll try your config

Let me know how it went.

> >> Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
> >> the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
> >> devicetree boot.
> >
> > Hmm.. don't see anything strange in the boot log related to USB,
> > I'll try your config
> 
> After looking into your config and boot log again, I see you use kernel
> 4.4, whereas the patch you've told about ("usb: gadget: bind UDC by name
> passed via usb_gadget_driver structure") was merged only into 4.5 kernel.
> Could you please try vanilla v4.5 with your config and see if it
> helps?

...ok, I could do that, but:

> >> I managed to boot N900 with working USB gadget (builtin g_ether)
> >> in boardfile mode, can ping it from PC and transfer data. I don't
> >> see any issue (except of musb name issue in twl phy driver, I've
> >> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
> >
> > I tried to add that one, too, and no change. Can I get your .config?
> 
> Since you use DT boot, this patch will not have any effect.
> See my config attached.

...it looks like it is not expected to have any effect.

Ok, let me examine the config.

Best regards,

									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-27 20:26                 ` Pavel Machek
@ 2016-03-27 21:44                   ` Ruslan Bilovol
  2016-03-28 21:33                     ` Pavel Machek
  2016-04-01 14:38                     ` Pavel Machek
  0 siblings, 2 replies; 18+ messages in thread
From: Ruslan Bilovol @ 2016-03-27 21:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Sun, Mar 27, 2016 at 11:26 PM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
>> >> I managed to boot N900 with working USB gadget (builtin g_ether)
>> >> in boardfile mode, can ping it from PC and transfer data. I don't
>> >> see any issue (except of musb name issue in twl phy driver, I've
>> >> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
>> >>
>> >> Pavel, I still don't see how you've got your issue, please share
>> >> more detials
>> >
>> > Ok, let me try. I undid all the changes in drivers/phy drivers/usb and
>> > include/linux/usb . I have all the gadget stuff built-in, so that I
>> > could use nfsroot, but this is boot from mmcblk.
>>
>> So do you mean you use original rootfs that was shipeed with N900?
>
> No. I'm using Debian ARM root. It includes useful X and even phone
> functions. https://gitlab.com/tui/tui .
>
>> > gzipped config is attached.
>>
>> Thanks, I'll try that
>
> Thanks.
>
>> > Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
>> > the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
>> > devicetree boot.
>>
>> Hmm.. don't see anything strange in the boot log related to USB,
>> I'll try your config
>
> Let me know how it went.

I tried your config (with slight modifications) with vanilla kernel v4.5
(modifications: cmdline changed to default; used INITRAMFS_SOURCE
for prebuilt cpio archive with rootfs) and Device Tree booting.
Works fine for me except I need to unplug-plug usb cable or issue
# echo connect > /sys/devices/platform/68000000.ocp/480ab000
.usb_otg_hs/musb-hdrc.0.auto/udc/musb-hdrc.0.auto/soft_connect
to make connection.
The gadget driver successfully binds to the gadget, but I don't know
why the musb core doesn't issue pullup on USB lines during boot.

Best regards,
Ruslan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-27 21:44                   ` Ruslan Bilovol
@ 2016-03-28 21:33                     ` Pavel Machek
  2016-04-01 14:38                     ` Pavel Machek
  1 sibling, 0 replies; 18+ messages in thread
From: Pavel Machek @ 2016-03-28 21:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> >> >> I managed to boot N900 with working USB gadget (builtin g_ether)
> >> >> in boardfile mode, can ping it from PC and transfer data. I don't
> >> >> see any issue (except of musb name issue in twl phy driver, I've
> >> >> already sent a fix for that: https://lkml.org/lkml/2016/3/24/670 )
> >> >>
> >> >> Pavel, I still don't see how you've got your issue, please share
> >> >> more detials
> >> >
> >> > Ok, let me try. I undid all the changes in drivers/phy drivers/usb and
> >> > include/linux/usb . I have all the gadget stuff built-in, so that I
> >> > could use nfsroot, but this is boot from mmcblk.
> >>
> >> So do you mean you use original rootfs that was shipeed with N900?
> >
> > No. I'm using Debian ARM root. It includes useful X and even phone
> > functions. https://gitlab.com/tui/tui .
> >
> >> > gzipped config is attached.
> >>
> >> Thanks, I'll try that
> >
> > Thanks.
> >
> >> > Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
> >> > the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
> >> > devicetree boot.
> >>
> >> Hmm.. don't see anything strange in the boot log related to USB,
> >> I'll try your config
> >
> > Let me know how it went.
> 
> I tried your config (with slight modifications) with vanilla kernel v4.5
> (modifications: cmdline changed to default; used INITRAMFS_SOURCE
> for prebuilt cpio archive with rootfs) and Device Tree booting.
> Works fine for me except I need to unplug-plug usb cable or issue
> # echo connect > /sys/devices/platform/68000000.ocp/480ab000
> .usb_otg_hs/musb-hdrc.0.auto/udc/musb-hdrc.0.auto/soft_connect
> to make connection.
> The gadget driver successfully binds to the gadget, but I don't know
> why the musb core doesn't issue pullup on USB lines during boot.

I did a quick test here, and unplug/replug does not help, I still get
error message on my PC.

[53907.784294] usb usb4-port1: unable to enumerate USB device
[53990.480064] usb 1-5: new high-speed USB device number 27 using
ehci-pci
[53990.592036] usb 1-5: device descriptor read/64, error -32
[53990.808092] usb 1-5: device descriptor read/64, error -32
[53991.024042] usb 1-5: new high-speed USB device number 28 using
ehci-pci
[53991.136043] usb 1-5: device descriptor read/64, error -32
[53991.352041] usb 1-5: device descriptor read/64, error -32
[53991.568076] usb 1-5: new high-speed USB device number 29 using
ehci-pci
[53991.589955] usb 1-5: device descriptor read/8, error -32
[53991.709703] usb 1-5: device descriptor read/8, error -32
[53991.924577] usb 1-5: new high-speed USB device number 30 using
ehci-pci
[53991.944944] usb 1-5: device descriptor read/8, error -32
[53992.065822] usb 1-5: device descriptor read/8, error -32

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

* usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure
  2016-03-27 21:44                   ` Ruslan Bilovol
  2016-03-28 21:33                     ` Pavel Machek
@ 2016-04-01 14:38                     ` Pavel Machek
  1 sibling, 0 replies; 18+ messages in thread
From: Pavel Machek @ 2016-04-01 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi!

> >> > Dmesg from the n900 is attached as /tmp/delme.gz. I did _not_ apply
> >> > the patch from https://lkml.org/lkml/2016/3/24/670 , yet, as I'm using
> >> > devicetree boot.
> >>
> >> Hmm.. don't see anything strange in the boot log related to USB,
> >> I'll try your config
> >
> > Let me know how it went.
> 
> I tried your config (with slight modifications) with vanilla kernel v4.5
> (modifications: cmdline changed to default; used INITRAMFS_SOURCE
> for prebuilt cpio archive with rootfs) and Device Tree booting.
> Works fine for me except I need to unplug-plug usb cable or issue
> # echo connect > /sys/devices/platform/68000000.ocp/480ab000
> .usb_otg_hs/musb-hdrc.0.auto/udc/musb-hdrc.0.auto/soft_connect
> to make connection.
> The gadget driver successfully binds to the gadget, but I don't know
> why the musb core doesn't issue pullup on USB lines during boot.

Hmm, strange. Unplug/replug of the USB cable results in:

<6>usb 1-5: new high-speed USB device number 100 using ehci-pci
<3>usb 1-5: device descriptor read/64, error -32
tail: /proc/kmsg: file truncated
<3>usb 1-5: device descriptor read/64, error -32
<3>usb 1-5: device descriptor read/64, error -32
<3>usb 1-5: device descriptor read/8, error -32
<3>usb 1-5: device descriptor read/8, error -32
<6>usb 1-5: new high-speed USB device number 103 using ehci-pci
<3>usb 1-5: device descriptor read/8, error -32
<3>usb 1-5: device descriptor read/8, error -32
<3>usb usb1-port5: unable to enumerate USB device
<6>usb 4-1: new full-speed USB device number 80 using uhci_hcd
<3>usb 4-1: device descriptor read/64, error -32
<3>usb 4-1: device descriptor read/64, error -32
<6>usb 4-1: new full-speed USB device number 81 using uhci_hcd
<3>usb 4-1: device descriptor read/64, error -32
<3>usb 4-1: device descriptor read/64, error -32
<3>usb usb4-port1: unable to enumerate USB device

echo connect does not seem to do the trick, either:

root at n900:~# echo connect >
/sys/devices/platform/68000000.ocp/480ab000.usb_otg_hs/musb-hdrc.0.auto/udc/musb-hdrc.0.auto/soft_connect
-bash: echo: write error: Operation not supported
root at n900:~# uname -a
Linux n900 4.4.0-omap3-149558-g5cf5ee5-dirty #168 PREEMPT Tue Mar 29
09:49:40 CEST 2016 armv7l GNU/Linux

Hmm, documentation is not too helpful, either...

What:           /sys/class/udc/<udc>/soft_connect
Date:           June 2011
KernelVersion:  3.1
Contact:        Felipe Balbi <balbi@kernel.org>
Description:
		Allows users to disconnect data pullup resistors thus
		causing a
 		logical disconnection from the USB
 		Host.

Dmesg says:

[  619.471374] udc musb-hdrc.0.auto: soft-connect without a gadget
driver

Any ideas?
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-04-01 14:38 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-17 21:26 usb: gadget breakage on N900: bind UDC by name passed via usb_gadget_driver structure Pavel Machek
2016-03-18  7:47 ` Ruslan Bilovol
2016-03-18  9:32   ` Pavel Machek
2016-03-18 20:20   ` Pavel Machek
2016-03-21 11:51     ` Marek Szyprowski
2016-03-23 12:21       ` Pavel Machek
2016-03-24  0:45         ` Ruslan Bilovol
2016-03-25  3:21           ` Ruslan Bilovol
2016-03-25 21:09             ` Pavel Machek
2016-03-26 21:32               ` Ruslan Bilovol
2016-03-26 21:59                 ` Ruslan Bilovol
2016-03-27 20:26                 ` Pavel Machek
2016-03-27 21:44                   ` Ruslan Bilovol
2016-03-28 21:33                     ` Pavel Machek
2016-04-01 14:38                     ` Pavel Machek
2016-03-25 21:15             ` Pavel Machek
2016-03-26 21:41               ` Ruslan Bilovol
2016-03-25 21:30             ` Pavel Machek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).