diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 3e0abbb49fe134e4721037ffdbeedb242dd6e062..81656337381fa1ba8ca53eddcfe67d29483ab61e 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1574,7 +1574,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 	if (!driver
 			|| driver->speed != USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->setup) {
 		DBG("bad parameter.\n");
 		return -EINVAL;
@@ -1611,7 +1610,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
 	struct at91_udc *udc = &controller;
 
-	if (!driver || driver != udc->driver)
+	if (!driver || driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
 	local_irq_disable();
@@ -1731,10 +1730,10 @@ static int __devexit at91udc_remove(struct platform_device *pdev)
 
 	DBG("remove\n");
 
-	pullup(udc, 0);
+	if (udc->driver)
+		return -EBUSY;
 
-	if (udc->driver != 0)
-		usb_gadget_unregister_driver(udc->driver);
+	pullup(udc, 0);
 
 	device_init_wakeup(&pdev->dev, 0);
 	remove_debug_file(udc);
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index f1f32d7be5f929d022660952c18d8e11b202e4dd..3c2bc075ef4f31260ddadaa659e7ea840b2e0d1c 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -779,7 +779,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
 		return -EINVAL;
 	if (dum->driver)
 		return -EBUSY;
-	if (!driver->bind || !driver->unbind || !driver->setup
+	if (!driver->bind || !driver->setup
 			|| driver->speed == USB_SPEED_UNKNOWN)
 		return -EINVAL;
 
@@ -837,7 +837,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
 err_bind_driver:
 	driver_unregister (&driver->driver);
 err_register:
-	driver->unbind (&dum->gadget);
+	if (driver->unbind)
+		driver->unbind (&dum->gadget);
 	spin_lock_irq (&dum->lock);
 	dum->pullup = 0;
 	set_link_state (dum);
@@ -857,7 +858,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 
 	if (!dum)
 		return -ENODEV;
-	if (!driver || driver != dum->driver)
+	if (!driver || driver != dum->driver || !driver->unbind)
 		return -EINVAL;
 
 	dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index a265e262a2eefd4239513613962a54d6bbee64d3..72f2ae96fbf342de37eb1687bc38dab8378fd08c 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4100,7 +4100,7 @@ static struct usb_gadget_driver		fsg_driver = {
 #endif
 	.function	= (char *) longname,
 	.bind		= fsg_bind,
-	.unbind		= __exit_p(fsg_unbind),
+	.unbind		= fsg_unbind,
 	.disconnect	= fsg_disconnect,
 	.setup		= fsg_setup,
 	.suspend	= fsg_suspend,
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 31351826f2baddc7c18d17276016745f3d5c2491..f1a679656c967f6cb4cfb40040f97410fb71a33a 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -123,7 +123,7 @@ struct gmidi_device {
 	struct usb_request	*req;		/* for control responses */
 	u8			config;
 	struct usb_ep		*in_ep, *out_ep;
-	struct snd_card 	*card;
+	struct snd_card		*card;
 	struct snd_rawmidi	*rmidi;
 	struct snd_rawmidi_substream *in_substream;
 	struct snd_rawmidi_substream *out_substream;
@@ -490,7 +490,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req)
 	int status = req->status;
 
 	switch (status) {
-	case 0: 			/* normal completion */
+	case 0:				/* normal completion */
 		if (ep == dev->out_ep) {
 			/* we received stuff.
 			   req is queued again, below */
@@ -505,7 +505,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req)
 		break;
 
 	/* this endpoint is normally active while we're configured */
-	case -ECONNABORTED: 		/* hardware forced ep reset */
+	case -ECONNABORTED:		/* hardware forced ep reset */
 	case -ECONNRESET:		/* request dequeued */
 	case -ESHUTDOWN:		/* disconnect from host */
 		VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
@@ -656,7 +656,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags)
 		case USB_SPEED_LOW:	speed = "low"; break;
 		case USB_SPEED_FULL:	speed = "full"; break;
 		case USB_SPEED_HIGH:	speed = "high"; break;
-		default: 		speed = "?"; break;
+		default:		speed = "?"; break;
 		}
 
 		dev->config = number;
@@ -1308,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = {
 	.speed		= USB_SPEED_FULL,
 	.function	= (char *)longname,
 	.bind		= gmidi_bind,
-	.unbind		= __exit_p(gmidi_unbind),
+	.unbind		= gmidi_unbind,
 
 	.setup		= gmidi_setup,
 	.disconnect	= gmidi_disconnect,
@@ -1316,7 +1316,7 @@ static struct usb_gadget_driver gmidi_driver = {
 	.suspend	= gmidi_suspend,
 	.resume		= gmidi_resume,
 
-	.driver 	= {
+	.driver		= {
 		.name		= (char *)shortname,
 		.owner		= THIS_MODULE,
 	},
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 805a9826842d51a1c9a05443d4208fa62e477cb1..d0ef1d6b3fac0c046bfdce5a8f9e878022c15aa3 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1432,7 +1432,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	if (!driver
 			|| driver->speed != USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->disconnect
 			|| !driver->setup)
 		return -EINVAL;
@@ -1495,7 +1494,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->lock, flags);
@@ -1808,13 +1807,8 @@ static void goku_remove(struct pci_dev *pdev)
 	struct goku_udc		*dev = pci_get_drvdata(pdev);
 
 	DBG(dev, "%s\n", __FUNCTION__);
-	/* start with the driver above us */
-	if (dev->driver) {
-		/* should have been done already by driver model core */
-		WARN(dev, "pci remove, driver '%s' is still registered\n",
-				dev->driver->driver.name);
-		usb_gadget_unregister_driver(dev->driver);
-	}
+
+	BUG_ON(dev->driver);
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
 	remove_proc_entry(proc_node_name, NULL);
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 4a991564a03ee5758515f99e01683a64116ddeeb..a0a73c08a34467730f007ed6bcf27bf4d8e7ae78 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -422,9 +422,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name);
 
 	if (!driver
-	    || driver->speed != USB_SPEED_FULL
-	    || !driver->bind
-	    || !driver->unbind || !driver->disconnect || !driver->setup)
+			|| driver->speed != USB_SPEED_FULL
+			|| !driver->bind
+			|| !driver->disconnect
+			|| !driver->setup)
 		return -EINVAL;
 	if (!dev)
 		return -ENODEV;
@@ -471,7 +472,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->lock, flags);
@@ -2125,9 +2126,11 @@ static int lh7a40x_udc_remove(struct platform_device *pdev)
 
 	DEBUG("%s: %p\n", __FUNCTION__, pdev);
 
+	if (dev->driver)
+		return -EBUSY;
+
 	udc_disable(dev);
 	remove_proc_files();
-	usb_gadget_unregister_driver(dev->driver);
 
 	free_irq(IRQ_USBINTR, dev);
 
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 3024c679e38e9fcec4e5ada07f8bc00bd799f045..569eb8ccf232bd2bdfe1fcff82d609f9e356d496 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2020,7 +2020,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 	if (!driver
 			|| driver->speed != USB_SPEED_HIGH
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->setup)
 		return -EINVAL;
 	if (!dev)
@@ -2107,7 +2106,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	spin_lock_irqsave (&dev->lock, flags);
@@ -2803,13 +2802,7 @@ static void net2280_remove (struct pci_dev *pdev)
 {
 	struct net2280		*dev = pci_get_drvdata (pdev);
 
-	/* start with the driver above us */
-	if (dev->driver) {
-		/* should have been done already by driver model core */
-		WARN (dev, "pci remove, driver '%s' is still registered\n",
-				dev->driver->driver.name);
-		usb_gadget_unregister_driver (dev->driver);
-	}
+	BUG_ON(dev->driver);
 
 	/* then clean up the resources we allocated during probe() */
 	net2280_led_shutdown (dev);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 030d87c28c2f614f4874c6c1867638fe410b5e87..15d77c30793093e18014c9fafd63daa6376e0095 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2043,7 +2043,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 			// FIXME if otg, check:  driver->is_otg
 			|| driver->speed < USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->setup)
 		return -EINVAL;
 
@@ -2087,9 +2086,11 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 		status = otg_set_peripheral(udc->transceiver, &udc->gadget);
 		if (status < 0) {
 			ERR("can't bind to transceiver\n");
-			driver->unbind (&udc->gadget);
-			udc->gadget.dev.driver = NULL;
-			udc->driver = NULL;
+			if (driver->unbind) {
+				driver->unbind (&udc->gadget);
+				udc->gadget.dev.driver = NULL;
+				udc->driver = NULL;
+			}
 			goto done;
 		}
 	} else {
@@ -2117,7 +2118,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 
 	if (!udc)
 		return -ENODEV;
-	if (!driver || driver != udc->driver)
+	if (!driver || driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
 	if (machine_is_omap_innovator() || machine_is_omap_osk())
@@ -2870,6 +2871,8 @@ static int __exit omap_udc_remove(struct platform_device *pdev)
 
 	if (!udc)
 		return -ENODEV;
+	if (udc->driver)
+		return -EBUSY;
 
 	udc->done = &done;
 
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 1ed506e959853f67c879b58a267787d60dfafb3e..b78de96946652128f326aae340bcdb991cd39d82 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -1623,7 +1623,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	if (!driver
 			|| driver->speed < USB_SPEED_FULL
 			|| !driver->bind
-			|| !driver->unbind
 			|| !driver->disconnect
 			|| !driver->setup)
 		return -EINVAL;
@@ -1694,7 +1693,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 	if (!dev)
 		return -ENODEV;
-	if (!driver || driver != dev->driver)
+	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
 	local_irq_disable();
@@ -2638,9 +2637,11 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
 {
 	struct pxa2xx_udc *dev = platform_get_drvdata(pdev);
 
+	if (dev->driver)
+		return -EBUSY;
+
 	udc_disable(dev);
 	remove_proc_files();
-	usb_gadget_unregister_driver(dev->driver);
 
 	if (dev->got_irq) {
 		free_irq(IRQ_USB, dev);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 2d12bf9f19d64efecc95b991c94697dc921f7295..f8a3ec64635d503279f0d18d9ec97f8743665ca9 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -296,7 +296,7 @@ static struct usb_gadget_driver gs_gadget_driver = {
 #endif /* CONFIG_USB_GADGET_DUALSPEED */
 	.function =		GS_LONG_NAME,
 	.bind =			gs_bind,
-	.unbind =		__exit_p(gs_unbind),
+	.unbind =		gs_unbind,
 	.setup =		gs_setup,
 	.disconnect =		gs_disconnect,
 	.driver = {