Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1273861 > unrolled thread
| Started by | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| First post | 2015-11-20 10:00 +0100 |
| Last post | 2015-11-20 17:30 +0100 |
| Articles | 8 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v6 0/4] usb/gadget: independent registration of gadgets and gadget drivers Marek Szyprowski <m.szyprowski@samsung.com> - 2015-11-20 10:00 +0100
[PATCH v6 3/4] usb: gadget: udc-core: remove unused usb_udc_attach_driver() Marek Szyprowski <m.szyprowski@samsung.com> - 2015-11-20 10:00 +0100
[PATCH v6 1/4] usb: gadget: bind UDC by name passed via usb_gadget_driver structure Marek Szyprowski <m.szyprowski@samsung.com> - 2015-11-20 10:00 +0100
[PATCH v6 2/4] usb: gadget: configfs: pass UDC name via usb_gadget_driver struct Marek Szyprowski <m.szyprowski@samsung.com> - 2015-11-20 10:00 +0100
[PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers Marek Szyprowski <m.szyprowski@samsung.com> - 2015-11-20 10:00 +0100
Re: [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers Marek Szyprowski <m.szyprowski@samsung.com> - 2015-11-20 10:50 +0100
RE: [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers Peter Chen <Peter.Chen@freescale.com> - 2015-11-20 11:00 +0100
Re: [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers Alan Stern <stern@rowland.harvard.edu> - 2015-11-20 17:30 +0100
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2015-11-20 10:00 +0100 |
| Subject | [PATCH v6 0/4] usb/gadget: independent registration of gadgets and gadget drivers |
| Message-ID | <qwPHY-4To-17@gated-at.bofh.it> |
Hello,
This is a resurrection of the patches initially submitted by Ruslan
Bilovol in the following thread: https://lkml.org/lkml/2015/6/22/554
The changes since the original submission (v5) includes rebase onto
latest linux-next branch, simplification of the code requested by Alan
Stern and Felipe Balbi and removal of a patch, which deleted
__init/__exit attributes (this change has been already merged).
This feature is urgently needed, because it is not longer possible to
use workaround to avoid deferred probe in UDC drivers due to
not-yet-probed i2c regulator drivers (for more information see
https://lkml.org/lkml/2015/10/30/374 ).
This patchset has been successfully tested on Odroid XU3 boards with
DWC3 UDC driver being deferred by missing regulator drivers.
Best regards
Marek Szyprowski
Samsung R&D Institute Poland
Patch summary:
Ruslan Bilovol (4):
usb: gadget: bind UDC by name passed via usb_gadget_driver structure
usb: gadget: configfs: pass UDC name via usb_gadget_driver struct
usb: gadget: udc-core: remove unused usb_udc_attach_driver()
usb: gadget: udc-core: independent registration of gadgets and gadget
drivers
drivers/usb/gadget/configfs.c | 27 ++++++-------
drivers/usb/gadget/udc/udc-core.c | 81 +++++++++++++++++++++++----------------
include/linux/usb/gadget.h | 8 +++-
3 files changed, 68 insertions(+), 48 deletions(-)
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2015-11-20 10:00 +0100 |
| Subject | [PATCH v6 3/4] usb: gadget: udc-core: remove unused usb_udc_attach_driver() |
| Message-ID | <qwPHZ-4To-23@gated-at.bofh.it> |
| In reply to | #1273861 |
From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
Now when last user of usb_udc_attach_driver() is switched
to passing UDC name via usb_gadget_driver struct, it's safe
to remove this function
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>
---
drivers/usb/gadget/udc/udc-core.c | 26 --------------------------
include/linux/usb/gadget.h | 2 --
2 files changed, 28 deletions(-)
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 429d64e..f76ebc8 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -520,32 +520,6 @@ err1:
return ret;
}
-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;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index b32e44f..e11f5a2 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1121,8 +1121,6 @@ extern int usb_add_gadget_udc_release(struct device *parent,
struct usb_gadget *gadget, void (*release)(struct device *dev));
extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget);
extern void usb_del_gadget_udc(struct usb_gadget *gadget);
-extern int usb_udc_attach_driver(const char *name,
- struct usb_gadget_driver *driver);
/*-------------------------------------------------------------------------*/
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2015-11-20 10:00 +0100 |
| Subject | [PATCH v6 1/4] usb: gadget: bind UDC by name passed via usb_gadget_driver structure |
| Message-ID | <qwPHZ-4To-25@gated-at.bofh.it> |
| In reply to | #1273861 |
From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
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>
---
drivers/usb/gadget/udc/udc-core.c | 24 +++++++++++++++++++-----
include/linux/usb/gadget.h | 4 ++++
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index f660afb..429d64e 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -549,21 +549,35 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver);
int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
{
struct usb_udc *udc = NULL;
- int ret;
+ int ret = -ENODEV;
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 */
- if (!udc->driver)
+ if (driver->udc_name) {
+ list_for_each_entry(udc, &udc_list, list) {
+ ret = strcmp(driver->udc_name, dev_name(&udc->dev));
+ if (!ret)
+ break;
+ }
+ if (ret)
+ ret = -ENODEV;
+ else if (udc->driver)
+ ret = -EBUSY;
+ else
goto found;
+ } else {
+ list_for_each_entry(udc, &udc_list, list) {
+ /* For now we take the first one */
+ if (!udc->driver)
+ goto found;
+ }
}
pr_debug("couldn't find an available UDC\n");
mutex_unlock(&udc_lock);
- return -ENODEV;
+ return ret;
found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(&udc_lock);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 3d583a1..b32e44f 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1012,6 +1012,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
* @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
* and should be called in_interrupt.
* @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.
*
* Devices are disabled till a gadget driver successfully bind()s, which
* means the driver will handle setup() requests needed to enumerate (and
@@ -1072,6 +1074,8 @@ struct usb_gadget_driver {
/* FIXME support safe rmmod */
struct device_driver driver;
+
+ char *udc_name;
};
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2015-11-20 10:00 +0100 |
| Subject | [PATCH v6 2/4] usb: gadget: configfs: pass UDC name via usb_gadget_driver struct |
| Message-ID | <qwPHZ-4To-33@gated-at.bofh.it> |
| In reply to | #1273861 |
From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
Now when udc-core supports binding to specific UDC by passing
its name via 'udc_name' member of usb_gadget_driver struct,
switch to this generic approach.
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>
---
drivers/usb/gadget/configfs.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 163d305..0bc6865 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -56,7 +56,6 @@ struct gadget_info {
struct list_head string_list;
struct list_head available_func;
- const char *udc_name;
struct usb_composite_driver composite;
struct usb_composite_dev cdev;
bool use_os_desc;
@@ -233,21 +232,21 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
{
- return sprintf(page, "%s\n", to_gadget_info(item)->udc_name ?: "");
+ return sprintf(page, "%s\n", to_gadget_info(item)->composite.gadget_driver.udc_name ?: "");
}
static int unregister_gadget(struct gadget_info *gi)
{
int ret;
- if (!gi->udc_name)
+ if (!gi->composite.gadget_driver.udc_name)
return -ENODEV;
ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
if (ret)
return ret;
- kfree(gi->udc_name);
- gi->udc_name = NULL;
+ kfree(gi->composite.gadget_driver.udc_name);
+ gi->composite.gadget_driver.udc_name = NULL;
return 0;
}
@@ -271,14 +270,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
if (ret)
goto err;
} else {
- if (gi->udc_name) {
+ if (gi->composite.gadget_driver.udc_name) {
ret = -EBUSY;
goto err;
}
- ret = usb_udc_attach_driver(name, &gi->composite.gadget_driver);
- if (ret)
+ gi->composite.gadget_driver.udc_name = name;
+ ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
+ if (ret) {
+ gi->composite.gadget_driver.udc_name = NULL;
goto err;
- gi->udc_name = name;
+ }
}
mutex_unlock(&gi->lock);
return len;
@@ -427,9 +428,9 @@ static int config_usb_cfg_unlink(
* remove the function.
*/
mutex_lock(&gi->lock);
- if (gi->udc_name)
+ if (gi->composite.gadget_driver.udc_name)
unregister_gadget(gi);
- WARN_ON(gi->udc_name);
+ WARN_ON(gi->composite.gadget_driver.udc_name);
list_for_each_entry(f, &cfg->func_list, list) {
if (f->fi == fi) {
@@ -873,10 +874,10 @@ static int os_desc_unlink(struct config_item *os_desc_ci,
struct usb_composite_dev *cdev = &gi->cdev;
mutex_lock(&gi->lock);
- if (gi->udc_name)
+ if (gi->composite.gadget_driver.udc_name)
unregister_gadget(gi);
cdev->os_desc_config = NULL;
- WARN_ON(gi->udc_name);
+ WARN_ON(gi->composite.gadget_driver.udc_name);
mutex_unlock(&gi->lock);
return 0;
}
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2015-11-20 10:00 +0100 |
| Subject | [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers |
| Message-ID | <qwPHZ-4To-29@gated-at.bofh.it> |
| In reply to | #1273861 |
From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
Change behavior during registration of gadgets and
gadget drivers in udc-core. Instead of previous
approach when for successful probe of usb gadget driver
at least one usb gadget should be already registered
use another one where gadget drivers and gadgets
can be registered in udc-core independently.
Independent registration of gadgets and gadget drivers
is useful for built-in into kernel gadget and gadget
driver case - because it's possible that gadget is
really probed only on late_init stage (due to deferred
probe) whereas gadget driver's probe is silently failed
on module_init stage due to no any UDC added.
Also it is useful for modules case - now there is no
difference what module to insert first: gadget module
or gadget driver one.
Tested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
[simplified code as requested by Alan Stern and Felipe Balbi]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/usb/gadget/udc/udc-core.c | 43 +++++++++++++++++++++++++++++++--------
include/linux/usb/gadget.h | 2 ++
2 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index f76ebc8..461b311 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -51,8 +51,12 @@ struct usb_udc {
static struct class *udc_class;
static LIST_HEAD(udc_list);
+static LIST_HEAD(gadget_driver_pending_list);
static DEFINE_MUTEX(udc_lock);
+static int udc_bind_to_driver(struct usb_udc *udc,
+ struct usb_gadget_driver *driver);
+
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_HAS_DMA
@@ -356,6 +360,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev))
{
struct usb_udc *udc;
+ struct usb_gadget_driver *driver;
int ret = -ENOMEM;
udc = kzalloc(sizeof(*udc), GFP_KERNEL);
@@ -403,6 +408,18 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
+ /* pick up one of pending gadget drivers */
+ list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
+ if (!driver->udc_name || strcmp(driver->udc_name,
+ dev_name(&udc->dev)) == 0) {
+ ret = udc_bind_to_driver(udc, driver);
+ if (ret)
+ goto err4;
+ list_del(&driver->pending);
+ break;
+ }
+ }
+
mutex_unlock(&udc_lock);
return 0;
@@ -475,9 +492,16 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
list_del(&udc->list);
mutex_unlock(&udc_lock);
- if (udc->driver)
+ if (udc->driver) {
+ struct usb_gadget_driver *driver = udc->driver;
+
usb_gadget_remove_driver(udc);
+ mutex_lock(&udc_lock);
+ list_add(&driver->pending, &gadget_driver_pending_list);
+ mutex_unlock(&udc_lock);
+ }
+
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
flush_work(&gadget->work);
device_unregister(&udc->dev);
@@ -535,11 +559,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
if (!ret)
break;
}
- if (ret)
- ret = -ENODEV;
- else if (udc->driver)
- ret = -EBUSY;
- else
+ if (!ret && !udc->driver)
goto found;
} else {
list_for_each_entry(udc, &udc_list, list) {
@@ -549,9 +569,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
}
}
- pr_debug("couldn't find an available UDC\n");
+ list_add_tail(&driver->pending, &gadget_driver_pending_list);
+ 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 ret;
+ return 0;
found:
ret = udc_bind_to_driver(udc, driver);
mutex_unlock(&udc_lock);
@@ -577,6 +600,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
break;
}
+ if (ret) {
+ list_del(&driver->pending);
+ ret = 0;
+ }
mutex_unlock(&udc_lock);
return ret;
}
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e11f5a2..a3436bf 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1014,6 +1014,7 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
* @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.
+ * @pending: UDC core private data used for deferred probe of this driver.
*
* Devices are disabled till a gadget driver successfully bind()s, which
* means the driver will handle setup() requests needed to enumerate (and
@@ -1076,6 +1077,7 @@ struct usb_gadget_driver {
struct device_driver driver;
char *udc_name;
+ struct list_head pending;
};
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Marek Szyprowski <m.szyprowski@samsung.com> |
|---|---|
| Date | 2015-11-20 10:50 +0100 |
| Subject | Re: [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers |
| Message-ID | <qwQum-5rq-25@gated-at.bofh.it> |
| In reply to | #1273870 |
Hello,
On 2015-11-20 10:26, Peter Chen wrote:
> On Fri, Nov 20, 2015 at 09:54:12AM +0100, Marek Szyprowski wrote:
>> From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
>>
>> Change behavior during registration of gadgets and
>> gadget drivers in udc-core. Instead of previous
>> approach when for successful probe of usb gadget driver
>> at least one usb gadget should be already registered
>> use another one where gadget drivers and gadgets
>> can be registered in udc-core independently.
>>
>> Independent registration of gadgets and gadget drivers
>> is useful for built-in into kernel gadget and gadget
>> driver case - because it's possible that gadget is
>> really probed only on late_init stage (due to deferred
>> probe) whereas gadget driver's probe is silently failed
>> on module_init stage due to no any UDC added.
>>
>> Also it is useful for modules case - now there is no
>> difference what module to insert first: gadget module
>> or gadget driver one.
>>
>> Tested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>> Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
>> [simplified code as requested by Alan Stern and Felipe Balbi]
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>> drivers/usb/gadget/udc/udc-core.c | 43 +++++++++++++++++++++++++++++++--------
>> include/linux/usb/gadget.h | 2 ++
>> 2 files changed, 37 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
>> index f76ebc8..461b311 100644
>> --- a/drivers/usb/gadget/udc/udc-core.c
>> +++ b/drivers/usb/gadget/udc/udc-core.c
>> @@ -51,8 +51,12 @@ struct usb_udc {
>>
>> static struct class *udc_class;
>> static LIST_HEAD(udc_list);
>> +static LIST_HEAD(gadget_driver_pending_list);
>> static DEFINE_MUTEX(udc_lock);
>>
>> +static int udc_bind_to_driver(struct usb_udc *udc,
>> + struct usb_gadget_driver *driver);
>> +
>> /* ------------------------------------------------------------------------- */
>>
>> #ifdef CONFIG_HAS_DMA
>> @@ -356,6 +360,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
>> void (*release)(struct device *dev))
>> {
>> struct usb_udc *udc;
>> + struct usb_gadget_driver *driver;
>> int ret = -ENOMEM;
>>
>> udc = kzalloc(sizeof(*udc), GFP_KERNEL);
>> @@ -403,6 +408,18 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
>> usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
>> udc->vbus = true;
>>
>> + /* pick up one of pending gadget drivers */
>> + list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
>> + if (!driver->udc_name || strcmp(driver->udc_name,
>> + dev_name(&udc->dev)) == 0) {
>> + ret = udc_bind_to_driver(udc, driver);
>> + if (ret)
>> + goto err4;
>> + list_del(&driver->pending);
>> + break;
>> + }
>> + }
>> +
>> mutex_unlock(&udc_lock);
>>
>> return 0;
>> @@ -475,9 +492,16 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
>> list_del(&udc->list);
>> mutex_unlock(&udc_lock);
>>
>> - if (udc->driver)
>> + if (udc->driver) {
>> + struct usb_gadget_driver *driver = udc->driver;
>> +
>> usb_gadget_remove_driver(udc);
>>
>> + mutex_lock(&udc_lock);
>> + list_add(&driver->pending, &gadget_driver_pending_list);
>> + mutex_unlock(&udc_lock);
>> + }
>> +
>> kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
>> flush_work(&gadget->work);
>> device_unregister(&udc->dev);
>> @@ -535,11 +559,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>> if (!ret)
>> break;
>> }
>> - if (ret)
>> - ret = -ENODEV;
>> - else if (udc->driver)
>> - ret = -EBUSY;
>> - else
>> + if (!ret && !udc->driver)
>> goto found;
>> } else {
>> list_for_each_entry(udc, &udc_list, list) {
>> @@ -549,9 +569,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
>> }
>> }
>>
>> - pr_debug("couldn't find an available UDC\n");
>> + list_add_tail(&driver->pending, &gadget_driver_pending_list);
>> + 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 ret;
>> + return 0;
>> found:
>> ret = udc_bind_to_driver(udc, driver);
>> mutex_unlock(&udc_lock);
>> @@ -577,6 +600,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
>> break;
>> }
>>
>> + if (ret) {
>> + list_del(&driver->pending);
>> + ret = 0;
>> + }
>> mutex_unlock(&udc_lock);
>> return ret;
>> }
>> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
>> index e11f5a2..a3436bf 100644
>> --- a/include/linux/usb/gadget.h
>> +++ b/include/linux/usb/gadget.h
>> @@ -1014,6 +1014,7 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget)
>> * @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.
>> + * @pending: UDC core private data used for deferred probe of this driver.
>> *
>> * Devices are disabled till a gadget driver successfully bind()s, which
>> * means the driver will handle setup() requests needed to enumerate (and
>> @@ -1076,6 +1077,7 @@ struct usb_gadget_driver {
>> struct device_driver driver;
>>
>> char *udc_name;
>> + struct list_head pending;
>> };
>>
>>
> And it seems can't apply for felipe's testing/next which I just rebased
> on it.
I really have no idea why it fails for You. The patchset applies
correctly on both
Felipe's 'next' and 'testing/next' branches from today.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Peter Chen <Peter.Chen@freescale.com> |
|---|---|
| Date | 2015-11-20 11:00 +0100 |
| Subject | RE: [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers |
| Message-ID | <qwQE2-5uX-11@gated-at.bofh.it> |
| In reply to | #1273900 |
DQogIA0KPiA+Pg0KPiA+IEFuZCBpdCBzZWVtcyBjYW4ndCBhcHBseSBmb3IgZmVsaXBlJ3MgdGVz dGluZy9uZXh0IHdoaWNoIEkganVzdA0KPiA+IHJlYmFzZWQgb24gaXQuDQo+IA0KPiBJIHJlYWxs eSBoYXZlIG5vIGlkZWEgd2h5IGl0IGZhaWxzIGZvciBZb3UuIFRoZSBwYXRjaHNldCBhcHBsaWVz IGNvcnJlY3RseSBvbiBib3RoDQo+IEZlbGlwZSdzICduZXh0JyBhbmQgJ3Rlc3RpbmcvbmV4dCcg YnJhbmNoZXMgZnJvbSB0b2RheS4NCj4gDQoNCkkgbWF5IGtub3cgdGhlIHJlYXNvbiwgaXQgbWF5 IGJlIGJlY2F1c2UgSSBjaGFuZ2VkIGluY2x1ZGUvbGludXgvdXNiL2dhZGdldC5oIGR1ZSB0bw0K eW91ciAxc3QgcGF0Y2gncyB3YXJuaW5nLCBzaW5jZSBJIGVuYWJsZSBjaGVja3BhdGNoLnBsIGhv b2sgZm9yIGFwcGx5aW5nLCBJIG5lZWQgdG8NCmZpeCBpdCBhZnRlciBhcHBseWluZyBtb3JlLg0K DQpBcHBseWluZzogdXNiOiBnYWRnZXQ6IHVkYy1jb3JlOiBpbmRlcGVuZGVudCByZWdpc3RyYXRp b24gb2YgZ2FkZ2V0cyBhbmQgZ2FkZ2V0IGRyaXZlcnMNCmZhdGFsOiBzaGExIGluZm9ybWF0aW9u IGlzIGxhY2tpbmcgb3IgdXNlbGVzcyAoaW5jbHVkZS9saW51eC91c2IvZ2FkZ2V0LmgpLg0KUmVw b3NpdG9yeSBsYWNrcyBuZWNlc3NhcnkgYmxvYnMgdG8gZmFsbCBiYWNrIG9uIDMtd2F5IG1lcmdl Lg0KQ2Fubm90IGZhbGwgYmFjayB0byB0aHJlZS13YXkgbWVyZ2UuDQpQYXRjaCBmYWlsZWQgYXQg MDAwMSB1c2I6IGdhZGdldDogdWRjLWNvcmU6IGluZGVwZW5kZW50IHJlZ2lzdHJhdGlvbiBvZiBn YWRnZXRzIGFuZCBnYWRnZXQgZHJpdmVycw0KDQpQZXRlcg0KDQo+IEJlc3QgcmVnYXJkcw0KPiAt LQ0KPiBNYXJlayBTenlwcm93c2tpLCBQaEQNCj4gU2Ftc3VuZyBSJkQgSW5zdGl0dXRlIFBvbGFu ZA0KDQo= -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Alan Stern <stern@rowland.harvard.edu> |
|---|---|
| Date | 2015-11-20 17:30 +0100 |
| Subject | Re: [PATCH v6 4/4] usb: gadget: udc-core: independent registration of gadgets and gadget drivers |
| Message-ID | <qwWJs-1a6-25@gated-at.bofh.it> |
| In reply to | #1273870 |
On Fri, 20 Nov 2015, Marek Szyprowski wrote:
> From: Ruslan Bilovol <ruslan.bilovol@gmail.com>
>
> Change behavior during registration of gadgets and
> gadget drivers in udc-core. Instead of previous
> approach when for successful probe of usb gadget driver
> at least one usb gadget should be already registered
> use another one where gadget drivers and gadgets
> can be registered in udc-core independently.
>
> Independent registration of gadgets and gadget drivers
> is useful for built-in into kernel gadget and gadget
> driver case - because it's possible that gadget is
> really probed only on late_init stage (due to deferred
> probe) whereas gadget driver's probe is silently failed
> on module_init stage due to no any UDC added.
>
> Also it is useful for modules case - now there is no
> difference what module to insert first: gadget module
> or gadget driver one.
>
> Tested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> Signed-off-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
> [simplified code as requested by Alan Stern and Felipe Balbi]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
...
> @@ -475,9 +492,16 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
> list_del(&udc->list);
> mutex_unlock(&udc_lock);
>
> - if (udc->driver)
> + if (udc->driver) {
> + struct usb_gadget_driver *driver = udc->driver;
> +
> usb_gadget_remove_driver(udc);
>
> + mutex_lock(&udc_lock);
> + list_add(&driver->pending, &gadget_driver_pending_list);
> + mutex_unlock(&udc_lock);
> + }
It looks like there is a race here with usb_gadget_unregister_driver().
Would it be okay to hold the udc_lock mutex throughout the whole "if"
statement?
Alan Stern
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web