From dfea9c94837d27e38c8cc85a3c1c7c268973c3c2 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 6 Mar 2015 10:36:02 +0800 Subject: [PATCH] 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 Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/udc-core.c | 34 ++++++++----------------------- 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; -- 2.30.2