usb: gadget: android: Update android gadget driver

* Functions and the device descriptor are configured from user space:
echo 0       > /sys/class/android_usb/android0/enable
echo adb,acm > /sys/class/android_usb/android0/functions
echo 2       > /sys/class/android_usb/android0/f_acm/instances
echo 1       > /sys/class/android_usb/android0/enable

* Driver does not require platform data anymore

* Moved function initialization to android.c instead of each
function file

* Replaced switches by uevents

Signed-off-by: Benoit Goby <benoit@android.com>
Signed-off-by: Mike Lockwood <lockwood@android.com>
Change-Id: If5ad9267c111ad0a442f0d87a0d31082dc5381b6
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 5b3c58e..144a8c8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -935,7 +935,7 @@
 	  For more information, see Documentation/usb/gadget_printer.txt
 	  which includes sample code for accessing the device file.
 
-config USB_ANDROID
+config USB_G_ANDROID
 	boolean "Android Gadget"
 	depends on SWITCH
 	help
@@ -943,53 +943,6 @@
 	  The functions can be configured via a board file and may be
 	  enabled and disabled dynamically.
 
-config USB_ANDROID_ACM
-	boolean "Android gadget ACM serial function"
-	depends on USB_ANDROID
-	help
-	  Provides ACM serial function for android gadget driver.
-
-config USB_ANDROID_ADB
-	boolean "Android gadget adb function"
-	depends on USB_ANDROID
-	help
-	  Provides adb function for android gadget driver.
-
-config USB_ANDROID_MASS_STORAGE
-	boolean "Android gadget mass storage function"
-	depends on USB_ANDROID && SWITCH
-	help
-	  Provides USB mass storage function for android gadget driver.
-
-config USB_ANDROID_MTP
-	boolean "Android MTP function"
-	depends on USB_ANDROID
-	help
-	  Provides Media Transfer Protocol (MTP) support for android gadget driver.
-
-config USB_ANDROID_RNDIS
-	boolean "Android gadget RNDIS ethernet function"
-	depends on USB_ANDROID
-	help
-	  Provides RNDIS ethernet function for android gadget driver.
-
-config USB_ANDROID_RNDIS_WCEIS
-        boolean "Use Windows Internet Sharing Class/SubClass/Protocol"
-        depends on USB_ANDROID_RNDIS
-        help
-         Causes the driver to look like a Windows-compatible Internet
-         Sharing device, so Windows auto-detects it.
-
-         If you enable this option, the device is no longer CDC ethernet
-         compatible.
-
-
-config USB_ANDROID_ACCESSORY
-	boolean "Android USB accessory function"
-	depends on USB_ANDROID
-	help
-	  Provides Android USB Accessory support for android gadget driver.
-
 config USB_CDC_COMPOSITE
 	tristate "CDC Composite Device (Ethernet and ACM)"
 	depends on NET
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index e9066b9..ab17a4c 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -49,6 +49,7 @@
 g_nokia-y			:= nokia.o
 g_webcam-y			:= webcam.o
 g_ncm-y				:= ncm.o
+g_android-y			:= android.o
 
 obj-$(CONFIG_USB_ZERO)		+= g_zero.o
 obj-$(CONFIG_USB_AUDIO)		+= g_audio.o
@@ -67,10 +68,4 @@
 obj-$(CONFIG_USB_G_NOKIA)	+= g_nokia.o
 obj-$(CONFIG_USB_G_WEBCAM)	+= g_webcam.o
 obj-$(CONFIG_USB_G_NCM)		+= g_ncm.o
-obj-$(CONFIG_USB_ANDROID)	+= android.o
-obj-$(CONFIG_USB_ANDROID_ACM)	+= f_acm.o u_serial.o
-obj-$(CONFIG_USB_ANDROID_ADB)	+= f_adb.o
-obj-$(CONFIG_USB_ANDROID_MASS_STORAGE)	+= f_mass_storage.o
-obj-$(CONFIG_USB_ANDROID_MTP)	+= f_mtp.o
-obj-$(CONFIG_USB_ANDROID_RNDIS)	+= f_rndis.o u_ether.o
-obj-$(CONFIG_USB_ANDROID_ACCESSORY)	+= f_accessory.o
+obj-$(CONFIG_USB_G_ANDROID)	+= g_android.o
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 2ebc818..377df5b 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -27,7 +27,6 @@
 #include <linux/utsname.h>
 #include <linux/platform_device.h>
 
-#include <linux/usb/android_composite.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/composite.h>
 #include <linux/usb/gadget.h>
@@ -46,6 +45,17 @@
 #include "epautoconf.c"
 #include "composite.c"
 
+#include "f_mass_storage.c"
+#include "u_serial.c"
+#include "f_acm.c"
+#include "f_adb.c"
+#include "f_mtp.c"
+#include "f_accessory.c"
+#define USB_ETH_RNDIS y
+#include "f_rndis.c"
+#include "rndis.c"
+#include "u_ether.c"
+
 MODULE_AUTHOR("Mike Lockwood");
 MODULE_DESCRIPTION("Android Composite USB Driver");
 MODULE_LICENSE("GPL");
@@ -53,37 +63,68 @@
 
 static const char longname[] = "Gadget Android";
 
-/* Default vendor and product IDs, overridden by platform data */
+/* Default vendor and product IDs, overridden by userspace */
 #define VENDOR_ID		0x18D1
 #define PRODUCT_ID		0x0001
 
-struct android_dev {
-	struct usb_composite_dev *cdev;
-	struct usb_configuration *config;
-	int num_products;
-	struct android_usb_product *products;
-	int num_functions;
-	char **functions;
+struct android_usb_function {
+	char *name;
+	void *config;
 
-	int vendor_id;
-	int product_id;
-	int version;
+	struct device *dev;
+	char *dev_name;
+	struct device_attribute **attributes;
+
+	/* for android_dev.enabled_functions */
+	struct list_head enabled_list;
+
+	/* Optional: initialization during gadget bind */
+	int (*init)(struct android_usb_function *, struct usb_composite_dev *);
+	/* Optional: cleanup during gadget unbind */
+	void (*cleanup)(struct android_usb_function *);
+
+	int (*bind_config)(struct android_usb_function *, struct usb_configuration *);
+
+	/* Optional: called when the configuration is removed */
+	void (*unbind_config)(struct android_usb_function *, struct usb_configuration *);
+	/* Optional: handle ctrl requests before the device is configured
+	 *	and/or before the function is enabled */
+	int (*ctrlrequest)(struct android_usb_function *,
+					struct usb_composite_dev *,
+					const struct usb_ctrlrequest *);
 };
 
+struct android_dev {
+	struct android_usb_function **functions;
+	struct list_head enabled_functions;
+	struct usb_composite_dev *cdev;
+	struct device *dev;
+
+	bool enabled;
+	bool connected;
+	bool sw_connected;
+	struct work_struct work;
+};
+
+static struct class *android_class;
 static struct android_dev *_android_dev;
+static int android_bind_config(struct usb_configuration *c);
+static void android_unbind_config(struct usb_configuration *c);
 
 /* string IDs are assigned dynamically */
-
 #define STRING_MANUFACTURER_IDX		0
 #define STRING_PRODUCT_IDX		1
 #define STRING_SERIAL_IDX		2
 
+static char manufacturer_string[256];
+static char product_string[256];
+static char serial_string[256];
+
 /* String Table */
 static struct usb_string strings_dev[] = {
-	/* These dummy values should be overridden by platform data */
-	[STRING_MANUFACTURER_IDX].s = "Android",
-	[STRING_PRODUCT_IDX].s = "Android",
-	[STRING_SERIAL_IDX].s = "0123456789ABCDEF",
+	[STRING_MANUFACTURER_IDX].s = manufacturer_string,
+	[STRING_PRODUCT_IDX].s = product_string,
+	[STRING_SERIAL_IDX].s = serial_string,
 	{  }			/* end of list */
 };
 
@@ -108,183 +149,788 @@
 	.bNumConfigurations   = 1,
 };
 
-static struct list_head _functions = LIST_HEAD_INIT(_functions);
-static bool _are_functions_bound;
-
-static struct android_usb_function *get_function(const char *name)
-{
-	struct android_usb_function	*f;
-	list_for_each_entry(f, &_functions, list) {
-		if (!strcmp(name, f->name))
-			return f;
-	}
-	return 0;
-}
-
-static bool are_functions_registered(struct android_dev *dev)
-{
-	char **functions = dev->functions;
-	int i;
-
-	/* Look only for functions required by the board config */
-	for (i = 0; i < dev->num_functions; i++) {
-		char *name = *functions++;
-		bool is_match = false;
-		/* Could reuse get_function() here, but a reverse search
-		 * should yield less comparisons overall */
-		struct android_usb_function *f;
-		list_for_each_entry_reverse(f, &_functions, list) {
-			if (!strcmp(name, f->name)) {
-				is_match = true;
-				break;
-			}
-		}
-		if (is_match)
-			continue;
-		else
-			return false;
-	}
-
-	return true;
-}
-
-static bool should_bind_functions(struct android_dev *dev)
-{
-	/* Don't waste time if the main driver hasn't bound */
-	if (!dev->config)
-		return false;
-
-	/* Don't waste time if we've already bound the functions */
-	if (_are_functions_bound)
-		return false;
-
-	/* This call is the most costly, so call it last */
-	if (!are_functions_registered(dev))
-		return false;
-
-	return true;
-}
-
-static void bind_functions(struct android_dev *dev)
-{
-	struct android_usb_function	*f;
-	char **functions = dev->functions;
-	int i;
-
-	for (i = 0; i < dev->num_functions; i++) {
-		char *name = *functions++;
-		f = get_function(name);
-		if (f)
-			f->bind_config(dev->config);
-		else
-			printk(KERN_ERR "function %s not found in bind_functions\n", name);
-	}
-
-	_are_functions_bound = true;
-}
-
-static int android_bind_config(struct usb_configuration *c)
-{
-	struct android_dev *dev = _android_dev;
-
-	printk(KERN_DEBUG "android_bind_config\n");
-	dev->config = c;
-
-	if (should_bind_functions(dev))
-		bind_functions(dev);
-
-	return 0;
-}
-
-static int android_setup_config(struct usb_configuration *c,
-		const struct usb_ctrlrequest *ctrl);
-
 static struct usb_configuration android_config_driver = {
 	.label		= "android",
-	.setup		= android_setup_config,
+	.unbind		= android_unbind_config,
 	.bConfigurationValue = 1,
 	.bmAttributes	= USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
 	.bMaxPower	= 0xFA, /* 500ma */
 };
 
