|
@@ -2142,6 +2142,7 @@ end:
|
|
|
void composite_dev_cleanup(struct usb_composite_dev *cdev)
|
|
|
{
|
|
|
struct usb_gadget_string_container *uc, *tmp;
|
|
|
+ struct usb_ep *ep, *tmp_ep;
|
|
|
|
|
|
list_for_each_entry_safe(uc, tmp, &cdev->gstrings, list) {
|
|
|
list_del(&uc->list);
|
|
@@ -2163,6 +2164,21 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev)
|
|
|
}
|
|
|
cdev->next_string_id = 0;
|
|
|
device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Some UDC backends have a dynamic EP allocation scheme.
|
|
|
+ *
|
|
|
+ * In that case, the dispose() callback is used to notify the
|
|
|
+ * backend that the EPs are no longer in use.
|
|
|
+ *
|
|
|
+ * Note: The UDC backend can remove the EP from the ep_list as
|
|
|
+ * a result, so we need to use the _safe list iterator.
|
|
|
+ */
|
|
|
+ list_for_each_entry_safe(ep, tmp_ep,
|
|
|
+ &cdev->gadget->ep_list, ep_list) {
|
|
|
+ if (ep->ops->dispose)
|
|
|
+ ep->ops->dispose(ep);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static int composite_bind(struct usb_gadget *gadget,
|