We have historic problem that the gadget will not work if the gadget
is build-in and the udc driver is defered probe due to some
resources are not ready. Below links are related to this problem.

http://marc.info/?l=linux-usb&m=139380872501745&w=2
http://marc.info/?l=linux-usb&m=137991612311893&w=2
http://marc.info/?l=linux-usb&m=137706435611447&w=2

This patch saves pointer of usb_gadget_driver when the udc is
not ready, and redo usb_gadget_probe_driver when the udc is ready
This method may not be good enough, but we need to find a way
to fix this problem, so I post this RFC to see if to see comments,
someone may have a better solution:)

Signed-off-by: Peter Chen <peter.c...@freescale.com>
---
 drivers/usb/gadget/udc-core.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 27768a7..1b991ef 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -48,6 +48,11 @@ struct usb_udc {
 static struct class *udc_class;
 static LIST_HEAD(udc_list);
 static DEFINE_MUTEX(udc_lock);
+/* 
+ * Only used for saving usb_gadget_driver pointer
+ * when the udc is not ready
+ */
+struct usb_gadget_driver       *saved_gadget_driver;
 
 /* ------------------------------------------------------------------------- */
 
@@ -272,7 +277,12 @@ EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release);
  */
 int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
 {
-       return usb_add_gadget_udc_release(parent, gadget, NULL);
+       int ret = usb_add_gadget_udc_release(parent, gadget, NULL);
+       if (!ret && saved_gadget_driver) {
+               usb_gadget_probe_driver(saved_gadget_driver);
+               saved_gadget_driver = NULL;
+       }
+       return ret;
 }
 EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
 
@@ -406,7 +416,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver 
*driver)
                        goto found;
        }
 
-       pr_debug("couldn't find an available UDC\n");
+       pr_debug("couldn't find an UDC, retry probe when udc is ready\n");
+       saved_gadget_driver = driver;
        mutex_unlock(&udc_lock);
        return -ENODEV;
 found:
-- 
1.7.8


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to