-static int android_setup_config(struct usb_configuration *c,
-		const struct usb_ctrlrequest *ctrl)
+static void android_work(struct work_struct *data)
+{
+	struct android_dev *dev = container_of(data, struct android_dev, work);
+	struct usb_composite_dev *cdev = dev->cdev;
+	char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
+	char *connected[2]    = { "USB_STATE=CONNECTED", NULL };
+	char *configured[2]   = { "USB_STATE=CONFIGURED", NULL };
+	unsigned long flags;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+        if (cdev->config) {
+		spin_unlock_irqrestore(&cdev->lock, flags);
+		kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
+							configured);
+		return;
+	}
+	if (dev->connected != dev->sw_connected) {
+		dev->sw_connected = dev->connected;
+		spin_unlock_irqrestore(&cdev->lock, flags);
+		kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE,
+				dev->sw_connected ? connected : disconnected);
+	} else {
+		spin_unlock_irqrestore(&cdev->lock, flags);
+	}
+}
+
+
+/*-------------------------------------------------------------------------*/
+/* Supported functions initialization */
+
+static int adb_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
+{
+	return adb_setup();
+}
+
+static void adb_function_cleanup(struct android_usb_function *f)
+{
+	adb_cleanup();
+}
+
+static int adb_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
+{
+	return adb_bind_config(c);
+}
+
+static struct android_usb_function adb_function = {
+	.name		= "adb",
+	.init		= adb_function_init,
+	.cleanup	= adb_function_cleanup,
+	.bind_config	= adb_function_bind_config,
+};
+
+
+#define MAX_ACM_INSTANCES 4
+struct acm_function_config {
+	int instances;
+};
+
+static int acm_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
+{
+	f->config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL);
+	if (!f->config)
+		return -ENOMEM;
+
+	return gserial_setup(cdev->gadget, MAX_ACM_INSTANCES);
+}
+
+static void acm_function_cleanup(struct android_usb_function *f)
+{
+	gserial_cleanup();
+	kfree(f->config);
+	f->config = NULL;
+}
+
+static int acm_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
 {
 	int i;
-	int ret = -EOPNOTSUPP;
+	int ret = 0;
+	struct acm_function_config *config = f->config;
 
-	for (i = 0; i < android_config_driver.next_interface_id; i++) {
-		if (android_config_driver.interface[i]->setup) {
-			ret = android_config_driver.interface[i]->setup(
-				android_config_driver.interface[i], ctrl);
-			if (ret >= 0)
-				return ret;
+	for (i = 0; i < config->instances; i++) {
+		ret = acm_bind_config(c, i);
+		if (ret) {
+			pr_err("Could not bind acm%u config\n", i);
+			break;
 		}
 	}
+
 	return ret;
 }
 
-static int product_has_function(struct android_usb_product *p,
-		struct usb_function *f)
+static ssize_t acm_instances_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
 {
-	char **functions = p->functions;
-	int count = p->num_functions;
-	const char *name = f->name;
-	int i;
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct acm_function_config *config = f->config;
+	return sprintf(buf, "%d\n", config->instances);
+}
 
-	for (i = 0; i < count; i++) {
-		/* For functions with multiple instances, usb_function.name
-		 * will have an index appended to the core name (ex: acm0),
-		 * while android_usb_product.functions[i] will only have the
-		 * core name (ex: acm). So, only compare up to the length of
-		 * android_usb_product.functions[i].
-		 */
-		if (!strncmp(name, functions[i], strlen(functions[i])))
-			return 1;
+static ssize_t acm_instances_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct acm_function_config *config = f->config;
+	int value;
+
+	sscanf(buf, "%d", &value);
+	if (value > MAX_ACM_INSTANCES)
+		value = MAX_ACM_INSTANCES;
+	config->instances = value;
+	return size;
+}
+
+static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show, acm_instances_store);
+static struct device_attribute *acm_function_attributes[] = { &dev_attr_instances, NULL };
+
+static struct android_usb_function acm_function = {
+	.name		= "acm",
+	.init		= acm_function_init,
+	.cleanup	= acm_function_cleanup,
+	.bind_config	= acm_function_bind_config,
+	.attributes	= acm_function_attributes,
+};
+
+
+static int mtp_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
+{
+	return mtp_setup();
+}
+
+static void mtp_function_cleanup(struct android_usb_function *f)
+{
+	mtp_cleanup();
+}
+
+static int mtp_function_bind_config(struct android_usb_function *f, struct usb_configuration *c)
+{
+	return mtp_bind_config(c);
+}
+
+static int mtp_function_ctrlrequest(struct android_usb_function *f,
+						struct usb_composite_dev *cdev,
+						const struct usb_ctrlrequest *c)
+{
+	return mtp_ctrlrequest(cdev, c);
+}
+
+static struct android_usb_function mtp_function = {
+	.name		= "mtp",
+	.init		= mtp_function_init,
+	.cleanup	= mtp_function_cleanup,
+	.bind_config	= mtp_function_bind_config,
+	.ctrlrequest	= mtp_function_ctrlrequest,
+};
+
+
+struct rndis_function_config {
+	u8      ethaddr[ETH_ALEN];
+	u32     vendorID;
+	char	manufacturer[256];
+	bool	wceis;
+};
+
+static int rndis_function_init(struct android_usb_function *f, struct usb_composite_dev *cdev)
+{
+	f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
+	if (!f->config)
+		return -ENOMEM;
+	return 0;
+}
+
+static void rndis_function_cleanup(struct android_usb_function *f)
+{
+	kfree(f->config);
+	f->config = NULL;
+}
+
+static int rndis_function_bind_config(struct android_usb_function *f,
+					struct usb_configuration *c)
+{
+	int ret;
+	struct rndis_function_config *rndis = f->config;
+
+	if (!rndis) {
+		pr_err("%s: rndis_pdata\n", __func__);
+		return -1;
+	}
+
+	pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
+		rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
+		rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
+
+	ret = gether_setup(c->cdev->gadget, rndis->ethaddr);
+	if (ret) {
+		pr_err("%s: gether_setup failed\n", __func__);
+		return ret;
+	}
+
+	if (rndis->wceis) {
+		/* "Wireless" RNDIS; auto-detected by Windows */
+		rndis_iad_descriptor.bFunctionClass =
+						USB_CLASS_WIRELESS_CONTROLLER;
+		rndis_iad_descriptor.bFunctionSubClass = 0x01;
+		rndis_iad_descriptor.bFunctionProtocol = 0x03;
+		rndis_control_intf.bInterfaceClass =
+						USB_CLASS_WIRELESS_CONTROLLER;
+		rndis_control_intf.bInterfaceSubClass =	 0x01;
+		rndis_control_intf.bInterfaceProtocol =	 0x03;
+	}
+
+	return rndis_bind_config(c, rndis->ethaddr, rndis->vendorID,
+				    rndis->manufacturer);
+}
+
+static void rndis_function_unbind_config(struct android_usb_function *f,
+						struct usb_configuration *c)
+{
+	gether_cleanup();
+}
+
+static ssize_t rndis_manufacturer_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	return sprintf(buf, "%s\n", config->manufacturer);
+}
+
+static ssize_t rndis_manufacturer_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+
+	if (size >= sizeof(config->manufacturer))
+		return -EINVAL;
+	if (sscanf(buf, "%s", config->manufacturer) == 1)
+		return size;
+	return -1;
+}
+
+static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
+						    rndis_manufacturer_store);
+
+static ssize_t rndis_wceis_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	return sprintf(buf, "%d\n", config->wceis);
+}
+
+static ssize_t rndis_wceis_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	int value;
+
+	if (sscanf(buf, "%d", &value) == 1) {
+		config->wceis = value;
+		return size;
+	}
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
+					     rndis_wceis_store);
+
+static ssize_t rndis_ethaddr_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *rndis = f->config;
+	return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+		rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
+		rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
+}
+
+static ssize_t rndis_ethaddr_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *rndis = f->config;
+
+	if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+		    (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
+		    (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
+		    (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
+		return size;
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
+					       rndis_ethaddr_store);
+
+static ssize_t rndis_vendorID_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	return sprintf(buf, "%04x\n", config->vendorID);
+}
+
+static ssize_t rndis_vendorID_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	int value;
+
+	if (sscanf(buf, "%04x", &value) == 1) {
+		config->vendorID = value;
+		return size;
+	}
+	return -EINVAL;
+}
+
+static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
+						rndis_vendorID_store);
+
+static struct device_attribute *rndis_function_attributes[] = {
+	&dev_attr_manufacturer,
+	&dev_attr_wceis,
+	&dev_attr_ethaddr,
+	&dev_attr_vendorID,
+	NULL
+};
+
+static struct android_usb_function rndis_function = {
+	.name		= "rndis",
+	.init		= rndis_function_init,
+	.cleanup	= rndis_function_cleanup,
+	.bind_config	= rndis_function_bind_config,
+	.unbind_config	= rndis_function_unbind_config,
+	.attributes	= rndis_function_attributes,
+};
+
+
+struct mass_storage_function_config {
+	struct fsg_config fsg;
+	struct fsg_common *common;
+};
+
+static int mass_storage_function_init(struct android_usb_function *f,
+					struct usb_composite_dev *cdev)
+{
+	struct mass_storage_function_config *config;
+	struct fsg_common *common;
+	int err;
+
+	config = kzalloc(sizeof(struct mass_storage_function_config),
+								GFP_KERNEL);
+	if (!config)
+		return -ENOMEM;
+
+	config->fsg.nluns = 1;
+	config->fsg.luns[0].removable = 1;
+
+	common = fsg_common_init(NULL, cdev, &config->fsg);
+	if (IS_ERR(common)) {
+		kfree(config);
+		return PTR_ERR(common);
+	}
+
+	err = sysfs_create_link(&f->dev->kobj,
+				&common->luns[0].dev.kobj,
+				"lun");
+	if (err) {
+		kfree(config);
+		return err;
+	}
+
+	config->common = common;
+	f->config = config;
+	return 0;
+}
+
+static void mass_storage_function_cleanup(struct android_usb_function *f)
+{
+	kfree(f->config);
+	f->config = NULL;
+}
+
+static int mass_storage_function_bind_config(struct android_usb_function *f,
+						struct usb_configuration *c)
+{
+	struct mass_storage_function_config *config = f->config;
+	return fsg_bind_config(c->cdev, c, config->common);
+}
+
+static ssize_t mass_storage_inquiry_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct mass_storage_function_config *config = f->config;
+	return sprintf(buf, "%s\n", config->common->inquiry_string);
+}
+
+static ssize_t mass_storage_inquiry_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct android_usb_function *f = dev_get_drvdata(dev);
+	struct mass_storage_function_config *config = f->config;
+	if (size >= sizeof(config->common->inquiry_string))
+		return -EINVAL;
+	if (sscanf(buf, "%s", config->common->inquiry_string) != 1)
+		return -EINVAL;
+	return size;
+}
+
+static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
+					mass_storage_inquiry_show,
+					mass_storage_inquiry_store);
+
+static struct device_attribute *mass_storage_function_attributes[] = {
+	&dev_attr_inquiry_string,
+	NULL
+};
+
+static struct android_usb_function mass_storage_function = {
+	.name		= "mass_storage",
+	.init		= mass_storage_function_init,
+	.cleanup	= mass_storage_function_cleanup,
+	.bind_config	= mass_storage_function_bind_config,
+	.attributes	= mass_storage_function_attributes,
+};
+
+
+static int accessory_function_init(struct android_usb_function *f,
+					struct usb_composite_dev *cdev)
+{
+	return acc_setup();
+}
+
+static void accessory_function_cleanup(struct android_usb_function *f)
+{
+	acc_cleanup();
+}
+
+static int accessory_function_bind_config(struct android_usb_function *f,
+						struct usb_configuration *c)
+{
+	return acc_bind_config(c);
+}
+
+static int accessory_function_ctrlrequest(struct android_usb_function *f,
+						struct usb_composite_dev *cdev,
+						const struct usb_ctrlrequest *c)
+{
+	return acc_ctrlrequest(cdev, c);
+}
+
+static struct android_usb_function accessory_function = {
+	.name		= "accessory",
+	.init		= accessory_function_init,
+	.cleanup	= accessory_function_cleanup,
+	.bind_config	= accessory_function_bind_config,
+	.ctrlrequest	= accessory_function_ctrlrequest,
+};
+
+
+static struct android_usb_function *supported_functions[] = {
+	&adb_function,
+	&acm_function,
+	&mtp_function,
+	&rndis_function,
+	&mass_storage_function,
+	&accessory_function,
+	NULL
+};
+
+
+static int android_init_functions(struct android_usb_function **functions,
+				  struct usb_composite_dev *cdev)
+{
+	struct android_dev *dev = _android_dev;
+	struct android_usb_function *f;
+	struct device_attribute **attrs;
+	struct device_attribute *attr;
+	int err;
+	int index = 0;
+
+	for (; (f = *functions++); index++) {
+		f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
+		f->dev = device_create(android_class, dev->dev,
+				MKDEV(0, index), f, f->dev_name);
+		if (IS_ERR(f->dev)) {
+			pr_err("%s: Failed to create dev %s", __func__,
+							f->dev_name);
+			err = PTR_ERR(f->dev);
+			goto err_create;
+		}
+
+		if (f->init) {
+			err = f->init(f, cdev);
+			if (err) {
+				pr_err("%s: Failed to init %s", __func__,
+								f->name);
+				goto err_out;
+			}
+		}
+
+		attrs = f->attributes;
+		if (attrs) {
+			while ((attr = *attrs++) && !err)
+				err = device_create_file(f->dev, attr);
+		}
+		if (err) {
+			pr_err("%s: Failed to create function %s attributes",
+					__func__, f->name);
+			goto err_out;
+		}
+	}
+	return 0;
+
+err_out:
+	device_destroy(android_class, f->dev->devt);
+err_create:
+	kfree(f->dev_name);
+	return err;
+}
+
+static void android_cleanup_functions(struct android_usb_function **functions)
+{
+	struct android_usb_function *f;
+
+	while (*functions) {
+		f = *functions++;
+
+		if (f->dev) {
+			device_destroy(android_class, f->dev->devt);
+			kfree(f->dev_name);
+		}
+
+		if (f->cleanup)
+			f->cleanup(f);
+	}
+}
+
+static int
+android_bind_enabled_functions(struct android_dev *dev,
+			       struct usb_configuration *c)
+{
+	struct android_usb_function *f;
+	int ret;
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
+		ret = f->bind_config(f, c);
+		if (ret) {
+			pr_err("%s: %s failed", __func__, f->name);
+			return ret;
+		}
 	}
 	return 0;
 }
 
