Commit 2284b29d authored by Ruslan Bilovol's avatar Ruslan Bilovol Committed by Felipe Balbi

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: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarRuslan Bilovol <ruslan.bilovol@gmail.com>
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Tested-by: default avatarPeter Chen <peter.chen@freescale.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 59f042f6
...@@ -549,21 +549,35 @@ EXPORT_SYMBOL_GPL(usb_udc_attach_driver); ...@@ -549,21 +549,35 @@ 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; struct usb_udc *udc = NULL;
int ret; int ret = -ENODEV;
if (!driver || !driver->bind || !driver->setup) if (!driver || !driver->bind || !driver->setup)
return -EINVAL; return -EINVAL;
mutex_lock(&udc_lock); mutex_lock(&udc_lock);
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) { list_for_each_entry(udc, &udc_list, list) {
/* For now we take the first one */ /* For now we take the first one */
if (!udc->driver) if (!udc->driver)
goto found; goto found;
} }
}
pr_debug("couldn't find an available UDC\n"); pr_debug("couldn't find an available UDC\n");
mutex_unlock(&udc_lock); mutex_unlock(&udc_lock);
return -ENODEV; return ret;
found: found:
ret = udc_bind_to_driver(udc, driver); ret = udc_bind_to_driver(udc, driver);
mutex_unlock(&udc_lock); mutex_unlock(&udc_lock);
......
...@@ -1012,6 +1012,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) ...@@ -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 * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers
* and should be called in_interrupt. * and should be called in_interrupt.
* @driver: Driver model state for this driver. * @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 * Devices are disabled till a gadget driver successfully bind()s, which
* means the driver will handle setup() requests needed to enumerate (and * means the driver will handle setup() requests needed to enumerate (and
...@@ -1072,6 +1074,8 @@ struct usb_gadget_driver { ...@@ -1072,6 +1074,8 @@ struct usb_gadget_driver {
/* FIXME support safe rmmod */ /* FIXME support safe rmmod */
struct device_driver driver; struct device_driver driver;
char *udc_name;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment