#
 ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
 
+obj-$(CONFIG_USB_GADGET)       += udc-core.o
 obj-$(CONFIG_USB_DUMMY_HCD)    += dummy_hcd.o
 obj-$(CONFIG_USB_NET2272)      += net2272.o
 obj-$(CONFIG_USB_NET2280)      += net2280.o
 
        return 0;
 }
 
+static int amd5536_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int amd5536_stop(struct usb_gadget_driver *driver);
 /* gadget operations */
 static const struct usb_gadget_ops udc_ops = {
        .wakeup         = udc_wakeup,
        .get_frame      = udc_get_frame,
+       .start          = amd5536_start,
+       .stop           = amd5536_stop,
 };
 
 /* Setups endpoint parameters, adds endpoints to linked list */
 }
 
 /* Called by gadget driver to register itself */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int amd5536_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct udc              *dev = udc;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /* shutdown requests and disconnect from gadget */
 static void
 }
 
 /* Called by gadget driver to unregister itself */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int amd5536_stop(struct usb_gadget_driver *driver)
 {
        struct udc      *dev = udc;
        unsigned long   flags;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 
 /* Clear pending NAK bits */
 static void udc_process_cnak_queue(struct udc *dev)
 
        dev = pci_get_drvdata(pdev);
 
+       usb_del_gadget_udc(&udc->gadget);
        /* gadget driver must not be registered */
        BUG_ON(dev->driver != NULL);
 
                "driver version: %s(for Geode5536 B1)\n", tmp);
        udc = dev;
 
+       retval = usb_add_gadget_udc(&udc->pdev->dev, &dev->gadget);
+       if (retval)
+               goto finished;
+
        retval = device_register(&dev->gadget.dev);
        if (retval) {
+               usb_del_gadget_udc(&dev->gadget);
                put_device(&dev->gadget.dev);
                goto finished;
        }
 
        return 0;
 }
 
+static int at91_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int at91_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops at91_udc_ops = {
        .get_frame              = at91_get_frame,
        .wakeup                 = at91_wakeup,
        .set_selfpowered        = at91_set_selfpowered,
        .vbus_session           = at91_vbus_session,
        .pullup                 = at91_pullup,
+       .start                  = at91_start,
+       .stop                   = at91_stop,
 
        /*
         * VBUS-powered devices may also also want to support bigger
                schedule_work(&udc->vbus_timer_work);
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int at91_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct at91_udc *udc = &controller;
        DBG("bound to %s\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+static int at91_stop(struct usb_gadget_driver *driver)
 {
        struct at91_udc *udc = &controller;
        unsigned long   flags;
        DBG("unbound from %s\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL (usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------*/
 
                DBG("no VBUS detection, assuming always-on\n");
                udc->vbus = 1;
        }
+       retval = usb_add_gadget_udc(dev, &udc->gadget);
+       if (retval)
+               goto fail4;
        dev_set_drvdata(dev, udc);
        device_init_wakeup(dev, 1);
        create_debug_file(udc);
 
        INFO("%s version %s\n", driver_name, DRIVER_VERSION);
        return 0;
-
+fail4:
+       if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled)
+               free_irq(udc->board.vbus_pin, udc);
 fail3:
        if (udc->board.vbus_pin > 0)
                gpio_free(udc->board.vbus_pin);
 
        DBG("remove\n");
 
+       usb_del_gadget_udc(&udc->gadget);
        if (udc->driver)
                return -EBUSY;
 
 
        return 0;
 }
 
+static int atmel_usba_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int atmel_usba_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops usba_udc_ops = {
        .get_frame              = usba_udc_get_frame,
        .wakeup                 = usba_udc_wakeup,
        .set_selfpowered        = usba_udc_set_selfpowered,
+       .start                  = atmel_usba_start,
+       .stop                   = atmel_usba_stop,
 };
 
 static struct usb_endpoint_descriptor usba_ep0_desc = {
        return IRQ_HANDLED;
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int atmel_usba_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct usba_udc *udc = &the_udc;
        udc->gadget.dev.driver = NULL;
        return ret;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int atmel_usba_stop(struct usb_gadget_driver *driver)
 {
        struct usba_udc *udc = &the_udc;
        unsigned long flags;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static int __init usba_udc_probe(struct platform_device *pdev)
 {
                }
        }
 
+       ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
+       if (ret)
+               goto err_add_udc;
+
        usba_init_debugfs(udc);
        for (i = 1; i < pdata->num_ep; i++)
                usba_ep_init_debugfs(udc, &usba_ep[i]);
 
        return 0;
 
+err_add_udc:
+       if (gpio_is_valid(pdata->vbus_pin)) {
+               free_irq(gpio_to_irq(udc->vbus_pin), udc);
+               gpio_free(udc->vbus_pin);
+       }
+
+       device_unregister(&udc->gadget.dev);
+
 err_device_add:
        free_irq(irq, udc);
 err_request_irq:
 
        udc = platform_get_drvdata(pdev);
 
+       usb_del_gadget_udc(&udc->gadget);
+
        for (i = 1; i < pdata->num_ep; i++)
                usba_ep_cleanup_debugfs(&usba_ep[i]);
        usba_cleanup_debugfs(udc);
 
        stamp = stamp * 1000000 + tval.tv_usec;
 
        scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
-                 "%04X\t» %02X %-7.7s %4i «\t%s\n",
+                 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
                  stamp, addr, name, status, extra);
 
        dbg_inc(&dbg_data.idx);
        write_unlock_irqrestore(&dbg_data.lck, flags);
 
        if (dbg_data.tty != 0)
