diff options
author | Ruslan Bilovol <ruslan.bilovol@gmail.com> | 2015-11-23 09:56:35 +0100 |
---|---|---|
committer | Nitin Garg <nitin.garg@nxp.com> | 2016-01-14 11:03:02 -0600 |
commit | 0836c901dfd428c69a420af84287067f1a37821b (patch) | |
tree | 8e60091de7199ba22562c123ed15f578459a27fb | |
parent | 57bacac97e233d40d474311cf00297a70316e027 (diff) |
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>
-rw-r--r-- | drivers/usb/gadget/udc/udc-core.c | 24 | ||||
-rw-r--r-- | 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 7d69931cf45d..2d28a8152201 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -457,21 +457,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 658fa4e0a74f..565a55a89c94 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -827,6 +827,8 @@ static inline int usb_gadget_disconnect(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 @@ -887,6 +889,8 @@ struct usb_gadget_driver { /* FIXME support safe rmmod */ struct device_driver driver; + + char *udc_name; }; |