-static int product_matches_functions(struct android_usb_product *p)
+static void
+android_unbind_enabled_functions(struct android_dev *dev,
+			       struct usb_configuration *c)
 {
-	struct usb_function		*f;
-	list_for_each_entry(f, &android_config_driver.functions, list) {
-		if (product_has_function(p, f) == !!f->disabled)
+	struct android_usb_function *f;
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
+		if (f->unbind_config)
+			f->unbind_config(f, c);
+	}
+}
+
+static int android_enable_function(struct android_dev *dev, char *name)
+{
+	struct android_usb_function **functions = dev->functions;
+	struct android_usb_function *f;
+	while ((f = *functions++)) {
+		if (!strcmp(name, f->name)) {
+			list_add_tail(&f->enabled_list, &dev->enabled_functions);
 			return 0;
-	}
-	return 1;
-}
-
-static int get_vendor_id(struct android_dev *dev)
-{
-	struct android_usb_product *p = dev->products;
-	int count = dev->num_products;
-	int i;
-
-	if (p) {
-		for (i = 0; i < count; i++, p++) {
-			if (p->vendor_id && product_matches_functions(p))
-				return p->vendor_id;
 		}
 	}
-	/* use default vendor ID */
-	return dev->vendor_id;
+	return -EINVAL;
 }
 
-static int get_product_id(struct android_dev *dev)
-{
-	struct android_usb_product *p = dev->products;
-	int count = dev->num_products;
-	int i;
+/*-------------------------------------------------------------------------*/
+/* /sys/class/android_usb/android%d/ interface */
 
-	if (p) {
-		for (i = 0; i < count; i++, p++) {
-			if (product_matches_functions(p))
-				return p->product_id;
+static ssize_t
+functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
+{
+	struct android_dev *dev = dev_get_drvdata(pdev);
+	struct android_usb_function *f;
+	char *buff = buf;
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list)
+		buff += sprintf(buff, "%s,", f->name);
+	if (buff != buf)
+		*(buff-1) = '\n';
+	return buff - buf;
+}
+
+static ssize_t
+functions_store(struct device *pdev, struct device_attribute *attr,
+			       const char *buff, size_t size)
+{
+	struct android_dev *dev = dev_get_drvdata(pdev);
+	char *name;
+	char buf[256], *b;
+	int err;
+
+	INIT_LIST_HEAD(&dev->enabled_functions);
+
+	strncpy(buf, buff, sizeof(buf));
+	b = strim(buf);
+
+	while (b) {
+		name = strsep(&b, ",");
+		if (name) {
+			err = android_enable_function(dev, name);
+			if (err)
+				pr_err("android_usb: Cannot enable '%s'", name);
 		}
 	}
-	/* use default product ID */
-	return dev->product_id;
+
+	return size;
+}
+
+static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct android_dev *dev = dev_get_drvdata(pdev);
+	return sprintf(buf, "%d\n", dev->enabled);
+}
+
+static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
+			    const char *buff, size_t size)
+{
+	struct android_dev *dev = dev_get_drvdata(pdev);
+	struct usb_composite_dev *cdev = dev->cdev;
+	int enabled = 0;
+
+	sscanf(buff, "%d", &enabled);
+	if (enabled && !dev->enabled) {
+		/* update values in composite driver's copy of device descriptor */
+		cdev->desc.idVendor = device_desc.idVendor;
+		cdev->desc.idProduct = device_desc.idProduct;
+		cdev->desc.bcdDevice = device_desc.bcdDevice;
+		cdev->desc.bDeviceClass = device_desc.bDeviceClass;
+		cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
+		cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
+		usb_add_config(cdev, &android_config_driver,
+					android_bind_config);
+		usb_gadget_connect(cdev->gadget);
+		dev->enabled = true;
+	} else if (!enabled && dev->enabled) {
+		usb_gadget_disconnect(cdev->gadget);
+		usb_remove_config(cdev, &android_config_driver);
+		dev->enabled = false;
+	} else {
+		pr_err("android_usb: already %s\n",
+				dev->enabled ? "enabled" : "disabled");
+	}
+	return size;
+}
+
+static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct android_dev *dev = dev_get_drvdata(pdev);
+	struct usb_composite_dev *cdev = dev->cdev;
+	char *state = "DISCONNECTED";
+	unsigned long flags;
+
+	if (!cdev)
+		goto out;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+        if (cdev->config)
+		state = "CONFIGURED";
+	else if (dev->connected)
+		state = "CONNECTED";
+	spin_unlock_irqrestore(&cdev->lock, flags);
+out:
+	return sprintf(buf, "%s\n", state);
+}
+
+#define DESCRIPTOR_ATTR(field, format_string)				\
+static ssize_t								\
+field ## _show(struct device *dev, struct device_attribute *attr,	\
+		char *buf)						\
+{									\
+	return sprintf(buf, format_string, device_desc.field);		\
+}									\
+static ssize_t								\
+field ## _store(struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t size)		       		\
+{									\
+	int value;					       		\
+	if (sscanf(buf, format_string, &value) == 1) {			\
+		device_desc.field = value;				\
+		return size;						\
+	}								\
+	return -1;							\
+}									\
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
+
+#define DESCRIPTOR_STRING_ATTR(field, buffer)				\
+static ssize_t								\
+field ## _show(struct device *dev, struct device_attribute *attr,	\
+		char *buf)						\
+{									\
+	return sprintf(buf, "%s", buffer);				\
+}									\
+static ssize_t								\
+field ## _store(struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t size)		       		\
+{									\
+	if (size >= sizeof(buffer)) return -EINVAL;			\
+	if (sscanf(buf, "%s", buffer) == 1) {			       	\
+		return size;						\
+	}								\
+	return -1;							\
+}									\
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
+
+
+DESCRIPTOR_ATTR(idVendor, "%04x\n")
+DESCRIPTOR_ATTR(idProduct, "%04x\n")
+DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
+DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
+DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
+DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
+DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
+DESCRIPTOR_STRING_ATTR(iProduct, product_string)
+DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
+
+static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
+static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
+
+static struct device_attribute *android_usb_attributes[] = {
+	&dev_attr_idVendor,
+	&dev_attr_idProduct,
+	&dev_attr_bcdDevice,
+	&dev_attr_bDeviceClass,
+	&dev_attr_bDeviceSubClass,
+	&dev_attr_bDeviceProtocol,
+	&dev_attr_iManufacturer,
+	&dev_attr_iProduct,
+	&dev_attr_iSerial,
+	&dev_attr_functions,
+	&dev_attr_enable,
+	&dev_attr_state,
+	NULL
+};
+
+/*-------------------------------------------------------------------------*/
+/* Composite driver */
+
+static int android_bind_config(struct usb_configuration *c)
+{
+	struct android_dev *dev = _android_dev;
+	int ret = 0;
+
+	ret = android_bind_enabled_functions(dev, c);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void android_unbind_config(struct usb_configuration *c)
+{
+	struct android_dev *dev = _android_dev;
+
+	android_unbind_enabled_functions(dev, c);
 }
 
 static int android_bind(struct usb_composite_dev *cdev)
@@ -293,7 +939,11 @@
 	struct usb_gadget	*gadget = cdev->gadget;
 	int			gcnum, id, ret;
 
-	printk(KERN_INFO "android_bind\n");
+	usb_gadget_disconnect(gadget);
+
+	ret = android_init_functions(dev->functions, cdev);
+	if (ret)
+		return ret;
 
 	/* Allocate string descriptor numbers ... note that string
 	 * contents can be overridden by the composite_dev glue.
@@ -310,19 +960,17 @@
 	strings_dev[STRING_PRODUCT_IDX].id = id;
 	device_desc.iProduct = id;
 
+	/* Default strings - should be updated by userspace */
+	strncpy(manufacturer_string, "Android", sizeof(manufacturer_string) - 1);
+	strncpy(product_string, "Android", sizeof(product_string) - 1);
+	strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
+
 	id = usb_string_id(cdev);
 	if (id < 0)
 		return id;
 	strings_dev[STRING_SERIAL_IDX].id = id;
 	device_desc.iSerialNumber = id;
 
-	/* register our configuration */
-	ret = usb_add_config(cdev, &android_config_driver, android_bind_config);
-	if (ret) {
-		printk(KERN_ERR "usb_add_config failed\n");
-		return ret;
-	}
-
 	gcnum = usb_gadget_controller_number(gadget);
 	if (gcnum >= 0)
 		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
@@ -341,185 +989,136 @@
 
 	usb_gadget_set_selfpowered(gadget);
 	dev->cdev = cdev;
-	device_desc.idVendor = __constant_cpu_to_le16(get_vendor_id(dev));
-	device_desc.idProduct = __constant_cpu_to_le16(get_product_id(dev));
-	cdev->desc.idVendor = device_desc.idVendor;
-	cdev->desc.idProduct = device_desc.idProduct;
 
 	return 0;
 }
 
+static int android_usb_unbind(struct usb_composite_dev *cdev)
+{
+	struct android_dev *dev = _android_dev;
+
+	cancel_work_sync(&dev->work);
+	android_cleanup_functions(dev->functions);
+	return 0;
+}
+
 static struct usb_composite_driver android_usb_driver = {
 	.name		= "android_usb",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.enable_function = android_enable_function,
+	.unbind		= android_usb_unbind,
 };
 
-void android_register_function(struct android_usb_function *f)
+static int
+android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
+{
+	struct android_dev		*dev = _android_dev;
+	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
+	struct usb_request		*req = cdev->req;
+	struct android_usb_function	**functions = dev->functions;
+	struct android_usb_function	*f;
+	int value = -EOPNOTSUPP;
+	unsigned long flags;
+
+	req->zero = 0;
+	req->complete = composite_setup_complete;
+	req->length = 0;
+	gadget->ep0->driver_data = cdev;
+
+	while ((f = *functions++)) {
+		if (f->ctrlrequest) {
+			value = f->ctrlrequest(f, cdev, c);
+			if (value >= 0)
+				break;
+		}
+	}
+
+	if (value < 0)
+		value = composite_setup(gadget, c);
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	if (!dev->connected) {
+		dev->connected = 1;
+		schedule_work(&dev->work);
+	}
+	else if (c->bRequest == USB_REQ_SET_CONFIGURATION && cdev->config) {
+		schedule_work(&dev->work);
+	}
+	spin_unlock_irqrestore(&cdev->lock, flags);
+
+	return value;
+}
+
+static void android_disconnect(struct usb_gadget *gadget)
 {
 	struct android_dev *dev = _android_dev;
-
-	printk(KERN_INFO "android_register_function %s\n", f->name);
-	list_add_tail(&f->list, &_functions);
-
-	if (dev && should_bind_functions(dev))
-		bind_functions(dev);
+	dev->connected = 0;
+	schedule_work(&dev->work);
+	composite_disconnect(gadget);
 }
 
-void update_dev_desc(struct android_dev *dev)
+static int android_create_device(struct android_dev *dev)
 {
-	struct usb_function *f;
-	struct usb_function *last_enabled_f = NULL;
-	int num_enabled = 0;
-	int has_iad = 0;
+	struct device_attribute **attrs = android_usb_attributes;
+	struct device_attribute *attr;
+	int err;
 
-	dev->cdev->desc.bDeviceClass = USB_CLASS_PER_INTERFACE;
-	dev->cdev->desc.bDeviceSubClass = 0x00;
-	dev->cdev->desc.bDeviceProtocol = 0x00;
+	dev->dev = device_create(android_class, NULL,
+					MKDEV(0, 0), NULL, "android0");
+	if (IS_ERR(dev->dev))
+		return PTR_ERR(dev->dev);
 
-	list_for_each_entry(f, &android_config_driver.functions, list) {
-		if (!f->disabled) {
-			num_enabled++;
-			last_enabled_f = f;
-			if (f->descriptors[0]->bDescriptorType ==
-					USB_DT_INTERFACE_ASSOCIATION)
-				has_iad = 1;
-		}
-		if (num_enabled > 1 && has_iad) {
-			dev->cdev->desc.bDeviceClass = USB_CLASS_MISC;
-			dev->cdev->desc.bDeviceSubClass = 0x02;
-			dev->cdev->desc.bDeviceProtocol = 0x01;
-			break;
+	dev_set_drvdata(dev->dev, dev);
+
+	while ((attr = *attrs++)) {
+		err = device_create_file(dev->dev, attr);
+		if (err) {
+			device_destroy(android_class, dev->dev->devt);
+			return err;
 		}
 	}
-
-	if (num_enabled == 1) {
-#ifdef CONFIG_USB_ANDROID_RNDIS
-		if (!strcmp(last_enabled_f->name, "rndis")) {
-#ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS
-			dev->cdev->desc.bDeviceClass =
-					USB_CLASS_WIRELESS_CONTROLLER;
-#else
-			dev->cdev->desc.bDeviceClass = USB_CLASS_COMM;
-#endif
-		}
-#endif
-	}
+	return 0;
 }
 
-void android_enable_function(struct usb_function *f, int enable)
-{
-	struct android_dev *dev = _android_dev;
-	int disable = !enable;
-
-	if (!!f->disabled != disable) {
-		usb_function_set_enabled(f, !disable);
-
-#ifdef CONFIG_USB_ANDROID_RNDIS
-		if (!strcmp(f->name, "rndis")) {
-			struct usb_function		*func;
-			/* Windows does not support other interfaces when RNDIS is enabled,
-			 * so we disable UMS and MTP when RNDIS is on.
-			 */
-			list_for_each_entry(func, &android_config_driver.functions, list) {
-				if (!strcmp(func->name, "usb_mass_storage")
-					|| !strcmp(func->name, "mtp")) {
-					usb_function_set_enabled(func, !enable);
-				}
-			}
-		}
-#endif
-#ifdef CONFIG_USB_ANDROID_ACCESSORY
-		if (!strcmp(f->name, "accessory") && enable) {
-			struct usb_function		*func;
-
-		    /* disable everything else (and keep adb for now) */
-			list_for_each_entry(func, &android_config_driver.functions, list) {
-				if (strcmp(func->name, "accessory")
-					&& strcmp(func->name, "adb")) {
-					usb_function_set_enabled(func, 0);
-				}
-			}
-        }
-#endif
-
-		update_dev_desc(dev);
-
-		device_desc.idVendor = __constant_cpu_to_le16(get_vendor_id(dev));
-		device_desc.idProduct = __constant_cpu_to_le16(get_product_id(dev));
-		if (dev->cdev) {
-			dev->cdev->desc.idVendor = device_desc.idVendor;
-			dev->cdev->desc.idProduct = device_desc.idProduct;
-		}
-		usb_composite_force_reset(dev->cdev);
-	}
-}
-
-static int android_probe(struct platform_device *pdev)
-{
-	struct android_usb_platform_data *pdata = pdev->dev.platform_data;
-	struct android_dev *dev = _android_dev;
-
-	printk(KERN_INFO "android_probe pdata: %p\n", pdata);
-
-	if (pdata) {
-		dev->products = pdata->products;
-		dev->num_products = pdata->num_products;
-		dev->functions = pdata->functions;
-		dev->num_functions = pdata->num_functions;
-		if (pdata->vendor_id) {
-			dev->vendor_id = pdata->vendor_id;
-			device_desc.idVendor =
-				__constant_cpu_to_le16(pdata->vendor_id);
-		}
-		if (pdata->product_id) {
-			dev->product_id = pdata->product_id;
-			device_desc.idProduct =
-				__constant_cpu_to_le16(pdata->product_id);
-		}
-		if (pdata->version)
-			dev->version = pdata->version;
-
-		if (pdata->product_name)
-			strings_dev[STRING_PRODUCT_IDX].s = pdata->product_name;
-		if (pdata->manufacturer_name)
-			strings_dev[STRING_MANUFACTURER_IDX].s =
-					pdata->manufacturer_name;
-		if (pdata->serial_number)
-			strings_dev[STRING_SERIAL_IDX].s = pdata->serial_number;
-	}
-
-	return usb_composite_probe(&android_usb_driver, android_bind);
-}
-
-static struct platform_driver android_platform_driver = {
-	.driver = { .name = "android_usb", },
-	.probe = android_probe,
-};
 
 static int __init init(void)
 {
 	struct android_dev *dev;
+	int err;
 
-	printk(KERN_INFO "android init\n");
+	android_class = class_create(THIS_MODULE, "android_usb");
+	if (IS_ERR(android_class))
+		return PTR_ERR(android_class);
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
 
-	/* set default values, which should be overridden by platform data */
-	dev->product_id = PRODUCT_ID;
+	dev->functions = supported_functions;
+	INIT_LIST_HEAD(&dev->enabled_functions);
+	INIT_WORK(&dev->work, android_work);
+
+	err = android_create_device(dev);
+	if (err) {
+		class_destroy(android_class);
+		kfree(dev);
+		return err;
+	}
+
 	_android_dev = dev;
 
-	return platform_driver_register(&android_platform_driver);
+	/* Override composite driver functions */
+	composite_driver.setup = android_setup;
+	composite_driver.disconnect = android_disconnect;
+
+	return usb_composite_probe(&android_usb_driver, android_bind);
 }
 module_init(init);
 
 static void __exit cleanup(void)
 {
 	usb_composite_unregister(&android_usb_driver);
-	platform_driver_unregister(&android_platform_driver);
+	class_destroy(android_class);
 	kfree(_android_dev);
 	_android_dev = NULL;
 }
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 6c8fbb1..dc06da6 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -25,8 +25,7 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/utsname.h>
-#include <linux/delay.h>
-#include <linux/kdev_t.h>
+
 #include <linux/usb/composite.h>
 
 
@@ -76,56 +75,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
-		char *buf)
-{
-	struct usb_function *f = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", !f->disabled);
-}
-
-static ssize_t enable_store(
-		struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t size)
-{
-	struct usb_function *f = dev_get_drvdata(dev);
-	struct usb_composite_driver	*driver = f->config->cdev->driver;
-	int value;
-
-	sscanf(buf, "%d", &value);
-	if (driver->enable_function)
-		driver->enable_function(f, value);
-	else
-		usb_function_set_enabled(f, value);
-
-	return size;
-}
-
-static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
-
-void usb_function_set_enabled(struct usb_function *f, int enabled)
-{
-	f->disabled = !enabled;
-	kobject_uevent(&f->dev->kobj, KOBJ_CHANGE);
-}
-
-
-void usb_composite_force_reset(struct usb_composite_dev *cdev)
-{
-	unsigned long			flags;
-
-	spin_lock_irqsave(&cdev->lock, flags);
-	/* force reenumeration */
-	if (cdev && cdev->gadget && cdev->gadget->speed != USB_SPEED_UNKNOWN) {
-		spin_unlock_irqrestore(&cdev->lock, flags);
-
-		usb_gadget_disconnect(cdev->gadget);
-		msleep(10);
-		usb_gadget_connect(cdev->gadget);
-	} else {
-		spin_unlock_irqrestore(&cdev->lock, flags);
-	}
-}
-
 /**
  * usb_add_function() - add a function to a configuration
  * @config: the configuration
@@ -143,30 +92,15 @@
 int usb_add_function(struct usb_configuration *config,
 		struct usb_function *function)
 {
-	struct usb_composite_dev	*cdev = config->cdev;
 	int	value = -EINVAL;
-	int index;
 
-	DBG(cdev, "adding '%s'/%p to config '%s'/%p\n",
+	DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n",
 			function->name, function,
 			config->label, config);
 
 	if (!function->set_alt || !function->disable)
 		goto done;
 
-	index = atomic_inc_return(&cdev->driver->function_count);
-	function->dev = device_create(cdev->driver->class, NULL,
-		MKDEV(0, index), NULL, function->name);
-	if (IS_ERR(function->dev))
-		return PTR_ERR(function->dev);
-
-	value = device_create_file(function->dev, &dev_attr_enable);
-	if (value < 0) {
-		device_destroy(cdev->driver->class, MKDEV(0, index));
-		return value;
-	}
-	dev_set_drvdata(function->dev, function);
-
 	function->config = config;
 	list_add_tail(&function->list, &config->functions);
 
@@ -192,7 +126,7 @@
 
 done:
 	if (value)
-		DBG(cdev, "adding '%s'/%p --> %d\n",
+		DBG(config->cdev, "adding '%s'/%p --> %d\n",
 				function->name, function, value);
 	return value;
 }
@@ -302,20 +236,17 @@
 		enum usb_device_speed speed, void *buf, u8 type)
 {
 	struct usb_config_descriptor	*c = buf;
-	struct usb_interface_descriptor *intf;
-	struct usb_interface_assoc_descriptor *iad = NULL;
 	void				*next = buf + USB_DT_CONFIG_SIZE;
 	int				len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
 	struct usb_function		*f;
 	int				status;
-	int				interfaceCount = 0;
-	u8 *dest;
 
 	/* write the config descriptor */
 	c = buf;
 	c->bLength = USB_DT_CONFIG_SIZE;
 	c->bDescriptorType = type;
-	/* wTotalLength and bNumInterfaces are written later */
+	/* wTotalLength is written later */
+	c->bNumInterfaces = config->next_interface_id;
 	c->bConfigurationValue = config->bConfigurationValue;
 	c->iConfiguration = config->iConfiguration;
 	c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
@@ -334,54 +265,23 @@
 	/* add each function's descriptors */
 	list_for_each_entry(f, &config->functions, list) {
 		struct usb_descriptor_header **descriptors;
-		struct usb_descriptor_header *descriptor;
 
 		if (speed == USB_SPEED_HIGH)
 			descriptors = f->hs_descriptors;
 		else
 			descriptors = f->descriptors;
-		if (f->disabled || !descriptors || descriptors[0] == NULL)
+		if (!descriptors)
 			continue;
 		status = usb_descriptor_fillbuf(next, len,
 			(const struct usb_descriptor_header **) descriptors);
 		if (status < 0)
 			return status;
-
-		/* set interface numbers dynamically */
-		dest = next;
-		while ((descriptor = *descriptors++) != NULL) {
-			intf = (struct usb_interface_descriptor *)dest;
-			if (intf->bDescriptorType == USB_DT_INTERFACE) {
-				/* don't increment bInterfaceNumber for alternate settings */
-				if (intf->bAlternateSetting == 0)
-					intf->bInterfaceNumber = interfaceCount++;
-				else
-					intf->bInterfaceNumber = interfaceCount - 1;
-				if (iad) {
-					iad->bFirstInterface =
-							intf->bInterfaceNumber;
-					iad = NULL;
-				}
-			} else if (intf->bDescriptorType ==
-					USB_DT_INTERFACE_ASSOCIATION) {
-				/* This will be first if it exists. Save
-				 * a pointer to it so we can properly set
-				 * bFirstInterface when we process the first
-				 * interface.
-				 */
-				iad = (struct usb_interface_assoc_descriptor *)
-						dest;
-			}
-			dest += intf->bLength;
-		}
-
 		len -= status;
 		next += status;
 	}
 
 	len = next - buf;
 	c->wTotalLength = cpu_to_le16(len);
-	c->bNumInterfaces = interfaceCount;
 	return len;
 }
 