-               pr_notice("%04X\t» %02X %-7.7s %4i «\t%s\n",
+               pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
                          stamp, addr, name, status, extra);
 }
 
 
        n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
                       isr_statistics.test);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» ui  = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? ui  = %d\n",
                       isr_statistics.ui);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» uei = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
                       isr_statistics.uei);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» pci = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
                       isr_statistics.pci);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» uri = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
                       isr_statistics.uri);
-       n += scnprintf(buf + n, PAGE_SIZE - n, "» sli = %d\n",
+       n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
                       isr_statistics.sli);
        n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
                       isr_statistics.none);
        return -ENOTSUPP;
 }
 
+static int ci13xxx_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int ci13xxx_stop(struct usb_gadget_driver *driver);
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
        .vbus_session   = ci13xxx_vbus_session,
        .wakeup         = ci13xxx_wakeup,
        .vbus_draw      = ci13xxx_vbus_draw,
+       .start          = ci13xxx_start,
+       .stop           = ci13xxx_stop,
 };
 
 /**
- * usb_gadget_probe_driver: register a gadget driver
+ * ci13xxx_start: register a gadget driver
  * @driver: the driver being registered
  * @bind: the driver's bind callback
  *
- * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
+ * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
  * Interrupts are enabled here.
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int ci13xxx_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct ci13xxx *udc = _udc;
        spin_unlock_irqrestore(udc->lock, flags);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /**
- * usb_gadget_unregister_driver: unregister a gadget driver
+ * ci13xxx_stop: unregister a gadget driver
  *
  * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
  */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int ci13xxx_stop(struct usb_gadget_driver *driver)
 {
        struct ci13xxx *udc = _udc;
        unsigned long i, flags;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /******************************************************************************
  * BUS block
                if (retval)
                        goto remove_dbg;
        }
+
+       retval = usb_add_gadget_udc(dev, &udc->gadget);
+       if (retval)
+               goto remove_trans;
+
        pm_runtime_no_callbacks(&udc->gadget.dev);
        pm_runtime_enable(&udc->gadget.dev);
 
        _udc = udc;
        return retval;
 
+remove_trans:
+       if (udc->transceiver) {
+               otg_set_peripheral(udc->transceiver, &udc->gadget);
+               otg_put_transceiver(udc->transceiver);
+       }
+
        err("error = %i", retval);
 remove_dbg:
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
                err("EINVAL");
                return;
        }
+       usb_del_gadget_udc(&udc->gadget);
 
        if (udc->transceiver) {
                otg_set_peripheral(udc->transceiver, &udc->gadget);
 
        return 0;
 }
 
+static int dummy_udc_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int dummy_udc_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops dummy_ops = {
        .get_frame      = dummy_g_get_frame,
        .wakeup         = dummy_wakeup,
        .set_selfpowered = dummy_set_selfpowered,
        .pullup         = dummy_pullup,
+       .start          = dummy_udc_start,
+       .stop           = dummy_udc_stop,
 };
 
 /*-------------------------------------------------------------------------*/
  * for each driver that registers:  just add to a big root hub.
  */
 
-int
-usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int dummy_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct dummy    *dum = the_controller;
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int
-usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+static int dummy_udc_stop(struct usb_gadget_driver *driver)
 {
        struct dummy    *dum = the_controller;
        unsigned long   flags;
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
 }
-EXPORT_SYMBOL (usb_gadget_unregister_driver);
 
 #undef is_enabled
 
                return rc;
        }
 
+       rc = usb_add_gadget_udc(&pdev->dev, &dum->gadget);
+       if (rc < 0)
+               goto err_udc;
+
        rc = device_create_file (&dum->gadget.dev, &dev_attr_function);
        if (rc < 0)
-               device_unregister (&dum->gadget.dev);
-       else
-               platform_set_drvdata(pdev, dum);
+               goto err_dev;
+       platform_set_drvdata(pdev, dum);
+       return rc;
+
+err_dev:
+       usb_del_gadget_udc(&dum->gadget);
+err_udc:
+       device_unregister(&dum->gadget.dev);
        return rc;
 }
 
 {
        struct dummy    *dum = platform_get_drvdata (pdev);
 
+       usb_del_gadget_udc(&dum->gadget);
        platform_set_drvdata (pdev, NULL);
        device_remove_file (&dum->gadget.dev, &dev_attr_function);
        device_unregister (&dum->gadget.dev);
        dum = hcd_to_dummy (hcd);
 
        device_remove_file (dummy_dev(dum), &dev_attr_urbs);
-       usb_gadget_unregister_driver (dum->driver);
        dev_info (dummy_dev(dum), "stopped\n");
 }
 
 
        return -ENOTSUPP;
 }
 
