Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: UDC: Expand device model API interface

The routines used by the UDC core to interface with the kernel's
device model, namely usb_add_gadget_udc(),
usb_add_gadget_udc_release(), and usb_del_gadget_udc(), provide access
to only a subset of the device model's full API. They include
functionality equivalent to device_register() and device_unregister()
for gadgets, but they omit device_initialize(), device_add(),
device_del(), get_device(), and put_device().

This patch expands the UDC API by adding usb_initialize_gadget(),
usb_add_gadget(), usb_del_gadget(), usb_get_gadget(), and
usb_put_gadget() to fill in the gap. It rewrites the existing
routines to call the new ones.

CC: Anton Vasilyev <vasilyev@ispras.ru>
CC: Evgeny Novikov <novikov@ispras.ru>
CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>

authored by

Alan Stern and committed by
Felipe Balbi
3301c215 8dafb3c0

+84 -21
+63 -15
drivers/usb/gadget/udc/core.c
··· 1164 1164 } 1165 1165 1166 1166 /** 1167 - * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list 1167 + * usb_initialize_gadget - initialize a gadget and its embedded struct device 1168 1168 * @parent: the parent device to this udc. Usually the controller driver's 1169 1169 * device. 1170 - * @gadget: the gadget to be added to the list. 1170 + * @gadget: the gadget to be initialized. 1171 1171 * @release: a gadget release function. 1172 1172 * 1173 1173 * Returns zero on success, negative errno otherwise. 1174 1174 * Calls the gadget release function in the latter case. 1175 1175 */ 1176 - int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, 1176 + void usb_initialize_gadget(struct device *parent, struct usb_gadget *gadget, 1177 1177 void (*release)(struct device *dev)) 1178 1178 { 1179 - struct usb_udc *udc; 1180 - int ret = -ENOMEM; 1181 - 1182 1179 dev_set_name(&gadget->dev, "gadget"); 1183 1180 INIT_WORK(&gadget->work, usb_gadget_state_work); 1184 1181 gadget->dev.parent = parent; ··· 1186 1189 gadget->dev.release = usb_udc_nop_release; 1187 1190 1188 1191 device_initialize(&gadget->dev); 1192 + } 1193 + EXPORT_SYMBOL_GPL(usb_initialize_gadget); 1194 + 1195 + /** 1196 + * usb_add_gadget - adds a new gadget to the udc class driver list 1197 + * @gadget: the gadget to be added to the list. 1198 + * 1199 + * Returns zero on success, negative errno otherwise. 1200 + * Does not do a final usb_put_gadget() if an error occurs. 1201 + */ 1202 + int usb_add_gadget(struct usb_gadget *gadget) 1203 + { 1204 + struct usb_udc *udc; 1205 + int ret = -ENOMEM; 1189 1206 1190 1207 udc = kzalloc(sizeof(*udc), GFP_KERNEL); 1191 1208 if (!udc) 1192 - goto err_put_gadget; 1209 + goto error; 1193 1210 1194 1211 device_initialize(&udc->dev); 1195 1212 udc->dev.release = usb_udc_release; 1196 1213 udc->dev.class = udc_class; 1197 1214 udc->dev.groups = usb_udc_attr_groups; 1198 - udc->dev.parent = parent; 1199 - ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj)); 1215 + udc->dev.parent = gadget->dev.parent; 1216 + ret = dev_set_name(&udc->dev, "%s", 1217 + kobject_name(&gadget->dev.parent->kobj)); 1200 1218 if (ret) 1201 1219 goto err_put_udc; 1202 1220 ··· 1254 1242 err_put_udc: 1255 1243 put_device(&udc->dev); 1256 1244 1257 - err_put_gadget: 1258 - put_device(&gadget->dev); 1245 + error: 1246 + return ret; 1247 + } 1248 + EXPORT_SYMBOL_GPL(usb_add_gadget); 1249 + 1250 + /** 1251 + * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list 1252 + * @parent: the parent device to this udc. Usually the controller driver's 1253 + * device. 1254 + * @gadget: the gadget to be added to the list. 1255 + * @release: a gadget release function. 1256 + * 1257 + * Returns zero on success, negative errno otherwise. 1258 + * Calls the gadget release function in the latter case. 1259 + */ 1260 + int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, 1261 + void (*release)(struct device *dev)) 1262 + { 1263 + int ret; 1264 + 1265 + usb_initialize_gadget(parent, gadget, release); 1266 + ret = usb_add_gadget(gadget); 1267 + if (ret) 1268 + usb_put_gadget(gadget); 1259 1269 return ret; 1260 1270 } 1261 1271 EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release); ··· 1345 1311 } 1346 1312 1347 1313 /** 1348 - * usb_del_gadget_udc - deletes @udc from udc_list 1314 + * usb_del_gadget - deletes @udc from udc_list 1349 1315 * @gadget: the gadget to be removed. 1350 1316 * 1351 - * This, will call usb_gadget_unregister_driver() if 1317 + * This will call usb_gadget_unregister_driver() if 1352 1318 * the @udc is still busy. 1319 + * It will not do a final usb_put_gadget(). 1353 1320 */ 1354 - void usb_del_gadget_udc(struct usb_gadget *gadget) 1321 + void usb_del_gadget(struct usb_gadget *gadget) 1355 1322 { 1356 1323 struct usb_udc *udc = gadget->udc; 1357 1324 ··· 1375 1340 kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); 1376 1341 flush_work(&gadget->work); 1377 1342 device_unregister(&udc->dev); 1378 - device_unregister(&gadget->dev); 1343 + device_del(&gadget->dev); 1344 + } 1345 + EXPORT_SYMBOL_GPL(usb_del_gadget); 1346 + 1347 + /** 1348 + * usb_del_gadget_udc - deletes @udc from udc_list 1349 + * @gadget: the gadget to be removed. 1350 + * 1351 + * Calls usb_del_gadget() and does a final usb_put_gadget(). 1352 + */ 1353 + void usb_del_gadget_udc(struct usb_gadget *gadget) 1354 + { 1355 + usb_del_gadget(gadget); 1356 + usb_put_gadget(gadget); 1379 1357 memset(&gadget->dev, 0x00, sizeof(gadget->dev)); 1380 1358 } 1381 1359 EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
+21 -6
include/linux/usb/gadget.h
··· 436 436 }; 437 437 #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) 438 438 439 + /* Interface to the device model */ 439 440 static inline void set_gadget_data(struct usb_gadget *gadget, void *data) 440 441 { dev_set_drvdata(&gadget->dev, data); } 441 442 static inline void *get_gadget_data(struct usb_gadget *gadget) ··· 445 444 { 446 445 return container_of(dev, struct usb_gadget, dev); 447 446 } 447 + static inline struct usb_gadget *usb_get_gadget(struct usb_gadget *gadget) 448 + { 449 + get_device(&gadget->dev); 450 + return gadget; 451 + } 452 + static inline void usb_put_gadget(struct usb_gadget *gadget) 453 + { 454 + put_device(&gadget->dev); 455 + } 456 + extern void usb_initialize_gadget(struct device *parent, 457 + struct usb_gadget *gadget, void (*release)(struct device *dev)); 458 + extern int usb_add_gadget(struct usb_gadget *gadget); 459 + extern void usb_del_gadget(struct usb_gadget *gadget); 460 + 461 + /* Legacy device-model interface */ 462 + extern int usb_add_gadget_udc_release(struct device *parent, 463 + struct usb_gadget *gadget, void (*release)(struct device *dev)); 464 + extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); 465 + extern void usb_del_gadget_udc(struct usb_gadget *gadget); 466 + extern char *usb_get_gadget_udc_name(void); 448 467 449 468 /* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */ 450 469 #define gadget_for_each_ep(tmp, gadget) \ ··· 755 734 * will be in exit sections, so may not be linked in some kernels. 756 735 */ 757 736 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver); 758 - 759 - extern int usb_add_gadget_udc_release(struct device *parent, 760 - struct usb_gadget *gadget, void (*release)(struct device *dev)); 761 - extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); 762 - extern void usb_del_gadget_udc(struct usb_gadget *gadget); 763 - extern char *usb_get_gadget_udc_name(void); 764 737 765 738 /*-------------------------------------------------------------------------*/ 766 739