@@ -528,8 +428,6 @@
 
 		if (!f)
 			break;
-		if (f->disabled)
-			continue;
 
 		/*
 		 * Record which endpoints are used by the function. This is used
@@ -579,8 +477,6 @@
 done:
 	usb_gadget_vbus_draw(gadget, power);
 
-	schedule_work(&cdev->switch_work);
-
 	if (result >= 0 && cdev->delayed_status)
 		result = USB_GADGET_DELAYED_STATUS;
 	return result;
@@ -628,6 +524,7 @@
 
 	INIT_LIST_HEAD(&config->functions);
 	config->next_interface_id = 0;
+	memset(config->interface, '\0', sizeof(config->interface));
 
 	status = bind(config);
 	if (status < 0) {
@@ -961,14 +858,6 @@
 	u16				w_length = le16_to_cpu(ctrl->wLength);
 	struct usb_function		*f = NULL;
 	u8				endp;
-	unsigned long			flags;
-
-	spin_lock_irqsave(&cdev->lock, flags);
-	if (!cdev->connected) {
-		cdev->connected = 1;
-		schedule_work(&cdev->switch_work);
-	}
-	spin_unlock_irqrestore(&cdev->lock, flags);
 
 	/* partial re-init of the response message; the function or the
 	 * gadget might need to intercept e.g. a control-OUT completion
@@ -1012,21 +901,6 @@
 		case USB_DT_STRING:
 			value = get_string(cdev, req->buf,
 					w_index, w_value & 0xff);
-
-			/* Allow functions to handle USB_DT_STRING.
-			 * This is required for MTP.
-			 */
-			if (value < 0) {
-				struct usb_configuration        *cfg;
-				list_for_each_entry(cfg, &cdev->configs, list) {
-					if (cfg && cfg->setup) {
-						value = cfg->setup(cfg, ctrl);
-						if (value >= 0)
-							break;
-					}
-				}
-			}
-
 			if (value >= 0)
 				value = min(w_length, (u16) value);
 			break;
@@ -1140,25 +1014,6 @@
 				value = c->setup(c, ctrl);
 		}
 
-		/* If the vendor request is not processed (value < 0),
-		 * call all device registered configure setup callbacks
-		 * to process it.
-		 * This is used to handle the following cases:
-		 * - vendor request is for the device and arrives before
-		 * setconfiguration.
-		 * - Some devices are required to handle vendor request before
-		 * setconfiguration such as MTP, USBNET.
-		 */
-
-		if (value < 0) {
-			struct usb_configuration        *cfg;
-
-			list_for_each_entry(cfg, &cdev->configs, list) {
-			if (cfg && cfg->setup)
-				value = cfg->setup(cfg, ctrl);
-			}
-		}
-
 		goto done;
 	}
 
@@ -1194,12 +1049,8 @@
 	spin_lock_irqsave(&cdev->lock, flags);
 	if (cdev->config)
 		reset_config(cdev);
-
 	if (composite->disconnect)
 		composite->disconnect(cdev);
-
-	cdev->connected = 0;
-	schedule_work(&cdev->switch_work);
 	spin_unlock_irqrestore(&cdev->lock, flags);
 }
 
@@ -1242,8 +1093,6 @@
 		kfree(cdev->req->buf);
 		usb_ep_free_request(gadget->ep0, cdev->req);
 	}
-	switch_dev_unregister(&cdev->sw_connected);
-	switch_dev_unregister(&cdev->sw_config);
 	device_remove_file(&gadget->dev, &dev_attr_suspended);
 	kfree(cdev);
 	set_gadget_data(gadget, NULL);
@@ -1263,30 +1112,6 @@
 	return *desc;
 }
 
-static void
-composite_switch_work(struct work_struct *data)
-{
-	struct usb_composite_dev	*cdev =
-		container_of(data, struct usb_composite_dev, switch_work);
-	struct usb_configuration *config = cdev->config;
-	int connected;
-	unsigned long flags;
-
-	spin_lock_irqsave(&cdev->lock, flags);
-	if (cdev->connected != cdev->sw_connected.state) {
-		connected = cdev->connected;
-		spin_unlock_irqrestore(&cdev->lock, flags);
-		switch_set_state(&cdev->sw_connected, connected);
-	} else {
-		spin_unlock_irqrestore(&cdev->lock, flags);
-	}
-
-	if (config)
-		switch_set_state(&cdev->sw_config, config->bConfigurationValue);
-	else
-		switch_set_state(&cdev->sw_config, 0);
-}
-
 static int composite_bind(struct usb_gadget *gadget)
 {
 	struct usb_composite_dev	*cdev;
@@ -1336,16 +1161,6 @@
 	if (status < 0)
 		goto fail;
 
-	cdev->sw_connected.name = "usb_connected";
-	status = switch_dev_register(&cdev->sw_connected);
-	if (status < 0)
-		goto fail;
-	cdev->sw_config.name = "usb_configuration";
-	status = switch_dev_register(&cdev->sw_config);
-	if (status < 0)
-		goto fail;
-	INIT_WORK(&cdev->switch_work, composite_switch_work);
-
 	cdev->desc = *composite->dev;
 	cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 
@@ -1451,23 +1266,6 @@
 	cdev->suspended = 0;
 }
 
-static int
-composite_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-	struct usb_function *f = dev_get_drvdata(dev);
-
-	if (!f) {
-		/* this happens when the device is first created */
-		return 0;
-	}
-
-	if (add_uevent_var(env, "FUNCTION=%s", f->name))
-		return -ENOMEM;
-	if (add_uevent_var(env, "ENABLED=%d", !f->disabled))
-		return -ENOMEM;
-	return 0;
-}
-
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver composite_driver = {
@@ -1520,11 +1318,6 @@
 	composite = driver;
 	composite_gadget_bind = bind;
 
-	driver->class = class_create(THIS_MODULE, "usb_composite");
-	if (IS_ERR(driver->class))
-		return PTR_ERR(driver->class);
-	driver->class->dev_uevent = composite_uevent;
-
 	return usb_gadget_probe_driver(&composite_driver, composite_bind);
 }
 
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c
index ad3c173..873ab2e 100644
--- a/drivers/usb/gadget/f_accessory.c
+++ b/drivers/usb/gadget/f_accessory.c
@@ -35,7 +35,6 @@
 
 #include <linux/usb.h>
 #include <linux/usb/ch9.h>
-#include <linux/usb/android_composite.h>
 #include <linux/usb/f_accessory.h>
 
 #define BULK_BUFFER_SIZE    16384
@@ -249,12 +248,11 @@
 static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req)
 {
 	struct acc_dev	*dev = ep->driver_data;
-	struct usb_composite_dev *cdev = dev->cdev;
 	char *string_dest = NULL;
 	int length = req->actual;
 
 	if (req->status != 0) {
-		DBG(cdev, "acc_complete_set_string, err %d\n", req->status);
+		pr_err("acc_complete_set_string, err %d\n", req->status);
 		return;
 	}
 
@@ -285,12 +283,12 @@
 			length = ACC_STRING_SIZE - 1;
 
 		spin_lock_irqsave(&dev->lock, flags);
-		memcpy(string_dest, cdev->req->buf, length);
+		memcpy(string_dest, req->buf, length);
 		/* ensure zero termination */
 		string_dest[length] = 0;
 		spin_unlock_irqrestore(&dev->lock, flags);
 	} else {
-		DBG(cdev, "unknown accessory string index %d\n",
+		pr_err("unknown accessory string index %d\n",
 			dev->string_index);
 	}
 }