+static int fsl_qe_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int fsl_qe_stop(struct usb_gadget_driver *driver);
+
 /* defined in usb_gadget.h */
 static struct usb_gadget_ops qe_gadget_ops = {
        .get_frame = qe_get_frame,
        .vbus_session = qe_vbus_session,
        .vbus_draw = qe_vbus_draw,
        .pullup = qe_pullup,
+       .start = fsl_qe_start,
+       .stop = fsl_qe_stop,
 };
 
 /*-------------------------------------------------------------------------
 /*-------------------------------------------------------------------------
        Gadget driver probe and unregister.
  --------------------------------------------------------------------------*/
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int fsl_qe_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        int retval;
                udc_controller->gadget.name, driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int fsl_qe_stop(struct usb_gadget_driver *driver)
 {
        struct qe_ep *loop_ep;
        unsigned long flags;
                        driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /* udc structure's alloc and setup, include ep-param alloc */
 static struct qe_udc __devinit *qe_udc_config(struct platform_device *ofdev)
        if (ret)
                goto err6;
 
+       ret = usb_add_gadget_udc(&ofdev->dev, &udc_controller->gadget);
+       if (ret)
+               goto err7;
+
        dev_info(udc_controller->dev,
                        "%s USB controller initialized as device\n",
                        (udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
        return 0;
 
+err7:
+       device_unregister(&udc_controller->gadget.dev);
 err6:
        free_irq(udc_controller->usb_irq, udc_controller);
 err5:
        if (!udc_controller)
                return -ENODEV;
 
+       usb_del_gadget_udc(&udc_controller->gadget);
+
        udc_controller->done = &done;
        tasklet_disable(&udc_controller->rx_tasklet);
 
 
        return 0;
 }
 
+static int fsl_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int fsl_stop(struct usb_gadget_driver *driver);
 /* defined in gadget.h */
 static struct usb_gadget_ops fsl_gadget_ops = {
        .get_frame = fsl_get_frame,
        .vbus_session = fsl_vbus_session,
        .vbus_draw = fsl_vbus_draw,
        .pullup = fsl_pullup,
+       .start = fsl_start,
+       .stop = fsl_stop,
 };
 
 /* Set protocol stall on ep0, protocol stall will automatically be cleared
  * Hook to gadget drivers
  * Called by initialization code of gadget drivers
 *----------------------------------------------------------------*/
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int fsl_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        int retval = -ENODEV;
                       retval);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /* Disconnect from gadget driver */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int fsl_stop(struct usb_gadget_driver *driver)
 {
        struct fsl_ep *loop_ep;
        unsigned long flags;
               driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------
                PROC File System Support
                ret = -ENOMEM;
                goto err_unregister;
        }
+
+       ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget);
+       if (ret)
+               goto err_del_udc;
+
        create_proc_file();
        return 0;
 
+err_del_udc:
+       dma_pool_destroy(udc_controller->td_pool);
 err_unregister:
        device_unregister(&udc_controller->gadget.dev);
 err_free_irq:
 
        if (!udc_controller)
                return -ENODEV;
+
+       usb_del_gadget_udc(&udc_controller->gadget);
        udc_controller->done = &done;
 
        fsl_udc_clk_release();
 
 /*------------------------------------------------------------------------*/
 static struct fusb300 *the_controller;
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int fusb300_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct fusb300 *fusb300 = the_controller;
 
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int fusb300_udc_stop(struct usb_gadget_driver *driver)
 {
        struct fusb300 *fusb300 = the_controller;
 
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 /*--------------------------------------------------------------------------*/
 
 static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active)
 
 static struct usb_gadget_ops fusb300_gadget_ops = {
        .pullup         = fusb300_udc_pullup,
+       .start          = fusb300_udc_start,
+       .stop           = fusb300_udc_stop,
 };
 
 static int __exit fusb300_remove(struct platform_device *pdev)
 {
        struct fusb300 *fusb300 = dev_get_drvdata(&pdev->dev);
 
+       usb_del_gadget_udc(&fusb300->gadget);
        iounmap(fusb300->reg);
        free_irq(platform_get_irq(pdev, 0), fusb300);
 
                goto clean_up3;
 
        init_controller(fusb300);
+       ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget);
+       if (ret)
+               goto err_add_udc;
+
        dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
 
        return 0;
+err_add_udc:
+       fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req);
 
 clean_up3:
        free_irq(ires->start, fusb300);
 
        return -EOPNOTSUPP;
 }
 
