#include <linux/ctype.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
+#include <linux/idr.h>
 #include <linux/kref.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 
 /*----------------------------------------------------------------------*/
 
+static DEFINE_IDA(driver_id_numbers);
+#define DRIVER_DRIVER_NAME_LENGTH_MAX  32
+
 #define RAW_EVENT_QUEUE_SIZE   16
 
 struct raw_event_queue {
        /* Reference to misc device: */
        struct device                   *dev;
 
+       /* Make driver names unique */
+       int                             driver_id_number;
+
        /* Protected by lock: */
        enum dev_state                  state;
        bool                            gadget_registered;
        spin_lock_init(&dev->lock);
        init_completion(&dev->ep0_done);
        raw_event_queue_init(&dev->queue);
+       dev->driver_id_number = -1;
        return dev;
 }
 
 
        kfree(dev->udc_name);
        kfree(dev->driver.udc_name);
+       kfree(dev->driver.driver.name);
+       if (dev->driver_id_number >= 0)
+               ida_free(&driver_id_numbers, dev->driver_id_number);
        if (dev->req) {
                if (dev->ep0_urb_queued)
                        usb_ep_dequeue(dev->gadget->ep0, dev->req);
        struct usb_raw_init arg;
        char *udc_driver_name;
        char *udc_device_name;
+       char *driver_driver_name;
        unsigned long flags;
 
        if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
                return -EINVAL;
        }
 
+       ret = ida_alloc(&driver_id_numbers, GFP_KERNEL);
+       if (ret < 0)
+               return ret;
+       dev->driver_id_number = ret;
+
+       driver_driver_name = kmalloc(DRIVER_DRIVER_NAME_LENGTH_MAX, GFP_KERNEL);
+       if (!driver_driver_name) {
+               ret = -ENOMEM;
+               goto out_free_driver_id_number;
+       }
+       snprintf(driver_driver_name, DRIVER_DRIVER_NAME_LENGTH_MAX,
+                               DRIVER_NAME ".%d", dev->driver_id_number);
+
        udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL);
-       if (!udc_driver_name)
-               return -ENOMEM;
+       if (!udc_driver_name) {
+               ret = -ENOMEM;
+               goto out_free_driver_driver_name;
+       }
        ret = strscpy(udc_driver_name, &arg.driver_name[0],
                                UDC_NAME_LENGTH_MAX);
-       if (ret < 0) {
-               kfree(udc_driver_name);
-               return ret;
-       }
+       if (ret < 0)
+               goto out_free_udc_driver_name;
        ret = 0;
 
        udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL);
        if (!udc_device_name) {
-               kfree(udc_driver_name);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_free_udc_driver_name;
        }
        ret = strscpy(udc_device_name, &arg.device_name[0],
                                UDC_NAME_LENGTH_MAX);
-       if (ret < 0) {
-               kfree(udc_driver_name);
-               kfree(udc_device_name);
-               return ret;
-       }
+       if (ret < 0)
+               goto out_free_udc_device_name;
        ret = 0;
 
        spin_lock_irqsave(&dev->lock, flags);
        if (dev->state != STATE_DEV_OPENED) {
                dev_dbg(dev->dev, "fail, device is not opened\n");
-               kfree(udc_driver_name);
-               kfree(udc_device_name);
                ret = -EINVAL;
                goto out_unlock;
        }
        dev->driver.suspend = gadget_suspend;
        dev->driver.resume = gadget_resume;
        dev->driver.reset = gadget_reset;
-       dev->driver.driver.name = DRIVER_NAME;
+       dev->driver.driver.name = driver_driver_name;
        dev->driver.udc_name = udc_device_name;
        dev->driver.match_existing_only = 1;
 
        dev->state = STATE_DEV_INITIALIZED;
+       spin_unlock_irqrestore(&dev->lock, flags);
+       return ret;
 
 out_unlock:
        spin_unlock_irqrestore(&dev->lock, flags);
+out_free_udc_device_name:
+       kfree(udc_device_name);
+out_free_udc_driver_name:
+       kfree(udc_driver_name);
+out_free_driver_driver_name:
+       kfree(driver_driver_name);
+out_free_driver_id_number:
+       ida_free(&driver_id_numbers, dev->driver_id_number);
        return ret;
 }