[PATCH] USB: gadget driver section fixups

This adds __init section annotations to gadget driver bind() routines to
remove calls from .text into .init sections (for endpoint autoconfig).
Likewise it adds __exit section annotations to their unbind() routines.

The specification of the gadget driver register/unregister functions is
updated to explicitly allow use of those sections.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 3d2603e..0d9d9bb 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2125,7 +2125,7 @@
 }
 
 
-static void
+static void __exit
 eth_unbind (struct usb_gadget *gadget)
 {
 	struct eth_dev		*dev = get_gadget_data (gadget);
@@ -2532,7 +2532,7 @@
 
 	.function	= (char *) driver_desc,
 	.bind		= eth_bind,
-	.unbind		= eth_unbind,
+	.unbind		= __exit_p(eth_unbind),
 
 	.setup		= eth_setup,
 	.disconnect	= eth_disconnect,
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index de59c58..cf3be29 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3678,7 +3678,7 @@
 	kref_put(&fsg->ref, fsg_release);
 }
 
-static void fsg_unbind(struct usb_gadget *gadget)
+static void __exit fsg_unbind(struct usb_gadget *gadget)
 {
 	struct fsg_dev		*fsg = get_gadget_data(gadget);
 	int			i;
@@ -4064,7 +4064,7 @@
 #endif
 	.function	= (char *) longname,
 	.bind		= fsg_bind,
-	.unbind		= fsg_unbind,
+	.unbind		= __exit_p(fsg_unbind),
 	.disconnect	= fsg_disconnect,
 	.setup		= fsg_setup,
 	.suspend	= fsg_suspend,
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index ba9acd5..548feaa 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -369,7 +369,7 @@
 #endif /* CONFIG_USB_GADGET_DUALSPEED */
 	.function =		GS_LONG_NAME,
 	.bind =			gs_bind,
-	.unbind =		gs_unbind,
+	.unbind =		__exit_p(gs_unbind),
 	.setup =		gs_setup,
 	.disconnect =		gs_disconnect,
 	.driver = {
@@ -1413,7 +1413,7 @@
  * Called on module load.  Allocates and initializes the device
  * structure and a control request.
  */
-static int gs_bind(struct usb_gadget *gadget)
+static int __init gs_bind(struct usb_gadget *gadget)
 {
 	int ret;
 	struct usb_ep *ep;
@@ -1538,7 +1538,7 @@
  * Called on module unload.  Frees the control request and device
  * structure.
  */
-static void gs_unbind(struct usb_gadget *gadget)
+static void __exit gs_unbind(struct usb_gadget *gadget)
 {
 	struct gs_dev *dev = get_gadget_data(gadget);
 
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 5e9fe8a..44d8e5e 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1119,7 +1119,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void
+static void __exit
 zero_unbind (struct usb_gadget *gadget)
 {
 	struct zero_dev		*dev = get_gadget_data (gadget);
@@ -1136,7 +1136,7 @@
 	set_gadget_data (gadget, NULL);
 }
 
-static int
+static int __init
 zero_bind (struct usb_gadget *gadget)
 {
 	struct zero_dev		*dev;
@@ -1288,7 +1288,7 @@
 #endif
 	.function	= (char *) longname,
 	.bind		= zero_bind,
-	.unbind		= zero_unbind,
+	.unbind		= __exit_p(zero_unbind),
 
 	.setup		= zero_setup,
 	.disconnect	= zero_disconnect,
diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h
index ff81117..1d78870 100644
--- a/include/linux/usb_gadget.h
+++ b/include/linux/usb_gadget.h
@@ -801,7 +801,9 @@
  * Call this in your gadget driver's module initialization function,
  * to tell the underlying usb controller driver about your driver.
  * The driver's bind() function will be called to bind it to a
- * gadget.  This function must be called in a context that can sleep.
+ * gadget before this registration call returns.  It's expected that
+ * the bind() functions will be in init sections.
+ * This function must be called in a context that can sleep.
  */
 int usb_gadget_register_driver (struct usb_gadget_driver *driver);
 
@@ -814,7 +816,8 @@
  * going away.  If the controller is connected to a USB host,
  * it will first disconnect().  The driver is also requested
  * to unbind() and clean up any device state, before this procedure
- * finally returns.
+ * finally returns.  It's expected that the unbind() functions
+ * will in in exit sections, so may not be linked in some kernels.
  * This function must be called in a context that can sleep.
  */
 int usb_gadget_unregister_driver (struct usb_gadget_driver *driver);