+static int goku_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int goku_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops goku_ops = {
        .get_frame      = goku_get_frame,
+       .start          = goku_start,
+       .stop           = goku_stop,
        // no remote wakeup
        // not selfpowered
 };
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int goku_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct goku_udc *dev = the_controller;
        DBG(dev, "registered gadget driver '%s'\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
                udc_enable(dev);
 }
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int goku_stop(struct usb_gadget_driver *driver)
 {
        struct goku_udc *dev = the_controller;
        unsigned long   flags;
        DBG(dev, "unregistered driver '%s'\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 
 /*-------------------------------------------------------------------------*/
 
 
        DBG(dev, "%s\n", __func__);
 
+       usb_del_gadget_udc(&dev->gadget);
+
        BUG_ON(dev->driver);
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
                goto err;
        }
        dev->registered = 1;
+       retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
+       if (retval)
+               goto err;
+
        return 0;
 
 err:
 
  *******************************************************************************
  */
 
+static int imx_udc_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int imx_udc_stop(struct usb_gadget_driver *driver);
 static const struct usb_gadget_ops imx_udc_ops = {
        .get_frame       = imx_udc_get_frame,
        .wakeup          = imx_udc_wakeup,
+       .start          = imx_udc_start,
+       .stop           = imx_udc_stop,
 };
 
 static struct imx_udc_struct controller = {
  * USB gadget driver functions
  *******************************************************************************
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int imx_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct imx_udc_struct *imx_usb = &controller;
        imx_usb->gadget.dev.driver = NULL;
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int imx_udc_stop(struct usb_gadget_driver *driver)
 {
        struct imx_udc_struct *imx_usb = &controller;
 
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*******************************************************************************
  * Module functions
        imx_usb->timer.function = handle_config;
        imx_usb->timer.data = (unsigned long)imx_usb;
 
-       return 0;
+       ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget);
+       if (ret)
+               goto fail4;
 
+       return 0;
+fail4:
+       for (i = 0; i < IMX_USB_NB_EP + 1; i++)
+               free_irq(imx_usb->usbd_int[i], imx_usb);
 fail3:
        clk_put(clk);
        clk_disable(clk);
        struct imxusb_platform_data *pdata = pdev->dev.platform_data;
        int i;
 
+       usb_del_gadget_udc(&imx_usb->gadget);
        imx_udc_disable(imx_usb);
        del_timer(&imx_usb->timer);
 
 
        return 0;
 }
 
-
+static int langwell_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int langwell_stop(struct usb_gadget_driver *driver);
 /* device controller usb_gadget_ops structure */
 static const struct usb_gadget_ops langwell_ops = {
 
 
        /* D+ pullup, software-controlled connect/disconnect to USB host */
        .pullup         = langwell_pullup,
+
+       .start          = langwell_start,
+       .stop           = langwell_stop,
 };
 
 
  * the driver might get unbound.
  */
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int langwell_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct langwell_udc     *dev = the_controller;
        dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
-
 
 /* unregister gadget driver */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int langwell_stop(struct usb_gadget_driver *driver)
 {
        struct langwell_udc     *dev = the_controller;
        unsigned long           flags;
        dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 
 /*-------------------------------------------------------------------------*/
 
        if (retval)
                goto error;
 
+       retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
+       if (retval)
+               goto error;
+
        retval = device_create_file(&pdev->dev, &dev_attr_langwell_udc);
        if (retval)
                goto error;
 
        dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
+       usb_del_gadget_udc(&dev->gadget);
        /* disable interrupt and set controller to stop state */
        langwell_udc_stop(dev);
 
 
 /*-------------------------------------------------------------------------*/
 static struct m66592 *the_controller;
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int m66592_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct m66592 *m66592 = the_controller;
 
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int m66592_stop(struct usb_gadget_driver *driver)
 {
        struct m66592 *m66592 = the_controller;
        unsigned long flags;
        m66592->driver = NULL;
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------*/
 static int m66592_get_frame(struct usb_gadget *_gadget)
 
 static struct usb_gadget_ops m66592_gadget_ops = {
        .get_frame              = m66592_get_frame,
+       .start                  = m66592_start,
+       .stop                   = m66592_stop,
 };
 
 static int __exit m66592_remove(struct platform_device *pdev)
 {
        struct m66592           *m66592 = dev_get_drvdata(&pdev->dev);
 
+       usb_del_gadget_udc(&m66592->gadget);
+
        del_timer_sync(&m66592->timer);
        iounmap(m66592->reg);
        free_irq(platform_get_irq(pdev, 0), m66592);
 
        init_controller(m66592);
 
+       ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget);
+       if (ret)
+               goto err_add_udc;
+
        dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
        return 0;
 
+err_add_udc:
+       m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
+
 clean_up3:
 #ifdef CONFIG_HAVE_CLK
        if (m66592->pdata->on_chip) {
 
        return 0;
 }
 
+static int mv_udc_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int mv_udc_stop(struct usb_gadget_driver *driver);
 /* device controller usb_gadget_ops structure */
 static const struct usb_gadget_ops mv_ops = {
 
 
        /* D+ pullup, software-controlled connect/disconnect to USB host */
        .pullup         = mv_udc_pullup,
+       .start          = mv_udc_start,
+       .stop           = mv_udc_stop,
 };
 
 static void mv_udc_testmode(struct mv_udc *udc, u16 index, bool enter)
        }
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int mv_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct mv_udc *udc = the_controller;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int mv_udc_stop(struct usb_gadget_driver *driver)
 {
        struct mv_udc *udc = the_controller;
        unsigned long flags;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static int
 udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty)
 static int mv_udc_remove(struct platform_device *dev)
 {
        struct mv_udc *udc = the_controller;
-
        DECLARE_COMPLETION(done);
 
+       usb_del_gadget_udc(&udc->gadget);
+
        udc->done = &done;
 
        /* free memory allocated in probe */
 
        the_controller = udc;
 
-       goto out;
+       retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
+       if (!retval)
+               return retval;
 error:
        if (udc)
                mv_udc_remove(udc->dev);
-out:
        return retval;
 }
 
 
        return 0;
 }
 
+static int net2272_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int net2272_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops net2272_ops = {
        .get_frame       = net2272_get_frame,
        .wakeup          = net2272_wakeup,
        .set_selfpowered = net2272_set_selfpowered,
-       .pullup          = net2272_pullup
+       .pullup                 = net2272_pullup,
+       .start                  = net2272_start,
+       .stop                   = net2272_stop,
 };
 
 /*---------------------------------------------------------------------------*/
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int net2272_start(struct usb_gadget_driver *driver,
        int (*bind)(struct usb_gadget *))
 {
        struct net2272 *dev = the_controller;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver)
        net2272_usb_reinit(dev);
 }
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int net2272_stop(struct usb_gadget_driver *driver)
 {
        struct net2272 *dev = the_controller;
        unsigned long flags;
        dev_dbg(dev->dev, "unregistered driver '%s'\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*---------------------------------------------------------------------------*/
 /* handle ep-a/ep-b dma completions */
 static void __devexit
 net2272_remove(struct net2272 *dev)
 {
+       usb_del_gadget_udc(&dev->gadget);
+
        /* start with the driver above us */
        if (dev->driver) {
                /* should have been done already by driver model core */
        if (ret)
                goto err_dev_reg;
 
+       ret = usb_add_gadget_udc(dev->dev, &dev->gadget);
+       if (ret)
+               goto err_add_udc;
+
        return 0;
 
+err_add_udc:
+       device_remove_file(dev->dev, &dev_attr_registers);
  err_dev_reg:
        device_unregister(&dev->gadget.dev);
  err_irq:
 
        return 0;
 }
 
+static int net2280_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int net2280_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops net2280_ops = {
        .get_frame      = net2280_get_frame,
        .wakeup         = net2280_wakeup,
        .set_selfpowered = net2280_set_selfpowered,
        .pullup         = net2280_pullup,
+       .start          = net2280_start,
+       .stop           = net2280_stop,
 };
 
 /*-------------------------------------------------------------------------*/
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int net2280_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct net2280          *dev = the_controller;
        dev->driver = NULL;
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
        usb_reinit (dev);
 }
 
-int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+static int net2280_stop(struct usb_gadget_driver *driver)
 {
        struct net2280  *dev = the_controller;
        unsigned long   flags;
        DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL (usb_gadget_unregister_driver);
-
 
 /*-------------------------------------------------------------------------*/
 
 {
        struct net2280          *dev = pci_get_drvdata (pdev);
 
+       usb_del_gadget_udc(&dev->gadget);
+
        BUG_ON(dev->driver);
 
        /* then clean up the resources we allocated during probe() */
        retval = device_create_file (&pdev->dev, &dev_attr_registers);
        if (retval) goto done;
 
+       retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
+       if (retval)
+               goto done;
        return 0;
 
 done:
 
        return 0;
 }
 
+static int omap_udc_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int omap_udc_stop(struct usb_gadget_driver *driver);
+
 static struct usb_gadget_ops omap_gadget_ops = {
        .get_frame              = omap_get_frame,
        .wakeup                 = omap_wakeup,
        .vbus_session           = omap_vbus_session,
        .vbus_draw              = omap_vbus_draw,
        .pullup                 = omap_pullup,
+       .start                  = omap_udc_start,
+       .stop                   = omap_udc_stop,
 };
 
 /*-------------------------------------------------------------------------*/
                );
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int omap_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        int             status = -ENODEV;
                omap_udc_enable_clock(0);
        return status;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+static int omap_udc_stop(struct usb_gadget_driver *driver)
 {
        unsigned long   flags;
        int             status = -ENODEV;
        DBG("unregistered driver '%s'\n", driver->driver.name);
        return status;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 
 /*-------------------------------------------------------------------------*/
 
 
        create_proc_file();
        status = device_add(&udc->gadget.dev);
+       if (status)
+               goto cleanup4;
+
+       status = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
        if (!status)
                return status;
        /* If fail, fall through */
+cleanup4:
+       remove_proc_file();
+
 #ifdef USE_ISO
 cleanup3:
        free_irq(pdev->resource[2].start, udc);
 
        if (!udc)
                return -ENODEV;
+
+       usb_del_gadget_udc(&udc->gadget);
        if (udc->driver)
                return -EBUSY;
 
 
        return -EOPNOTSUPP;
 }
 
+static int pch_udc_start(struct usb_gadget_driver *driver,
+       int (*bind)(struct usb_gadget *));
+static int pch_udc_stop(struct usb_gadget_driver *driver);
 static const struct usb_gadget_ops pch_udc_ops = {
        .get_frame = pch_udc_pcd_get_frame,
        .wakeup = pch_udc_pcd_wakeup,
        .pullup = pch_udc_pcd_pullup,
        .vbus_session = pch_udc_pcd_vbus_session,
        .vbus_draw = pch_udc_pcd_vbus_draw,
+       .start  = pch_udc_start,
+       .stop   = pch_udc_stop,
 };
 
 /**
        return 0;
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int pch_udc_start(struct usb_gadget_driver *driver,
        int (*bind)(struct usb_gadget *))
 {
        struct pch_udc_dev      *dev = pch_udc;
        dev->connected = 1;
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int pch_udc_stop(struct usb_gadget_driver *driver)
 {
        struct pch_udc_dev      *dev = pch_udc;
 
        pch_udc_set_disconnect(dev);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static void pch_udc_shutdown(struct pci_dev *pdev)
 {
 {
        struct pch_udc_dev      *dev = pci_get_drvdata(pdev);
 
+       usb_del_gadget_udc(&dev->gadget);
+
        /* gadget driver must not be registered */
        if (dev->driver)
                dev_err(&pdev->dev,
 
        /* Put the device in disconnected state till a driver is bound */
        pch_udc_set_disconnect(dev);
+       retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
+       if (retval)
+               goto finished;
        return 0;
 
 finished:
 
        return -EOPNOTSUPP;
 }
 
+static int pxa25x_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int pxa25x_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops pxa25x_udc_ops = {
        .get_frame      = pxa25x_udc_get_frame,
        .wakeup         = pxa25x_udc_wakeup,
        .vbus_session   = pxa25x_udc_vbus_session,
        .pullup         = pxa25x_udc_pullup,
        .vbus_draw      = pxa25x_udc_vbus_draw,
+       .start          = pxa25x_start,
+       .stop           = pxa25x_stop,
 };
 
 /*-------------------------------------------------------------------------*/
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int pxa25x_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct pxa25x_udc       *dev = the_controller;
 bind_fail:
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
        udc_reinit(dev);
 }
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int pxa25x_stop(struct usb_gadget_driver *driver)
 {
        struct pxa25x_udc       *dev = the_controller;
 
        dump_state(dev);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 
 /*-------------------------------------------------------------------------*/
 
 #endif
        create_debug_files(dev);
 
-       return 0;
+       retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
+       if (!retval)
+               return retval;
 
+       remove_debug_files(dev);
 #ifdef CONFIG_ARCH_LUBBOCK
 lubbock_fail0:
        free_irq(LUBBOCK_USB_DISC_IRQ, dev);
 {
        struct pxa25x_udc *dev = platform_get_drvdata(pdev);
 
+       usb_del_gadget_udc(&dev->gadget);
        if (dev->driver)
                return -EBUSY;
 
 
        return -EOPNOTSUPP;
 }
 
+static int pxa27x_udc_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int pxa27x_udc_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops pxa_udc_ops = {
        .get_frame      = pxa_udc_get_frame,
        .wakeup         = pxa_udc_wakeup,
        .pullup         = pxa_udc_pullup,
        .vbus_session   = pxa_udc_vbus_session,
        .vbus_draw      = pxa_udc_vbus_draw,
+       .start          = pxa27x_udc_start,
+       .stop           = pxa27x_udc_stop,
 };
 
 /**
 }
 
 /**
- * usb_gadget_probe_driver - Register gadget driver
+ * pxa27x_start - Register gadget driver
  * @driver: gadget driver
  * @bind: bind function
  *
  *
  * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int pxa27x_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct pxa_udc *udc = the_controller;
        udc->gadget.dev.driver = NULL;
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
-
 
 /**
  * stop_activity - Stops udc endpoints
 }
 
 /**
- * usb_gadget_unregister_driver - Unregister the gadget driver
+ * pxa27x_udc_stop - Unregister the gadget driver
  * @driver: gadget driver
  *
  * Returns 0 if no error, -ENODEV, -EINVAL otherwise
  */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int pxa27x_udc_stop(struct usb_gadget_driver *driver)
 {
        struct pxa_udc *udc = the_controller;
 
                return otg_set_peripheral(udc->transceiver, NULL);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /**
  * handle_ep0_ctrl_req - handle control endpoint control request
                        driver_name, IRQ_USB, retval);
                goto err_irq;
        }
+       retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
+       if (retval)
+               goto err_add_udc;
 
        pxa_init_debugfs(udc);
        return 0;
+err_add_udc:
+       free_irq(udc->irq, udc);
 err_irq:
        iounmap(udc->regs);
 err_map:
        struct pxa_udc *udc = platform_get_drvdata(_dev);
        int gpio = udc->mach->gpio_pullup;
 
+       usb_del_gadget_udc(&udc->gadget);
        usb_gadget_unregister_driver(udc->driver);
        free_irq(udc->irq, udc);
        pxa_cleanup_debugfs(udc);
 
 /*-------------------------------------------------------------------------*/
 static struct r8a66597 *the_controller;
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int r8a66597_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct r8a66597 *r8a66597 = the_controller;
 
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int r8a66597_stop(struct usb_gadget_driver *driver)
 {
        struct r8a66597 *r8a66597 = the_controller;
        unsigned long flags;
        r8a66597->driver = NULL;
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------*/
 static int r8a66597_get_frame(struct usb_gadget *_gadget)
 
 static struct usb_gadget_ops r8a66597_gadget_ops = {
        .get_frame              = r8a66597_get_frame,
+       .start                  = r8a66597_start,
+       .stop                   = r8a66597_stop,
 };
 
 static int __exit r8a66597_remove(struct platform_device *pdev)
 {
        struct r8a66597         *r8a66597 = dev_get_drvdata(&pdev->dev);
 
+       usb_del_gadget_udc(&r8a66597->gadget);
        del_timer_sync(&r8a66597->timer);
        iounmap(r8a66597->reg);
        free_irq(platform_get_irq(pdev, 0), r8a66597);
 
        init_controller(r8a66597);
 
+       ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget);
+       if (ret)
+               goto err_add_udc;
+
        dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
        return 0;
 
+err_add_udc:
+       r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
 clean_up3:
        free_irq(irq, r8a66597);
 clean_up2:
 
        return 0;
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int s3c_hsotg_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct s3c_hsotg *hsotg = our_hsotg;
        hsotg->gadget.dev.driver = NULL;
        return ret;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int s3c_hsotg_stop(struct usb_gadget_driver *driver)
 {
        struct s3c_hsotg *hsotg = our_hsotg;
        int ep;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget)
 {
 
 static struct usb_gadget_ops s3c_hsotg_gadget_ops = {
        .get_frame      = s3c_hsotg_gadget_getframe,
+       .start          = s3c_hsotg_start,
+       .stop           = s3c_hsotg_stop,
 };
 
 /**
        for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++)
                s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum);
 
+       ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
+       if (ret)
+               goto err_add_udc;
+
        s3c_hsotg_create_debug(hsotg);
 
        s3c_hsotg_dump(hsotg);
        our_hsotg = hsotg;
        return 0;
 
+err_add_udc:
+       s3c_hsotg_gate(pdev, false);
+       clk_disable(hsotg->clk);
+       clk_put(hsotg->clk);
+
 err_regs:
        iounmap(hsotg->regs);
 
 {
        struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
 
+       usb_del_gadget_udc(&hsotg->gadget);
+
        s3c_hsotg_delete_debug(hsotg);
 
        usb_gadget_unregister_driver(hsotg->driver);
 
        return IRQ_HANDLED;
 }
 
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int s3c_hsudc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct s3c_hsudc *hsudc = the_controller;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int s3c_hsudc_stop(struct usb_gadget_driver *driver)
 {
        struct s3c_hsudc *hsudc = the_controller;
        unsigned long flags;
                        driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc)
 {
 
 static struct usb_gadget_ops s3c_hsudc_gadget_ops = {
        .get_frame      = s3c_hsudc_gadget_getframe,
+       .start          = s3c_hsudc_start,
+       .stop           = s3c_hsudc_stop,
 };
 
 static int s3c_hsudc_probe(struct platform_device *pdev)
 
        disable_irq(hsudc->irq);
        local_irq_enable();
+
+       ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget);
+       if (ret)
+               goto err_add_udc;
+
        return 0;
+err_add_udc:
+       clk_disable(hsudc->uclk);
+       clk_put(hsudc->uclk);
 err_clk:
        free_irq(hsudc->irq, hsudc);
 err_irq:
 
        return -ENOTSUPP;
 }
 
+static int s3c2410_udc_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int s3c2410_udc_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops s3c2410_ops = {
        .get_frame              = s3c2410_udc_get_frame,
        .wakeup                 = s3c2410_udc_wakeup,
        .pullup                 = s3c2410_udc_pullup,
        .vbus_session           = s3c2410_udc_vbus_session,
        .vbus_draw              = s3c2410_vbus_draw,
+       .start                  = s3c2410_udc_start,
+       .stop                   = s3c2410_udc_stop,
 };
 
 static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd)
        s3c2410_udc_command(S3C2410_UDC_P_ENABLE);
 }
 
-/*
- *     usb_gadget_probe_driver
- */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int s3c2410_udc_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct s3c2410_udc *udc = the_controller;
        udc->gadget.dev.driver = NULL;
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-/*
- *     usb_gadget_unregister_driver
- */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int s3c2410_udc_stop(struct usb_gadget_driver *driver)
 {
        struct s3c2410_udc *udc = the_controller;
 
                        goto err_vbus_irq;
        }
 
+       retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
+       if (retval)
+               goto err_add_udc;
+
        if (s3c2410_udc_debugfs_root) {
                udc->regs_info = debugfs_create_file("registers", S_IRUGO,
                                s3c2410_udc_debugfs_root,
 
        return 0;
 
+err_add_udc:
+       if (udc_info && !udc_info->udc_command &&
+                       gpio_is_valid(udc_info->pullup_pin))
+               gpio_free(udc_info->pullup_pin);
 err_vbus_irq:
        if (udc_info && udc_info->vbus_pin > 0)
                free_irq(gpio_to_irq(udc_info->vbus_pin), udc);
        unsigned int irq;
 
        dev_dbg(&pdev->dev, "%s()\n", __func__);
+
+       usb_del_gadget_udc(&udc->gadget);
        if (udc->driver)
                return -EBUSY;
 
        debugfs_remove(s3c2410_udc_debugfs_root);
 }
 
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 module_init(udc_init);
 module_exit(udc_exit);
 
 
        return 0;
 }
 
+static int musb_gadget_start(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *));
+static int musb_gadget_stop(struct usb_gadget_driver *driver);
+
 static const struct usb_gadget_ops musb_gadget_operations = {
        .get_frame              = musb_gadget_get_frame,
        .wakeup                 = musb_gadget_wakeup,
        /* .vbus_session                = musb_gadget_vbus_session, */
        .vbus_draw              = musb_gadget_vbus_draw,
        .pullup                 = musb_gadget_pullup,
+       .start                  = musb_gadget_start,
+       .stop                   = musb_gadget_stop,
 };
 
 /* ----------------------------------------------------------------------- */
        if (status != 0) {
                put_device(&musb->g.dev);
                the_gadget = NULL;
+               return status;
        }
+       status = usb_add_gadget_udc(musb->controller, &musb->g);
+       if (status)
+               goto err;
+
+       return 0;
+err:
+       device_unregister(&musb->g.dev);
+       the_gadget = NULL;
        return status;
 }
 
        if (musb != the_gadget)
                return;
 
+       usb_del_gadget_udc(&musb->g);
        device_unregister(&musb->g.dev);
        the_gadget = NULL;
 }
  * @param bind the driver's bind function
  * @return <0 if error, 0 if everything is fine
  */
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int musb_gadget_start(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct musb             *musb = the_gadget;
 err0:
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
 {
  *
  * @param driver the gadget driver to unregister
  */
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int musb_gadget_stop(struct usb_gadget_driver *driver)
 {
        struct musb     *musb = the_gadget;
        unsigned long   flags;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
-
 
 /* ----------------------------------------------------------------------- */
 
 
  *
  */
 struct usbhsg_gpriv *the_controller;
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+static int usbhsg_gadget_start(struct usb_gadget_driver *driver,
                            int (*bind)(struct usb_gadget *))
 {
        struct usbhsg_gpriv *gpriv = the_controller;
 
        return ret;
 }
-EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+static int usbhsg_gadget_stop(struct usb_gadget_driver *driver)
 {
        struct usbhsg_gpriv *gpriv = the_controller;
        struct usbhs_priv *priv;
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*
  *             usb gadget ops
 
 static struct usb_gadget_ops usbhsg_gadget_ops = {
        .get_frame              = usbhsg_get_frame,
+       .start                  = usbhsg_gadget_start,
+       .stop                   = usbhsg_gadget_stop,
 };
 
 static int usbhsg_start(struct usbhs_priv *priv)
        struct device *dev = usbhs_priv_to_dev(priv);
        int pipe_size = usbhs_get_dparam(priv, pipe_size);
        int i;
+       int ret;
 
        gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL);
        if (!gpriv) {
        uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL);
        if (!uep) {
                dev_err(dev, "Could not allocate ep\n");
+               ret = -ENOMEM;
                goto usbhs_mod_gadget_probe_err_gpriv;
        }
 
 
        the_controller = gpriv;
 
+       ret = usb_add_gadget_udc(dev, &gpriv->gadget);
+       if (ret)
+               goto err_add_udc;
+
+
        dev_info(dev, "gadget probed\n");
 
        return 0;
+err_add_udc:
+       kfree(gpriv->uep);
 
 usbhs_mod_gadget_probe_err_gpriv:
        kfree(gpriv);
 
-       return -ENOMEM;
+       return ret;
 }
 
 void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
 
+       usb_del_gadget_udc(&gpriv->gadget);
        kfree(gpriv->uep);
        kfree(gpriv);
 }