@@ -364,12 +362,11 @@
 	size_t count, loff_t *pos)
 {
 	struct acc_dev *dev = fp->private_data;
-	struct usb_composite_dev *cdev = dev->cdev;
 	struct usb_request *req;
 	int r = count, xfer;
 	int ret = 0;
 
-	DBG(cdev, "acc_read(%d)\n", count);
+	pr_debug("acc_read(%d)\n", count);
 
 	if (dev->disconnected)
 		return -ENODEV;
@@ -378,7 +375,7 @@
 		count = BULK_BUFFER_SIZE;
 
 	/* we will block until we're online */
-	DBG(cdev, "acc_read: waiting for online\n");
+	pr_debug("acc_read: waiting for online\n");
 	ret = wait_event_interruptible(dev->read_wq, dev->online);
 	if (ret < 0) {
 		r = ret;
@@ -395,7 +392,7 @@
 		r = -EIO;
 		goto done;
 	} else {
-		DBG(cdev, "rx %p queue\n", req);
+		pr_debug("rx %p queue\n", req);
 	}
 
 	/* wait for a request to complete */
@@ -410,7 +407,7 @@
 		if (req->actual == 0)
 			goto requeue_req;
 
-		DBG(cdev, "rx %p %d\n", req, req->actual);
+		pr_debug("rx %p %d\n", req, req->actual);
 		xfer = (req->actual < count) ? req->actual : count;
 		r = xfer;
 		if (copy_to_user(buf, req->buf, xfer))
@@ -419,7 +416,7 @@
 		r = -EIO;
 
 done:
-	DBG(cdev, "acc_read returning %d\n", r);
+	pr_debug("acc_read returning %d\n", r);
 	return r;
 }
 
@@ -427,19 +424,18 @@
 	size_t count, loff_t *pos)
 {
 	struct acc_dev *dev = fp->private_data;
-	struct usb_composite_dev *cdev = dev->cdev;
 	struct usb_request *req = 0;
 	int r = count, xfer;
 	int ret;
 
-	DBG(cdev, "acc_write(%d)\n", count);
+	pr_debug("acc_write(%d)\n", count);
 
 	if (!dev->online || dev->disconnected)
 		return -ENODEV;
 
 	while (count > 0) {
 		if (!dev->online) {
-			DBG(cdev, "acc_write dev->error\n");
+			pr_debug("acc_write dev->error\n");
 			r = -EIO;
 			break;
 		}
@@ -465,7 +461,7 @@
 		req->length = xfer;
 		ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL);
 		if (ret < 0) {
-			DBG(cdev, "acc_write: xfer error %d\n", ret);
+			pr_debug("acc_write: xfer error %d\n", ret);
 			r = -EIO;
 			break;
 		}
@@ -480,7 +476,7 @@
 	if (req)
 		req_put(dev, &dev->tx_idle, req);
 
-	DBG(cdev, "acc_write returning %d\n", r);
+	pr_debug("acc_write returning %d\n", r);
 	return r;
 }
 
@@ -490,9 +486,6 @@
 	char *src = NULL;
 	int ret;
 
-	if (dev->function.disabled)
-		return -ENODEV;
-
 	switch (code) {
 	case ACCESSORY_GET_STRING_MANUFACTURER:
 		src = dev->manufacturer;
@@ -558,6 +551,69 @@
 	.fops = &acc_fops,
 };
 
+
+static int acc_ctrlrequest(struct usb_composite_dev *cdev,
+				const struct usb_ctrlrequest *ctrl)
+{
+	struct acc_dev	*dev = _acc_dev;
+	int	value = -EOPNOTSUPP;
+	u8 b_requestType = ctrl->bRequestType;
+	u8 b_request = ctrl->bRequest;
+	u16	w_index = le16_to_cpu(ctrl->wIndex);
+	u16	w_value = le16_to_cpu(ctrl->wValue);
+	u16	w_length = le16_to_cpu(ctrl->wLength);
+
+/*
+	printk(KERN_INFO "acc_ctrlrequest "
+			"%02x.%02x v%04x i%04x l%u\n",
+			b_requestType, b_request,
+			w_value, w_index, w_length);
+*/
+
+	if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) {
+		if (b_request == ACCESSORY_START) {
+			schedule_delayed_work(
+				&dev->work, msecs_to_jiffies(10));
+			value = 0;
+		} else if (b_request == ACCESSORY_SEND_STRING) {
+			dev->string_index = w_index;
+			cdev->gadget->ep0->driver_data = dev;
+			cdev->req->complete = acc_complete_set_string;
+			value = w_length;
+		}
+	} else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) {
+		if (b_request == ACCESSORY_GET_PROTOCOL) {
+			*((u16 *)cdev->req->buf) = PROTOCOL_VERSION;
+			value = sizeof(u16);
+
+			/* clear any strings left over from a previous session */
+			memset(dev->manufacturer, 0, sizeof(dev->manufacturer));
+			memset(dev->model, 0, sizeof(dev->model));
+			memset(dev->description, 0, sizeof(dev->description));
+			memset(dev->version, 0, sizeof(dev->version));
+			memset(dev->uri, 0, sizeof(dev->uri));
+			memset(dev->serial, 0, sizeof(dev->serial));
+		}
+	}
+
+	if (value >= 0) {
+		cdev->req->zero = 0;
+		cdev->req->length = value;
+		value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
+		if (value < 0)
+			ERROR(cdev, "%s setup response queue error\n",
+				__func__);
+	}
+
+	if (value == -EOPNOTSUPP)
+		VDBG(cdev,
+			"unknown class-specific control req "
+			"%02x.%02x v%04x i%04x l%u\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			w_value, w_index, w_length);
+	return value;
+}
+
 static int
 acc_function_bind(struct usb_configuration *c, struct usb_function *f)
 {
@@ -566,7 +622,6 @@
 	int			id;
 	int			ret;
 
-	dev->cdev = cdev;
 	DBG(cdev, "acc_function_bind dev: %p\n", dev);
 
 	/* allocate interface ID(s) */
@@ -602,90 +657,16 @@
 	struct usb_request *req;
 	int i;
 
-	spin_lock_irq(&dev->lock);
 	while ((req = req_get(dev, &dev->tx_idle)))
 		acc_request_free(req, dev->ep_in);
 	for (i = 0; i < RX_REQ_MAX; i++)
 		acc_request_free(dev->rx_req[i], dev->ep_out);
-	dev->online = 0;
-	spin_unlock_irq(&dev->lock);
-
-	misc_deregister(&acc_device);
-	kfree(_acc_dev);
-	_acc_dev = NULL;
 }
 
 static void acc_work(struct work_struct *data)
 {
-	struct delayed_work *delayed = to_delayed_work(data);
-	struct acc_dev	*dev =
-		container_of(delayed, struct acc_dev, work);
-	android_enable_function(&dev->function, 1);
-}
-
-static int acc_function_setup(struct usb_function *f,
-					const struct usb_ctrlrequest *ctrl)
-{
-	struct acc_dev	*dev = func_to_dev(f);
-	struct usb_composite_dev *cdev = dev->cdev;
-	int	value = -EOPNOTSUPP;
-	u8 b_requestType = ctrl->bRequestType;
-	u8 b_request = ctrl->bRequest;
-	u16	w_index = le16_to_cpu(ctrl->wIndex);
-	u16	w_value = le16_to_cpu(ctrl->wValue);
-	u16	w_length = le16_to_cpu(ctrl->wLength);
-
-/*
-	printk(KERN_INFO "acc_function_setup "
-			"%02x.%02x v%04x i%04x l%u\n",
-			b_requestType, b_request,
-			w_value, w_index, w_length);
-*/
-
-	if (dev->function.disabled) {
-		if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) {
-			if (b_request == ACCESSORY_START) {
-				schedule_delayed_work(
-					&dev->work, msecs_to_jiffies(10));
-				value = 0;
-			} else if (b_request == ACCESSORY_SEND_STRING) {
-				dev->string_index = w_index;
-				cdev->gadget->ep0->driver_data = dev;
-				cdev->req->complete = acc_complete_set_string;
-				value = w_length;
-			}
-		} else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) {
-			if (b_request == ACCESSORY_GET_PROTOCOL) {
-				*((u16 *)cdev->req->buf) = PROTOCOL_VERSION;
-				value = sizeof(u16);
-
-				/* clear any strings left over from a previous session */
-				memset(dev->manufacturer, 0, sizeof(dev->manufacturer));
-				memset(dev->model, 0, sizeof(dev->model));
-				memset(dev->description, 0, sizeof(dev->description));
-				memset(dev->version, 0, sizeof(dev->version));
-				memset(dev->uri, 0, sizeof(dev->uri));
-				memset(dev->serial, 0, sizeof(dev->serial));
-			}
-		}
-	}
-
-	if (value >= 0) {
-		cdev->req->zero = 0;
-		cdev->req->length = value;
-		value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
-		if (value < 0)
-			ERROR(cdev, "%s setup response queue error\n",
-				__func__);
-	}
-
-	if (value == -EOPNOTSUPP)
-		VDBG(cdev,
-			"unknown class-specific control req "
-			"%02x.%02x v%04x i%04x l%u\n",
-			ctrl->bRequestType, ctrl->bRequest,
-			w_value, w_index, w_length);
-	return value;
+	char *envp[2] = { "ACCESSORY=START", NULL };
+	kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp);
 }
 
 static int acc_function_set_alt(struct usb_function *f,
@@ -710,8 +691,8 @@
 		usb_ep_disable(dev->ep_in);
 		return ret;
 	}
-	if (!dev->function.disabled)
-		dev->online = 1;
+
+	dev->online = 1;
 
 	/* readers may be blocked waiting for us to go online */
 	wake_up(&dev->read_wq);
@@ -736,15 +717,11 @@
 
 static int acc_bind_config(struct usb_configuration *c)
 {
-	struct acc_dev *dev;
+	struct acc_dev *dev = _acc_dev;
 	int ret;
 
 	printk(KERN_INFO "acc_bind_config\n");
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
-
 	/* allocate a string ID for our interface */
 	if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) {
 		ret = usb_string_id(c->cdev);
@@ -754,13 +731,6 @@
 		acc_interface_desc.iInterface = ret;
 	}
 
-	spin_lock_init(&dev->lock);
-	init_waitqueue_head(&dev->read_wq);
-	init_waitqueue_head(&dev->write_wq);
-	atomic_set(&dev->open_excl, 0);
-	INIT_LIST_HEAD(&dev->tx_idle);
-	INIT_DELAYED_WORK(&dev->work, acc_work);
-
 	dev->cdev = c->cdev;
 	dev->function.name = "accessory";
 	dev->function.strings = acc_strings,
@@ -768,41 +738,46 @@
 	dev->function.hs_descriptors = hs_acc_descs;
 	dev->function.bind = acc_function_bind;
 	dev->function.unbind = acc_function_unbind;
-	dev->function.setup = acc_function_setup;
 	dev->function.set_alt = acc_function_set_alt;
 	dev->function.disable = acc_function_disable;
-	dev->function.disabled = 1;
+
+	return usb_add_function(c, &dev->function);
+}
+
+static int acc_setup(void)
+{
+	struct acc_dev *dev;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	spin_lock_init(&dev->lock);
+	init_waitqueue_head(&dev->read_wq);
+	init_waitqueue_head(&dev->write_wq);
+	atomic_set(&dev->open_excl, 0);
+	INIT_LIST_HEAD(&dev->tx_idle);
+	INIT_DELAYED_WORK(&dev->work, acc_work);
 
 	/* _acc_dev must be set before calling usb_gadget_register_driver */
 	_acc_dev = dev;
 
 	ret = misc_register(&acc_device);
 	if (ret)
-		goto err1;
-
-	ret = usb_add_function(c, &dev->function);
-	if (ret)
-		goto err2;
+		goto err;
 
 	return 0;
 
-err2:
-	misc_deregister(&acc_device);
-err1:
+err:
 	kfree(dev);
 	printk(KERN_ERR "USB accessory gadget driver failed to initialize\n");
 	return ret;
 }
 
-static struct android_usb_function acc_function = {
-	.name = "accessory",
-	.bind_config = acc_bind_config,
-};
-
-static int __init init(void)
+static void acc_cleanup(void)
 {
-	printk(KERN_INFO "f_accessory init\n");
-	android_register_function(&acc_function);
-	return 0;
+	misc_deregister(&acc_device);
+	kfree(_acc_dev);
+	_acc_dev = NULL;
 }
-module_init(init);
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index cf2e7fc..68b1a8e 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
-#include <linux/usb/android_composite.h>
 
 #include "u_serial.h"
 #include "gadget_chips.h"
@@ -788,55 +787,3 @@
 		kfree(acm);
 	return status;
 }
-
-#ifdef CONFIG_USB_ANDROID_ACM
-#include <linux/platform_device.h>
-
-static struct acm_platform_data *acm_pdata;
-
-static int acm_probe(struct platform_device *pdev)
-{
-	acm_pdata = pdev->dev.platform_data;
-	return 0;
-}
-
-static struct platform_driver acm_platform_driver = {
-	.driver = { .name = "acm", },
-	.probe = acm_probe,
-};
-
-int acm_function_bind_config(struct usb_configuration *c)
-{
-	int i;
-	u8 num_inst = acm_pdata ? acm_pdata->num_inst : 1;
-	int ret = gserial_setup(c->cdev->gadget, num_inst);
-
-	if (ret)
-		return ret;
-
-	for (i = 0; i < num_inst; i++) {
-		ret = acm_bind_config(c, i);
-		if (ret) {
-			pr_err("Could not bind acm%u config\n", i);
-			break;
-		}
-	}
-
-	return ret;
-}
-
-static struct android_usb_function acm_function = {
-	.name = "acm",
-	.bind_config = acm_function_bind_config,
-};
-
-static int __init init(void)
-{
-	printk(KERN_INFO "f_acm init\n");
-	platform_driver_register(&acm_platform_driver);
-	android_register_function(&acm_function);
-	return 0;
-}
-module_init(init);
-
-#endif /* CONFIG_USB_ANDROID_ACM */
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c
index 7cfa39c..fe4455e 100644
--- a/drivers/usb/gadget/f_adb.c
+++ b/drivers/usb/gadget/f_adb.c
@@ -15,9 +15,6 @@
  *
  */
 
-/* #define DEBUG */
-/* #define VERBOSE_DEBUG */
-
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/poll.h>
@@ -30,14 +27,12 @@
 #include <linux/device.h>
 #include <linux/miscdevice.h>
 
-#include <linux/usb/android_composite.h>
-
-#define BULK_BUFFER_SIZE           4096
+#define ADB_BULK_BUFFER_SIZE           4096
 
 /* number of tx requests to allocate */
 #define TX_REQ_MAX 4
 
