root/drivers/usb/usbip/vudc_main.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cleanup

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
   4  * Copyright (C) 2015-2016 Samsung Electronics
   5  *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
   6  *               Krzysztof Opasiak <k.opasiak@samsung.com>
   7  */
   8 
   9 #include <linux/device.h>
  10 #include <linux/list.h>
  11 #include <linux/module.h>
  12 
  13 #include "vudc.h"
  14 
  15 static unsigned int vudc_number = 1;
  16 
  17 module_param_named(num, vudc_number, uint, S_IRUGO);
  18 MODULE_PARM_DESC(num, "number of emulated controllers");
  19 
  20 static struct platform_driver vudc_driver = {
  21         .probe          = vudc_probe,
  22         .remove         = vudc_remove,
  23         .driver         = {
  24                 .name   = GADGET_NAME,
  25                 .dev_groups = vudc_groups,
  26         },
  27 };
  28 
  29 static struct list_head vudc_devices = LIST_HEAD_INIT(vudc_devices);
  30 
  31 static int __init init(void)
  32 {
  33         int retval = -ENOMEM;
  34         int i;
  35         struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
  36 
  37         if (usb_disabled())
  38                 return -ENODEV;
  39 
  40         if (vudc_number < 1) {
  41                 pr_err("Number of emulated UDC must be no less than 1");
  42                 return -EINVAL;
  43         }
  44 
  45         retval = platform_driver_register(&vudc_driver);
  46         if (retval < 0)
  47                 goto out;
  48 
  49         for (i = 0; i < vudc_number; i++) {
  50                 udc_dev = alloc_vudc_device(i);
  51                 if (!udc_dev) {
  52                         retval = -ENOMEM;
  53                         goto cleanup;
  54                 }
  55 
  56                 retval = platform_device_add(udc_dev->pdev);
  57                 if (retval < 0) {
  58                         put_vudc_device(udc_dev);
  59                         goto cleanup;
  60                 }
  61 
  62                 list_add_tail(&udc_dev->dev_entry, &vudc_devices);
  63                 if (!platform_get_drvdata(udc_dev->pdev)) {
  64                         /*
  65                          * The udc was added successfully but its probe
  66                          * function failed for some reason.
  67                          */
  68                         retval = -EINVAL;
  69                         goto cleanup;
  70                 }
  71         }
  72         goto out;
  73 
  74 cleanup:
  75         list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
  76                 list_del(&udc_dev->dev_entry);
  77                 /*
  78                  * Just do platform_device_del() here, put_vudc_device()
  79                  * calls the platform_device_put()
  80                  */
  81                 platform_device_del(udc_dev->pdev);
  82                 put_vudc_device(udc_dev);
  83         }
  84 
  85         platform_driver_unregister(&vudc_driver);
  86 out:
  87         return retval;
  88 }
  89 module_init(init);
  90 
  91 static void __exit cleanup(void)
  92 {
  93         struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
  94 
  95         list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
  96                 list_del(&udc_dev->dev_entry);
  97                 /*
  98                  * Just do platform_device_del() here, put_vudc_device()
  99                  * calls the platform_device_put()
 100                  */
 101                 platform_device_del(udc_dev->pdev);
 102                 put_vudc_device(udc_dev);
 103         }
 104         platform_driver_unregister(&vudc_driver);
 105 }
 106 module_exit(cleanup);
 107 
 108 MODULE_DESCRIPTION("USB over IP Device Controller");
 109 MODULE_AUTHOR("Krzysztof Opasiak, Karol Kosik, Igor Kotrasinski");
 110 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */