mmc: rtsx_pci: Enable MMC_CAP_ERASE to allow erase/discard/trim requests
[linux/fpc-iii.git] / drivers / usb / usbip / vudc_main.c
blob9e655714e389120808446a6b52d6676192df457a
1 /*
2 * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
3 * Copyright (C) 2015-2016 Samsung Electronics
4 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
5 * Krzysztof Opasiak <k.opasiak@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <linux/device.h>
22 #include <linux/list.h>
23 #include <linux/module.h>
25 #include "vudc.h"
27 static unsigned int vudc_number = 1;
29 module_param_named(num, vudc_number, uint, S_IRUGO);
30 MODULE_PARM_DESC(num, "number of emulated controllers");
32 static struct platform_driver vudc_driver = {
33 .probe = vudc_probe,
34 .remove = vudc_remove,
35 .driver = {
36 .name = GADGET_NAME,
40 static struct list_head vudc_devices = LIST_HEAD_INIT(vudc_devices);
42 static int __init init(void)
44 int retval = -ENOMEM;
45 int i;
46 struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
48 if (usb_disabled())
49 return -ENODEV;
51 if (vudc_number < 1) {
52 pr_err("Number of emulated UDC must be no less than 1");
53 return -EINVAL;
56 retval = platform_driver_register(&vudc_driver);
57 if (retval < 0)
58 goto out;
60 for (i = 0; i < vudc_number; i++) {
61 udc_dev = alloc_vudc_device(i);
62 if (!udc_dev) {
63 retval = -ENOMEM;
64 goto cleanup;
67 retval = platform_device_add(udc_dev->pdev);
68 if (retval < 0) {
69 put_vudc_device(udc_dev);
70 goto cleanup;
73 list_add_tail(&udc_dev->dev_entry, &vudc_devices);
74 if (!platform_get_drvdata(udc_dev->pdev)) {
76 * The udc was added successfully but its probe
77 * function failed for some reason.
79 retval = -EINVAL;
80 goto cleanup;
83 goto out;
85 cleanup:
86 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
87 list_del(&udc_dev->dev_entry);
88 platform_device_del(udc_dev->pdev);
89 put_vudc_device(udc_dev);
92 platform_driver_unregister(&vudc_driver);
93 out:
94 return retval;
96 module_init(init);
98 static void __exit cleanup(void)
100 struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
102 list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
103 list_del(&udc_dev->dev_entry);
104 platform_device_unregister(udc_dev->pdev);
105 put_vudc_device(udc_dev);
107 platform_driver_unregister(&vudc_driver);
109 module_exit(cleanup);
111 MODULE_DESCRIPTION("USB over IP Device Controller");
112 MODULE_AUTHOR("Krzysztof Opasiak, Karol Kosik, Igor Kotrasinski");
113 MODULE_LICENSE("GPL");