-static const char shortname[] = "android_adb";
+static const char adb_shortname[] = "android_adb";
 
 struct adb_dev {
 	struct usb_function function;
@@ -120,9 +115,7 @@
 /* temporary variable used between adb_open() and adb_gadget_bind() */
 static struct adb_dev *_adb_dev;
 
-static atomic_t adb_enable_excl;
-
-static inline struct adb_dev *func_to_dev(struct usb_function *f)
+static inline struct adb_dev *func_to_adb(struct usb_function *f)
 {
 	return container_of(f, struct adb_dev, function);
 }
@@ -152,7 +145,7 @@
 	}
 }
 
-static inline int _lock(atomic_t *excl)
+static inline int adb_lock(atomic_t *excl)
 {
 	if (atomic_inc_return(excl) == 1) {
 		return 0;
@@ -162,13 +155,13 @@
 	}
 }
 
-static inline void _unlock(atomic_t *excl)
+static inline void adb_unlock(atomic_t *excl)
 {
 	atomic_dec(excl);
 }
 
 /* add a request to the tail of a list */
-void req_put(struct adb_dev *dev, struct list_head *head,
+void adb_req_put(struct adb_dev *dev, struct list_head *head,
 		struct usb_request *req)
 {
 	unsigned long flags;
@@ -179,7 +172,7 @@
 }
 
 /* remove a request from the head of a list */
-struct usb_request *req_get(struct adb_dev *dev, struct list_head *head)
+struct usb_request *adb_req_get(struct adb_dev *dev, struct list_head *head)
 {
 	unsigned long flags;
 	struct usb_request *req;
@@ -202,7 +195,7 @@
 	if (req->status != 0)
 		dev->error = 1;
 
-	req_put(dev, &dev->tx_idle, req);
+	adb_req_put(dev, &dev->tx_idle, req);
 
 	wake_up(&dev->write_wq);
 }
@@ -218,7 +211,7 @@
 	wake_up(&dev->read_wq);
 }
 
-static int __init create_bulk_endpoints(struct adb_dev *dev,
+static int adb_create_bulk_endpoints(struct adb_dev *dev,
 				struct usb_endpoint_descriptor *in_desc,
 				struct usb_endpoint_descriptor *out_desc)
 {
@@ -248,18 +241,18 @@
 	dev->ep_out = ep;
 
 	/* now allocate requests for our endpoints */
-	req = adb_request_new(dev->ep_out, BULK_BUFFER_SIZE);
+	req = adb_request_new(dev->ep_out, ADB_BULK_BUFFER_SIZE);
 	if (!req)
 		goto fail;
 	req->complete = adb_complete_out;
 	dev->rx_req = req;
 
 	for (i = 0; i < TX_REQ_MAX; i++) {
-		req = adb_request_new(dev->ep_in, BULK_BUFFER_SIZE);
+		req = adb_request_new(dev->ep_in, ADB_BULK_BUFFER_SIZE);
 		if (!req)
 			goto fail;
 		req->complete = adb_complete_in;
-		req_put(dev, &dev->tx_idle, req);
+		adb_req_put(dev, &dev->tx_idle, req);
 	}
 
 	return 0;
@@ -273,26 +266,27 @@
 				size_t count, loff_t *pos)
 {
 	struct adb_dev *dev = fp->private_data;
-	struct usb_composite_dev *cdev = dev->cdev;
 	struct usb_request *req;
 	int r = count, xfer;
 	int ret;
 
-	DBG(cdev, "adb_read(%d)\n", count);
+	pr_debug("adb_read(%d)\n", count);
+	if (!_adb_dev)
+		return -ENODEV;
 
-	if (count > BULK_BUFFER_SIZE)
+	if (count > ADB_BULK_BUFFER_SIZE)
 		return -EINVAL;
 
-	if (_lock(&dev->read_excl))
+	if (adb_lock(&dev->read_excl))
 		return -EBUSY;
 
 	/* we will block until we're online */
 	while (!(dev->online || dev->error)) {
-		DBG(cdev, "adb_read: waiting for online state\n");
+		pr_debug("adb_read: waiting for online state\n");
 		ret = wait_event_interruptible(dev->read_wq,
 				(dev->online || dev->error));
 		if (ret < 0) {
-			_unlock(&dev->read_excl);
+			adb_unlock(&dev->read_excl);
 			return ret;
 		}
 	}
@@ -308,12 +302,12 @@
 	dev->rx_done = 0;
 	ret = usb_ep_queue(dev->ep_out, req, GFP_ATOMIC);
 	if (ret < 0) {
-		DBG(cdev, "adb_read: failed to queue req %p (%d)\n", req, ret);
+		pr_debug("adb_read: failed to queue req %p (%d)\n", req, ret);
 		r = -EIO;
 		dev->error = 1;
 		goto done;
 	} else {
-		DBG(cdev, "rx %p queue\n", req);
+		pr_debug("rx %p queue\n", req);
 	}
 
 	/* wait for a request to complete */
@@ -329,16 +323,17 @@
 		if (req->actual == 0)
 			goto requeue_req;
 
-		DBG(cdev, "rx %p %d\n", req, req->actual);
+		pr_debug("rx %p %d\n", req, req->actual);
 		xfer = (req->actual < count) ? req->actual : count;
 		if (copy_to_user(buf, req->buf, xfer))
 			r = -EFAULT;
+
 	} else
 		r = -EIO;
 
 done:
-	_unlock(&dev->read_excl);
-	DBG(cdev, "adb_read returning %d\n", r);
+	adb_unlock(&dev->read_excl);
+	pr_debug("adb_read returning %d\n", r);
 	return r;
 }
 
