diff options
author | Peter Chen <peter.chen@freescale.com> | 2015-03-06 10:36:02 +0800 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-03-19 11:25:46 -0500 |
commit | dfea9c94837d27e38c8cc85a3c1c7c268973c3c2 (patch) | |
tree | b4f76788c83c4a0a8ae8e01e349e02055eb01bf9 | |
parent | 7252f1bfd4bc97ec4b5fa7adaf3a1a45c325635c (diff) | |
download | linux-dfea9c94837d27e38c8cc85a3c1c7c268973c3c2.tar.bz2 |
usb: udc: store usb_udc pointer in struct usb_gadget
Instead of iterate to find usb_udc according to usb_gadget, this
way is easier.
Alan Stern suggests this way too:
http://marc.info/?l=linux-usb&m=142168496528894&w=2
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-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 | 34 | ||||
-rw-r--r-- | include/linux/usb/gadget.h | 3 |
2 files changed, 12 insertions, 25 deletions
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 5a81cb086b99..bf7ed777a87d 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -128,21 +128,11 @@ EXPORT_SYMBOL_GPL(usb_gadget_giveback_request); static void usb_gadget_state_work(struct work_struct *work) { - struct usb_gadget *gadget = work_to_gadget(work); - struct usb_udc *udc = NULL; - - mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) - if (udc->gadget == gadget) - goto found; - mutex_unlock(&udc_lock); + struct usb_gadget *gadget = work_to_gadget(work); + struct usb_udc *udc = gadget->udc; - return; - -found: - mutex_unlock(&udc_lock); - - sysfs_notify(&udc->dev.kobj, NULL, "state"); + if (udc) + sysfs_notify(&udc->dev.kobj, NULL, "state"); } void usb_gadget_set_state(struct usb_gadget *gadget, @@ -278,6 +268,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, goto err3; udc->gadget = gadget; + gadget->udc = udc; mutex_lock(&udc_lock); list_add_tail(&udc->list, &udc_list); @@ -348,21 +339,14 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) */ void usb_del_gadget_udc(struct usb_gadget *gadget) { - struct usb_udc *udc = NULL; + struct usb_udc *udc = gadget->udc; - mutex_lock(&udc_lock); - list_for_each_entry(udc, &udc_list, list) - if (udc->gadget == gadget) - goto found; - - dev_err(gadget->dev.parent, "gadget not registered.\n"); - mutex_unlock(&udc_lock); - - return; + if (!udc) + return; -found: dev_vdbg(gadget->dev.parent, "unregistering gadget\n"); + mutex_lock(&udc_lock); list_del(&udc->list); mutex_unlock(&udc_lock); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 02476b3a1109..242c694a5b85 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -474,6 +474,7 @@ struct usb_dcd_config_params { struct usb_gadget; struct usb_gadget_driver; +struct usb_udc; /* the rest of the api to the controller hardware: device operations, * which don't involve endpoints (or i/o). @@ -496,6 +497,7 @@ struct usb_gadget_ops { /** * struct usb_gadget - represents a usb slave device * @work: (internal use) Workqueue to be used for sysfs_notify() + * @udc: struct usb_udc pointer for this gadget * @ops: Function pointers used to access hardware-specific operations. * @ep0: Endpoint zero, used when reading or writing responses to * driver setup() requests @@ -545,6 +547,7 @@ struct usb_gadget_ops { */ struct usb_gadget { struct work_struct work; + struct usb_udc *udc; /* readonly to gadget driver */ const struct usb_gadget_ops *ops; struct usb_ep *ep0; |