aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/udc/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/udc/core.c')
-rw-r--r--drivers/usb/gadget/udc/core.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 0402177f93cd..d685d82dcf48 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -1080,6 +1080,24 @@ static void usb_udc_nop_release(struct device *dev)
1080 dev_vdbg(dev, "%s\n", __func__); 1080 dev_vdbg(dev, "%s\n", __func__);
1081} 1081}
1082 1082
1083/* should be called with udc_lock held */
1084static int check_pending_gadget_drivers(struct usb_udc *udc)
1085{
1086 struct usb_gadget_driver *driver;
1087 int ret = 0;
1088
1089 list_for_each_entry(driver, &gadget_driver_pending_list, pending)
1090 if (!driver->udc_name || strcmp(driver->udc_name,
1091 dev_name(&udc->dev)) == 0) {
1092 ret = udc_bind_to_driver(udc, driver);
1093 if (ret != -EPROBE_DEFER)
1094 list_del(&driver->pending);
1095 break;
1096 }
1097
1098 return ret;
1099}
1100
1083/** 1101/**
1084 * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list 1102 * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
1085 * @parent: the parent device to this udc. Usually the controller driver's 1103 * @parent: the parent device to this udc. Usually the controller driver's
@@ -1093,7 +1111,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
1093 void (*release)(struct device *dev)) 1111 void (*release)(struct device *dev))
1094{ 1112{
1095 struct usb_udc *udc; 1113 struct usb_udc *udc;
1096 struct usb_gadget_driver *driver;
1097 int ret = -ENOMEM; 1114 int ret = -ENOMEM;
1098 1115
1099 udc = kzalloc(sizeof(*udc), GFP_KERNEL); 1116 udc = kzalloc(sizeof(*udc), GFP_KERNEL);
@@ -1136,17 +1153,9 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
1136 udc->vbus = true; 1153 udc->vbus = true;
1137 1154
1138 /* pick up one of pending gadget drivers */ 1155 /* pick up one of pending gadget drivers */
1139 list_for_each_entry(driver, &gadget_driver_pending_list, pending) { 1156 ret = check_pending_gadget_drivers(udc);
1140 if (!driver->udc_name || strcmp(driver->udc_name, 1157 if (ret)
1141 dev_name(&udc->dev)) == 0) { 1158 goto err5;
1142 ret = udc_bind_to_driver(udc, driver);
1143 if (ret != -EPROBE_DEFER)
1144 list_del(&driver->pending);
1145 if (ret)
1146 goto err5;
1147 break;
1148 }
1149 }
1150 1159
1151 mutex_unlock(&udc_lock); 1160 mutex_unlock(&udc_lock);
1152 1161
@@ -1356,14 +1365,22 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1356 return -EINVAL; 1365 return -EINVAL;
1357 1366
1358 mutex_lock(&udc_lock); 1367 mutex_lock(&udc_lock);
1359 list_for_each_entry(udc, &udc_list, list) 1368 list_for_each_entry(udc, &udc_list, list) {
1360 if (udc->driver == driver) { 1369 if (udc->driver == driver) {
1361 usb_gadget_remove_driver(udc); 1370 usb_gadget_remove_driver(udc);
1362 usb_gadget_set_state(udc->gadget, 1371 usb_gadget_set_state(udc->gadget,
1363 USB_STATE_NOTATTACHED); 1372 USB_STATE_NOTATTACHED);
1373
1374 /* Maybe there is someone waiting for this UDC? */
1375 check_pending_gadget_drivers(udc);
1376 /*
1377 * For now we ignore bind errors as probably it's
1378 * not a valid reason to fail other's gadget unbind
1379 */
1364 ret = 0; 1380 ret = 0;
1365 break; 1381 break;
1366 } 1382 }
1383 }
1367 1384
1368 if (ret) { 1385 if (ret) {
1369 list_del(&driver->pending); 1386 list_del(&driver->pending);