@@ -346,19 +341,20 @@
 				 size_t count, loff_t *pos)
 {
 	struct adb_dev *dev = fp->private_data;
-	struct usb_composite_dev *cdev = dev->cdev;
 	struct usb_request *req = 0;
 	int r = count, xfer;
 	int ret;
 
-	DBG(cdev, "adb_write(%d)\n", count);
+	if (!_adb_dev)
+		return -ENODEV;
+	pr_debug("adb_write(%d)\n", count);
 
-	if (_lock(&dev->write_excl))
+	if (adb_lock(&dev->write_excl))
 		return -EBUSY;
 
 	while (count > 0) {
 		if (dev->error) {
-			DBG(cdev, "adb_write dev->error\n");
+			pr_debug("adb_write dev->error\n");
 			r = -EIO;
 			break;
 		}
@@ -366,7 +362,7 @@
 		/* get an idle tx request to use */
 		req = 0;
 		ret = wait_event_interruptible(dev->write_wq,
-			((req = req_get(dev, &dev->tx_idle)) || dev->error));
+			(req = adb_req_get(dev, &dev->tx_idle)) || dev->error);
 
 		if (ret < 0) {
 			r = ret;
@@ -374,8 +370,8 @@
 		}
 
 		if (req != 0) {
-			if (count > BULK_BUFFER_SIZE)
-				xfer = BULK_BUFFER_SIZE;
+			if (count > ADB_BULK_BUFFER_SIZE)
+				xfer = ADB_BULK_BUFFER_SIZE;
 			else
 				xfer = count;
 			if (copy_from_user(req->buf, buf, xfer)) {
@@ -386,7 +382,7 @@
 			req->length = xfer;
 			ret = usb_ep_queue(dev->ep_in, req, GFP_ATOMIC);
 			if (ret < 0) {
-				DBG(cdev, "adb_write: xfer error %d\n", ret);
+				pr_debug("adb_write: xfer error %d\n", ret);
 				dev->error = 1;
 				r = -EIO;
 				break;
@@ -401,17 +397,20 @@
 	}
 
 	if (req)
-		req_put(dev, &dev->tx_idle, req);
+		adb_req_put(dev, &dev->tx_idle, req);
 
-	_unlock(&dev->write_excl);
-	DBG(cdev, "adb_write returning %d\n", r);
+	adb_unlock(&dev->write_excl);
+	pr_debug("adb_write returning %d\n", r);
 	return r;
 }
 
 static int adb_open(struct inode *ip, struct file *fp)
 {
 	printk(KERN_INFO "adb_open\n");
-	if (_lock(&_adb_dev->open_excl))
+	if (!_adb_dev)
+		return -ENODEV;
+
+	if (adb_lock(&_adb_dev->open_excl))
 		return -EBUSY;
 
 	fp->private_data = _adb_dev;
@@ -425,7 +424,7 @@
 static int adb_release(struct inode *ip, struct file *fp)
 {
 	printk(KERN_INFO "adb_release\n");
-	_unlock(&_adb_dev->open_excl);
+	adb_unlock(&_adb_dev->open_excl);
 	return 0;
 }
 
@@ -440,48 +439,18 @@
 
 static struct miscdevice adb_device = {
 	.minor = MISC_DYNAMIC_MINOR,
-	.name = shortname,
+	.name = adb_shortname,
 	.fops = &adb_fops,
 };
 
-static int adb_enable_open(struct inode *ip, struct file *fp)
-{
-	if (atomic_inc_return(&adb_enable_excl) != 1) {
-		atomic_dec(&adb_enable_excl);
-		return -EBUSY;
-	}
 
-	printk(KERN_INFO "enabling adb\n");
-	android_enable_function(&_adb_dev->function, 1);
 
-	return 0;
-}
-
-static int adb_enable_release(struct inode *ip, struct file *fp)
-{
-	printk(KERN_INFO "disabling adb\n");
-	android_enable_function(&_adb_dev->function, 0);
-	atomic_dec(&adb_enable_excl);
-	return 0;
-}
-
-static const struct file_operations adb_enable_fops = {
-	.owner =   THIS_MODULE,
-	.open =    adb_enable_open,
-	.release = adb_enable_release,
-};
-
-static struct miscdevice adb_enable_device = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "android_adb_enable",
-	.fops = &adb_enable_fops,
-};
 
 static int
 adb_function_bind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct usb_composite_dev *cdev = c->cdev;
-	struct adb_dev	*dev = func_to_dev(f);
+	struct adb_dev	*dev = func_to_adb(f);
 	int			id;
 	int			ret;
 
@@ -495,7 +464,7 @@
 	adb_interface_desc.bInterfaceNumber = id;
 
 	/* allocate endpoints */
-	ret = create_bulk_endpoints(dev, &adb_fullspeed_in_desc,
+	ret = adb_create_bulk_endpoints(dev, &adb_fullspeed_in_desc,
 			&adb_fullspeed_out_desc);
 	if (ret)
 		return ret;
@@ -517,29 +486,24 @@
 static void
 adb_function_unbind(struct usb_configuration *c, struct usb_function *f)
 {
-	struct adb_dev	*dev = func_to_dev(f);
+	struct adb_dev	*dev = func_to_adb(f);
 	struct usb_request *req;
 
-	spin_lock_irq(&dev->lock);
-
-	adb_request_free(dev->rx_req, dev->ep_out);
-	while ((req = req_get(dev, &dev->tx_idle)))
-		adb_request_free(req, dev->ep_in);
 
 	dev->online = 0;
 	dev->error = 1;
-	spin_unlock_irq(&dev->lock);
 
-	misc_deregister(&adb_device);
-	misc_deregister(&adb_enable_device);
-	kfree(_adb_dev);
-	_adb_dev = NULL;
+	wake_up(&dev->read_wq);
+
+	adb_request_free(dev->rx_req, dev->ep_out);
+	while ((req = adb_req_get(dev, &dev->tx_idle)))
+		adb_request_free(req, dev->ep_in);
 }
 
 static int adb_function_set_alt(struct usb_function *f,
 		unsigned intf, unsigned alt)
 {
-	struct adb_dev	*dev = func_to_dev(f);
+	struct adb_dev	*dev = func_to_adb(f);
 	struct usb_composite_dev *cdev = f->config->cdev;
 	int ret;
 
@@ -567,10 +531,10 @@
 
 static void adb_function_disable(struct usb_function *f)
 {
-	struct adb_dev	*dev = func_to_dev(f);
+	struct adb_dev	*dev = func_to_adb(f);
 	struct usb_composite_dev	*cdev = dev->cdev;
 
-	DBG(cdev, "adb_function_disable\n");
+	DBG(cdev, "adb_function_disable cdev %p\n", cdev);
 	dev->online = 0;
 	dev->error = 1;
 	usb_ep_disable(dev->ep_in);
@@ -584,11 +548,27 @@
 
 static int adb_bind_config(struct usb_configuration *c)
 {
-	struct adb_dev *dev;
-	int ret;
+	struct adb_dev *dev = _adb_dev;
 
 	printk(KERN_INFO "adb_bind_config\n");
 
+	dev->cdev = c->cdev;
+	dev->function.name = "adb";
+	dev->function.descriptors = fs_adb_descs;
+	dev->function.hs_descriptors = hs_adb_descs;
+	dev->function.bind = adb_function_bind;
+	dev->function.unbind = adb_function_unbind;
+	dev->function.set_alt = adb_function_set_alt;
+	dev->function.disable = adb_function_disable;
+
+	return usb_add_function(c, &dev->function);
+}
+
+static int adb_setup(void)
+{
+	struct adb_dev *dev;
+	int ret;
+
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
@@ -604,53 +584,24 @@
 
 	INIT_LIST_HEAD(&dev->tx_idle);
 
-	dev->cdev = c->cdev;
-	dev->function.name = "adb";
-	dev->function.descriptors = fs_adb_descs;
-	dev->function.hs_descriptors = hs_adb_descs;
-	dev->function.bind = adb_function_bind;
-	dev->function.unbind = adb_function_unbind;
-	dev->function.set_alt = adb_function_set_alt;
-	dev->function.disable = adb_function_disable;
-
-	/* start disabled */
-	dev->function.disabled = 1;
-
-	/* _adb_dev must be set before calling usb_gadget_register_driver */
 	_adb_dev = dev;
 
 	ret = misc_register(&adb_device);
 	if (ret)
-		goto err1;
-	ret = misc_register(&adb_enable_device);
-	if (ret)
-		goto err2;
-
-	ret = usb_add_function(c, &dev->function);
-	if (ret)
-		goto err3;
+		goto err;
 
 	return 0;
 
-err3:
-	misc_deregister(&adb_enable_device);
-err2:
-	misc_deregister(&adb_device);
-err1:
+err:
 	kfree(dev);
 	printk(KERN_ERR "adb gadget driver failed to initialize\n");
 	return ret;
 }
 
-static struct android_usb_function adb_function = {
-	.name = "adb",
-	.bind_config = adb_bind_config,
-};
-
-static int __init init(void)
+static void adb_cleanup(void)
 {
-	printk(KERN_INFO "f_adb init\n");
-	android_register_function(&adb_function);
-	return 0;
+	misc_deregister(&adb_device);
+
+	kfree(_adb_dev);
+	_adb_dev = NULL;
 }
-module_init(init);
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a296cd8..5440c6d 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -297,12 +297,6 @@
 
 #include "gadget_chips.h"
 
-#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
-#include <linux/usb/android_composite.h>
-#include <linux/platform_device.h>
-
-#define FUNCTION_NAME		"usb_mass_storage"
-#endif
 
 /*------------------------------------------------------------------------*/
 
@@ -438,10 +432,6 @@
 	u16 release;
 
 	char			can_stall;
-
-#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
-	struct platform_device *pdev;
-#endif
 };
 
 struct fsg_dev {
@@ -2790,13 +2780,7 @@
 		curlun->initially_ro = curlun->ro;
 		curlun->removable = lcfg->removable;
 		curlun->dev.release = fsg_lun_release;
-
-#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
-		/* use "usb_mass_storage" platform device as parent */
-		curlun->dev.parent = &cfg->pdev->dev;
-#else
 		curlun->dev.parent = &gadget->dev;
-#endif
 		/* curlun->dev.driver = &fsg_driver.driver; XXX */
 		dev_set_drvdata(&curlun->dev, &common->filesem);
 		dev_set_name(&curlun->dev,
@@ -3068,11 +3052,7 @@
 	if (unlikely(!fsg))
 		return -ENOMEM;
 
-#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
-	fsg->function.name        = FUNCTION_NAME;
-#else
-	fsg->function.name        = FSG_DRIVER_DESC;
-#endif
+	fsg->function.name        = "mass_storage";
 	fsg->function.strings     = fsg_strings_array;
 	fsg->function.bind        = fsg_bind;
 	fsg->function.unbind      = fsg_unbind;
@@ -3198,63 +3178,3 @@
 	return fsg_common_init(common, cdev, &cfg);
 }
 
-#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
-
-static struct fsg_config fsg_cfg;
-
-static int fsg_probe(struct platform_device *pdev)
-{
-	struct usb_mass_storage_platform_data *pdata = pdev->dev.platform_data;
-	int i, nluns;
-
-	printk(KERN_INFO "fsg_probe pdev: %p, pdata: %p\n", pdev, pdata);
-	if (!pdata)
-		return -1;
-
-	nluns = pdata->nluns;
-	if (nluns > FSG_MAX_LUNS)
-		nluns = FSG_MAX_LUNS;
-	fsg_cfg.nluns = nluns;
-	for (i = 0; i < nluns; i++)
-		fsg_cfg.luns[i].removable = 1;
-
-	fsg_cfg.vendor_name = pdata->vendor;
-	fsg_cfg.product_name = pdata->product;
-	fsg_cfg.release = pdata->release;
-	fsg_cfg.can_stall = 0;
-	fsg_cfg.pdev = pdev;
-
-	return 0;
-}
-
-static struct platform_driver fsg_platform_driver = {
-	.driver = { .name = FUNCTION_NAME, },
-	.probe = fsg_probe,
-};
-
-int mass_storage_bind_config(struct usb_configuration *c)
-{
-	struct fsg_common *common = fsg_common_init(NULL, c->cdev, &fsg_cfg);
-	if (IS_ERR(common))
-		return -1;
-	return fsg_add(c->cdev, c, common);
-}
-
-static struct android_usb_function mass_storage_function = {
-	.name = FUNCTION_NAME,
-	.bind_config = mass_storage_bind_config,
-};
-
-static int __init init(void)
-{
-	int		rc;
-	printk(KERN_INFO "f_mass_storage init\n");
-	rc = platform_driver_register(&fsg_platform_driver);
-	if (rc != 0)
-		return rc;
-	android_register_function(&mass_storage_function);
-	return 0;
-}module_init(init);
-
-#endif /* CONFIG_USB_ANDROID_MASS_STORAGE */
-
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 92dd89b..c892ec8 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -34,10 +34,9 @@
 #include <linux/usb.h>
 #include <linux/usb_usual.h>
 #include <linux/usb/ch9.h>
-#include <linux/usb/android_composite.h>
 #include <linux/usb/f_mtp.h>
 
-#define BULK_BUFFER_SIZE           16384
+#define MTP_BULK_BUFFER_SIZE       16384
 #define INTR_BUFFER_SIZE           28
 
 /* String IDs */
@@ -67,7 +66,7 @@
 #define MTP_RESPONSE_OK             0x2001
 #define MTP_RESPONSE_DEVICE_BUSY    0x2019
 
-static const char shortname[] = "mtp_usb";
+static const char mtp_shortname[] = "mtp_usb";
 
 struct mtp_dev {
 	struct usb_function function;
@@ -273,7 +272,7 @@
 /* temporary variable used between mtp_open() and mtp_gadget_bind() */
 static struct mtp_dev *_mtp_dev;
 
-static inline struct mtp_dev *func_to_dev(struct usb_function *f)
+static inline struct mtp_dev *func_to_mtp(struct usb_function *f)
 {
 	return container_of(f, struct mtp_dev, function);
 }
@@ -302,7 +301,7 @@
 	}
 }
 
-static inline int _lock(atomic_t *excl)
+static inline int mtp_lock(atomic_t *excl)
 {
 	if (atomic_inc_return(excl) == 1) {
 		return 0;
@@ -312,13 +311,13 @@
 	}
 }
 
-static inline void _unlock(atomic_t *excl)
+static inline void mtp_unlock(atomic_t *excl)
 {
 	atomic_dec(excl);
 }
 
 /* add a request to the tail of a list */
-static void req_put(struct mtp_dev *dev, struct list_head *head,
+static void mtp_req_put(struct mtp_dev *dev, struct list_head *head,
 		struct usb_request *req)
 {
 	unsigned long flags;
@@ -329,7 +328,8 @@
 }
 
 /* remove a request from the head of a list */
-static struct usb_request *req_get(struct mtp_dev *dev, struct list_head *head)
+static struct usb_request
+*mtp_req_get(struct mtp_dev *dev, struct list_head *head)
 {
 	unsigned long flags;
 	struct usb_request *req;
@@ -352,7 +352,7 @@
 	if (req->status != 0)
 		dev->state = STATE_ERROR;
 
-	req_put(dev, &dev->tx_idle, req);
+	mtp_req_put(dev, &dev->tx_idle, req);
 
 	wake_up(&dev->write_wq);
 }
@@ -379,7 +379,7 @@
 		dev->state = STATE_ERROR;
 }
 
-static int __init create_bulk_endpoints(struct mtp_dev *dev,
+static int mtp_create_bulk_endpoints(struct mtp_dev *dev,
 				struct usb_endpoint_descriptor *in_desc,
 				struct usb_endpoint_descriptor *out_desc,
 				struct usb_endpoint_descriptor *intr_desc)
@@ -429,14 +429,14 @@
 
 	/* now allocate requests for our endpoints */
 	for (i = 0; i < TX_REQ_MAX; i++) {
-		req = mtp_request_new(dev->ep_in, BULK_BUFFER_SIZE);
+		req = mtp_request_new(dev->ep_in, MTP_BULK_BUFFER_SIZE);
 		if (!req)
 			goto fail;
 		req->complete = mtp_complete_in;
-		req_put(dev, &dev->tx_idle, req);
+		mtp_req_put(dev, &dev->tx_idle, req);
 	}
 	for (i = 0; i < RX_REQ_MAX; i++) {
-		req = mtp_request_new(dev->ep_out, BULK_BUFFER_SIZE);
+		req = mtp_request_new(dev->ep_out, MTP_BULK_BUFFER_SIZE);
 		if (!req)
 			goto fail;
 		req->complete = mtp_complete_out;
@@ -466,7 +466,7 @@
 
 	DBG(cdev, "mtp_read(%d)\n", count);
 
-	if (count > BULK_BUFFER_SIZE)
+	if (count > MTP_BULK_BUFFER_SIZE)
 		return -EINVAL;
 
 	/* we will block until we're online */
@@ -579,15 +579,15 @@
 		/* get an idle tx request to use */
 		req = 0;
 		ret = wait_event_interruptible(dev->write_wq,
-			((req = req_get(dev, &dev->tx_idle))
+			((req = mtp_req_get(dev, &dev->tx_idle))
 				|| dev->state != STATE_BUSY));
 		if (!req) {
 			r = ret;
 			break;
 		}
 
-		if (count > BULK_BUFFER_SIZE)
-			xfer = BULK_BUFFER_SIZE;
+		if (count > MTP_BULK_BUFFER_SIZE)
+			xfer = MTP_BULK_BUFFER_SIZE;
 		else
 			xfer = count;
 		if (xfer && copy_from_user(req->buf, buf, xfer)) {
@@ -611,7 +611,7 @@
 	}
 
 	if (req)
-		req_put(dev, &dev->tx_idle, req);
+		mtp_req_put(dev, &dev->tx_idle, req);
 
 	spin_lock_irq(&dev->lock);
 	if (dev->state == STATE_CANCELED)
@@ -659,7 +659,7 @@
 		/* get an idle tx request to use */
 		req = 0;
 		ret = wait_event_interruptible(dev->write_wq,
-			(req = req_get(dev, &dev->tx_idle))
+			(req = mtp_req_get(dev, &dev->tx_idle))
 			|| dev->state != STATE_BUSY);
 		if (dev->state == STATE_CANCELED) {
 			r = -ECANCELED;
@@ -670,8 +670,8 @@
 			break;
 		}
 
-		if (count > BULK_BUFFER_SIZE)
-			xfer = BULK_BUFFER_SIZE;
+		if (count > MTP_BULK_BUFFER_SIZE)
+			xfer = MTP_BULK_BUFFER_SIZE;
 		else
 			xfer = count;
 		ret = vfs_read(filp, req->buf, xfer, &offset);
@@ -697,7 +697,7 @@
 	}
 
 	if (req)
-		req_put(dev, &dev->tx_idle, req);
+		mtp_req_put(dev, &dev->tx_idle, req);
 
 	DBG(cdev, "send_file_work returning %d\n", r);
 	/* write the result */
@@ -731,8 +731,8 @@
 			read_req = dev->rx_req[cur_buf];
 			cur_buf = (cur_buf + 1) % RX_REQ_MAX;
 
-			read_req->length = (count > BULK_BUFFER_SIZE
-					? BULK_BUFFER_SIZE : count);
+			read_req->length = (count > MTP_BULK_BUFFER_SIZE
+					? MTP_BULK_BUFFER_SIZE : count);
 			dev->rx_done = 0;
 			ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
 			if (ret < 0) {
@@ -824,7 +824,7 @@
 	struct file *filp = NULL;
 	int ret = -EINVAL;
 
-	if (_lock(&dev->ioctl_excl))
+	if (mtp_lock(&dev->ioctl_excl))
 		return -EBUSY;
 
 	switch (code) {
@@ -922,7 +922,7 @@
 		dev->state = STATE_READY;
 	spin_unlock_irq(&dev->lock);
 out:
-	_unlock(&dev->ioctl_excl);
+	mtp_unlock(&dev->ioctl_excl);
 	DBG(dev->cdev, "ioctl returning %d\n", ret);
 	return ret;
 }
@@ -930,7 +930,7 @@
 static int mtp_open(struct inode *ip, struct file *fp)
 {
 	printk(KERN_INFO "mtp_open\n");
-	if (_lock(&_mtp_dev->open_excl))
+	if (mtp_lock(&_mtp_dev->open_excl))
 		return -EBUSY;
 
 	/* clear any error condition */
@@ -945,7 +945,7 @@
 {
 	printk(KERN_INFO "mtp_release\n");
 
-	_unlock(&_mtp_dev->open_excl);
+	mtp_unlock(&_mtp_dev->open_excl);
 	return 0;
 }
 
@@ -961,15 +961,52 @@
 
 static struct miscdevice mtp_device = {
 	.minor = MISC_DYNAMIC_MINOR,
-	.name = shortname,
+	.name = mtp_shortname,
 	.fops = &mtp_fops,
 };
 
+static int mtp_ctrlrequest(struct usb_composite_dev *cdev,
+				const struct usb_ctrlrequest *ctrl)
+{
+	struct mtp_dev *dev = _mtp_dev;
+	int	value = -EOPNOTSUPP;
+	u16	w_index = le16_to_cpu(ctrl->wIndex);
+	u16	w_value = le16_to_cpu(ctrl->wValue);
+	u16	w_length = le16_to_cpu(ctrl->wLength);
+
+	VDBG(cdev, "mtp_ctrlrequest "
+			"%02x.%02x v%04x i%04x l%u\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			w_value, w_index, w_length);
+
+	/* Handle MTP OS string */
+	if (dev->interface_mode == MTP_INTERFACE_MODE_MTP
+			&& ctrl->bRequestType ==
+			(USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE)
+			&& ctrl->bRequest == USB_REQ_GET_DESCRIPTOR
+			&& (w_value >> 8) == USB_DT_STRING
+			&& (w_value & 0xFF) == MTP_OS_STRING_ID) {
+		value = (w_length < sizeof(mtp_os_string)
+				? w_length : sizeof(mtp_os_string));
+		memcpy(cdev->req->buf, mtp_os_string, value);
+	}
+	/* respond with data transfer or status phase? */
+	if (value >= 0) {
+		int rc;
+		cdev->req->zero = value < w_length;
+		cdev->req->length = value;
+		rc = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC);
+		if (rc < 0)
+			ERROR(cdev, "%s setup response queue error\n", __func__);
+	}
+	return value;
+}
+
 static int
 mtp_function_bind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct usb_composite_dev *cdev = c->cdev;
-	struct mtp_dev	*dev = func_to_dev(f);
+	struct mtp_dev	*dev = func_to_mtp(f);
 	int			id;
 	int			ret;
 
@@ -983,7 +1020,7 @@
 	mtp_interface_desc.bInterfaceNumber = id;
 
 	/* allocate endpoints */
-	ret = create_bulk_endpoints(dev, &mtp_fullspeed_in_desc,
+	ret = mtp_create_bulk_endpoints(dev, &mtp_fullspeed_in_desc,
 			&mtp_fullspeed_out_desc, &mtp_intr_desc);
 	if (ret)
 		return ret;
@@ -1005,28 +1042,22 @@
 static void
 mtp_function_unbind(struct usb_configuration *c, struct usb_function *f)
 {
-	struct mtp_dev	*dev = func_to_dev(f);
+	struct mtp_dev	*dev = func_to_mtp(f);
 	struct usb_request *req;
 	int i;
 
-	spin_lock_irq(&dev->lock);
-	while ((req = req_get(dev, &dev->tx_idle)))
+	while ((req = mtp_req_get(dev, &dev->tx_idle)))
 		mtp_request_free(req, dev->ep_in);
 	for (i = 0; i < RX_REQ_MAX; i++)
 		mtp_request_free(dev->rx_req[i], dev->ep_out);
 	mtp_request_free(dev->intr_req, dev->ep_intr);
 	dev->state = STATE_OFFLINE;
-	spin_unlock_irq(&dev->lock);
-
-	misc_deregister(&mtp_device);
-	kfree(_mtp_dev);
-	_mtp_dev = NULL;
 }
 
 static int mtp_function_setup(struct usb_function *f,
 					const struct usb_ctrlrequest *ctrl)
 {
-	struct mtp_dev	*dev = func_to_dev(f);
+	struct mtp_dev	*dev = func_to_mtp(f);
 	struct usb_composite_dev *cdev = dev->cdev;
 	int	value = -EOPNOTSUPP;
 	u16	w_index = le16_to_cpu(ctrl->wIndex);
@@ -1034,28 +1065,11 @@
 	u16	w_length = le16_to_cpu(ctrl->wLength);
 	unsigned long	flags;
 
-	/* do nothing if we are disabled */
-	if (dev->function.disabled)
-		return value;
-
 	VDBG(cdev, "mtp_function_setup "
 			"%02x.%02x v%04x i%04x l%u\n",
 			ctrl->bRequestType, ctrl->bRequest,
 			w_value, w_index, w_length);
 
-	/* Handle MTP OS string */
-	if (dev->interface_mode == MTP_INTERFACE_MODE_MTP
-			&& ctrl->bRequestType ==
-			(USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE)
-			&& ctrl->bRequest == USB_REQ_GET_DESCRIPTOR
-			&& (w_value >> 8) == USB_DT_STRING
-			&& (w_value & 0xFF) == MTP_OS_STRING_ID) {
-		value = (w_length < sizeof(mtp_os_string)
-				? w_length : sizeof(mtp_os_string));
-		memcpy(cdev->req->buf, mtp_os_string, value);
-		/* return here since composite.c will send for us */
-		return value;
-	}
 	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
 		/* Handle MTP OS descriptor */
 		DBG(cdev, "vendor request: %d index: %d value: %d length: %d\n",
@@ -1135,7 +1149,7 @@
 static int mtp_function_set_alt(struct usb_function *f,
 		unsigned intf, unsigned alt)
 {
-	struct mtp_dev	*dev = func_to_dev(f);
+	struct mtp_dev	*dev = func_to_mtp(f);
 	struct usb_composite_dev *cdev = f->config->cdev;
 	int ret;
 
@@ -1169,7 +1183,7 @@
 
 static void mtp_function_disable(struct usb_function *f)
 {
-	struct mtp_dev	*dev = func_to_dev(f);
+	struct mtp_dev	*dev = func_to_mtp(f);
 	struct usb_composite_dev	*cdev = dev->cdev;
 
 	DBG(cdev, "mtp_function_disable\n");
@@ -1186,15 +1200,11 @@
 
 static int mtp_bind_config(struct usb_configuration *c)
 {
-	struct mtp_dev *dev;
+	struct mtp_dev *dev = _mtp_dev;
 	int ret = 0;
 
 	printk(KERN_INFO "mtp_bind_config\n");
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
-		return -ENOMEM;
-
 	/* allocate a string ID for our interface */
 	if (mtp_string_defs[INTERFACE_STRING_INDEX].id == 0) {
 		ret = usb_string_id(c->cdev);
@@ -1204,19 +1214,6 @@
 		mtp_interface_desc.iInterface = ret;
 	}
 
-	spin_lock_init(&dev->lock);
-	init_waitqueue_head(&dev->read_wq);
-	init_waitqueue_head(&dev->write_wq);
-	atomic_set(&dev->open_excl, 0);
-	atomic_set(&dev->ioctl_excl, 0);
-	INIT_LIST_HEAD(&dev->tx_idle);
-
-	dev->wq = create_singlethread_workqueue("f_mtp");
-	if (!dev->wq)
-		goto err1;
-	INIT_WORK(&dev->send_file_work, send_file_work);
-	INIT_WORK(&dev->receive_file_work, receive_file_work);
-
 	dev->cdev = c->cdev;
 	dev->function.name = "mtp";
 	dev->function.strings = mtp_strings,
@@ -1231,38 +1228,59 @@
 	/* MTP mode by default */
 	dev->interface_mode = MTP_INTERFACE_MODE_MTP;
 
-	/* _mtp_dev must be set before calling usb_gadget_register_driver */
+	return usb_add_function(c, &dev->function);
+}
+
+static int mtp_setup(void)
+{
+	struct mtp_dev *dev;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	spin_lock_init(&dev->lock);
+	init_waitqueue_head(&dev->read_wq);
+	init_waitqueue_head(&dev->write_wq);
+	atomic_set(&dev->open_excl, 0);
+	atomic_set(&dev->ioctl_excl, 0);
+	INIT_LIST_HEAD(&dev->tx_idle);
+
+	dev->wq = create_singlethread_workqueue("f_mtp");
+	if (!dev->wq) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+	INIT_WORK(&dev->send_file_work, send_file_work);
+	INIT_WORK(&dev->receive_file_work, receive_file_work);
+
 	_mtp_dev = dev;
 
 	ret = misc_register(&mtp_device);
 	if (ret)
-		goto err1;
-
-	ret = usb_add_function(c, &dev->function);
-	if (ret)
 		goto err2;
 
 	return 0;
 
 err2:
-	misc_deregister(&mtp_device);
+	destroy_workqueue(dev->wq);
 err1:
-	if (dev->wq)
-		destroy_workqueue(dev->wq);
+	_mtp_dev = NULL;
 	kfree(dev);
 	printk(KERN_ERR "mtp gadget driver failed to initialize\n");
 	return ret;
 }
 
-static struct android_usb_function mtp_function = {
-	.name = "mtp",
-	.bind_config = mtp_bind_config,
-};
-
-static int __init init(void)
+static void mtp_cleanup(void)
 {
-	printk(KERN_INFO "f_mtp init\n");
-	android_register_function(&mtp_function);
-	return 0;
+	struct mtp_dev *dev = _mtp_dev;
+
+	if (!dev)
+		return;
+
+	misc_deregister(&mtp_device);
+	destroy_workqueue(dev->wq);
+	_mtp_dev = NULL;
+	kfree(dev);
 }
-module_init(init);
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 761a789..d03b11b 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/etherdevice.h>
-#include <linux/usb/android_composite.h>
 
 #include <asm/atomic.h>
 
@@ -87,8 +86,11 @@
 	struct gether			port;
 	u8				ctrl_id, data_id;
 	u8				ethaddr[ETH_ALEN];
+	u32				vendorID;
+	const char			*manufacturer;
 	int				config;
 
+
 	struct rndis_ep_descs		fs;
 	struct rndis_ep_descs		hs;
 
@@ -130,16 +132,9 @@
 	/* .bInterfaceNumber = DYNAMIC */
 	/* status endpoint is optional; this could be patched later */
 	.bNumEndpoints =	1,
-#ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS
-	/* "Wireless" RNDIS; auto-detected by Windows */
-	.bInterfaceClass =	USB_CLASS_WIRELESS_CONTROLLER,
-	.bInterfaceSubClass =	0x01,
-	.bInterfaceProtocol =	0x03,
-#else
 	.bInterfaceClass =	USB_CLASS_COMM,
 	.bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
 	.bInterfaceProtocol =   USB_CDC_ACM_PROTO_VENDOR,
-#endif
 	/* .iInterface = DYNAMIC */
 };
 
@@ -195,19 +190,11 @@
 rndis_iad_descriptor = {
 	.bLength =		sizeof rndis_iad_descriptor,
 	.bDescriptorType =	USB_DT_INTERFACE_ASSOCIATION,
-
 	.bFirstInterface =	0, /* XXX, hardcoded */
 	.bInterfaceCount = 	2,	// control + data
-#ifdef CONFIG_USB_ANDROID_RNDIS_WCEIS
-	/* "Wireless" RNDIS; auto-detected by Windows */
-	.bFunctionClass =	USB_CLASS_WIRELESS_CONTROLLER,
-	.bFunctionSubClass =	0x01,
-	.bFunctionProtocol =	0x03,
-#else
 	.bFunctionClass =	USB_CLASS_COMM,
 	.bFunctionSubClass =	USB_CDC_SUBCLASS_ETHERNET,
 	.bFunctionProtocol =	USB_CDC_ACM_PROTO_VENDOR,
-#endif
 	/* .iFunction = DYNAMIC */
 };
 
@@ -319,10 +306,6 @@
 	NULL,
 };
 
-#ifdef CONFIG_USB_ANDROID_RNDIS
-static struct usb_ether_platform_data *rndis_pdata;
-#endif
-
 /*-------------------------------------------------------------------------*/
 
 static struct sk_buff *rndis_add_header(struct gether *port,
@@ -725,13 +708,9 @@
 	rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0);
 	rndis_set_host_mac(rndis->config, rndis->ethaddr);
 
-#ifdef CONFIG_USB_ANDROID_RNDIS
-	if (rndis_pdata) {
-		if (rndis_set_param_vendor(rndis->config, rndis_pdata->vendorID,
-					rndis_pdata->vendorDescr))
+	if (rndis_set_param_vendor(rndis->config, rndis->vendorID,
+				   rndis->manufacturer))
 			goto fail;
-	}
-#endif
 
 	/* NOTE:  all that is done without knowing or caring about
 	 * the network link ... which is unavailable to this code
@@ -808,7 +787,8 @@
  * for calling @gether_cleanup() before module unload.
  */
 int
-rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				u32 vendorID, const char *manufacturer)
 {
 	struct f_rndis	*rndis;
 	int		status;
@@ -853,6 +833,8 @@
 		goto fail;
 
 	memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
+	rndis->vendorID = vendorID;
+	rndis->manufacturer = manufacturer;
 
 	/* RNDIS activates when the host changes this filter */
 	rndis->port.cdc_filter = 0;
@@ -871,11 +853,6 @@
 	rndis->port.func.setup = rndis_setup;
 	rndis->port.func.disable = rndis_disable;
 
-#ifdef CONFIG_USB_ANDROID_RNDIS
-	/* start disabled */
-	rndis->port.func.disabled = 1;
-#endif
-
 	status = usb_add_function(c, &rndis->port.func);
 	if (status) {
 		kfree(rndis);
@@ -884,54 +861,3 @@
 	}
 	return status;
 }
-
-#ifdef CONFIG_USB_ANDROID_RNDIS
-#include "rndis.c"
-
-static int rndis_probe(struct platform_device *pdev)
-{
-	rndis_pdata = pdev->dev.platform_data;
-	return 0;
-}
-
-static struct platform_driver rndis_platform_driver = {
-	.driver = { .name = "rndis", },
-	.probe = rndis_probe,
-};
-
-int rndis_function_bind_config(struct usb_configuration *c)
-{
-	int ret;
-
-	if (!rndis_pdata) {
-		printk(KERN_ERR "rndis_pdata null in rndis_function_bind_config\n");
-		return -1;
-	}
-
-	printk(KERN_INFO
-		"rndis_function_bind_config MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
-		rndis_pdata->ethaddr[0], rndis_pdata->ethaddr[1],
-		rndis_pdata->ethaddr[2], rndis_pdata->ethaddr[3],
-		rndis_pdata->ethaddr[4], rndis_pdata->ethaddr[5]);
-
-	ret = gether_setup(c->cdev->gadget, rndis_pdata->ethaddr);
-	if (ret == 0)
-		ret = rndis_bind_config(c, rndis_pdata->ethaddr);
-	return ret;
-}
-
-static struct android_usb_function rndis_function = {
-	.name = "rndis",
-	.bind_config = rndis_function_bind_config,
-};
-
-static int __init init(void)
-{
-	printk(KERN_INFO "f_rndis init\n");
-	platform_driver_register(&rndis_platform_driver);
-	android_register_function(&rndis_function);
-	return 0;
-}
-module_init(init);
-
-#endif /* CONFIG_USB_ANDROID_RNDIS */
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
index 2779865..5bb1021 100644
--- a/drivers/usb/gadget/u_ether.h
+++ b/drivers/usb/gadget/u_ether.h
@@ -110,14 +110,16 @@
 int ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
 int eem_bind_config(struct usb_configuration *c);
 
-#if defined(USB_ETH_RNDIS) || defined(CONFIG_USB_ANDROID_RNDIS)
+#ifdef USB_ETH_RNDIS
 
-int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				u32 vendorID, const char *manufacturer);
 
 #else
 
 static inline int
-rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				u32 vendorID, const char *manufacturer)
 {
 	return 0;
 }
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 3dcbeca..3fdcc9a 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1028,7 +1028,7 @@
 
 static struct tty_driver *gs_tty_driver;
 
-static int __init
+static int
 gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
 {
 	struct gs_port	*port;
@@ -1074,7 +1074,7 @@
  *
  * Returns negative errno or zero.
  */
-int __init gserial_setup(struct usb_gadget *g, unsigned count)
+int gserial_setup(struct usb_gadget *g, unsigned count)
 {
 	unsigned			i;
 	struct usb_cdc_line_coding	coding;