1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/slab.h>
4 #include <linux/module.h>
7 #include <linux/usb/composite.h>
9 static LIST_HEAD(func_list
);
10 static DEFINE_MUTEX(func_lock
);
12 static struct usb_function_instance
*try_get_usb_function_instance(const char *name
)
14 struct usb_function_driver
*fd
;
15 struct usb_function_instance
*fi
;
17 fi
= ERR_PTR(-ENOENT
);
18 mutex_lock(&func_lock
);
19 list_for_each_entry(fd
, &func_list
, list
) {
21 if (strcmp(name
, fd
->name
))
24 if (!try_module_get(fd
->mod
)) {
28 fi
= fd
->alloc_inst();
35 mutex_unlock(&func_lock
);
39 struct usb_function_instance
*usb_get_function_instance(const char *name
)
41 struct usb_function_instance
*fi
;
44 fi
= try_get_usb_function_instance(name
);
50 ret
= request_module("usbfunc:%s", name
);
53 return try_get_usb_function_instance(name
);
55 EXPORT_SYMBOL_GPL(usb_get_function_instance
);
57 struct usb_function
*usb_get_function(struct usb_function_instance
*fi
)
59 struct usb_function
*f
;
61 f
= fi
->fd
->alloc_func(fi
);
67 EXPORT_SYMBOL_GPL(usb_get_function
);
69 void usb_put_function_instance(struct usb_function_instance
*fi
)
77 fi
->free_func_inst(fi
);
80 EXPORT_SYMBOL_GPL(usb_put_function_instance
);
82 void usb_put_function(struct usb_function
*f
)
89 EXPORT_SYMBOL_GPL(usb_put_function
);
91 int usb_function_register(struct usb_function_driver
*newf
)
93 struct usb_function_driver
*fd
;
98 mutex_lock(&func_lock
);
99 list_for_each_entry(fd
, &func_list
, list
) {
100 if (!strcmp(fd
->name
, newf
->name
))
104 list_add_tail(&newf
->list
, &func_list
);
106 mutex_unlock(&func_lock
);
109 EXPORT_SYMBOL_GPL(usb_function_register
);
111 void usb_function_unregister(struct usb_function_driver
*fd
)
113 mutex_lock(&func_lock
);
115 mutex_unlock(&func_lock
);
117 EXPORT_SYMBOL_GPL(usb_function_unregister
);