Revert: d7022078269b93dc6ee613a0a8519ce2ebe4a726

Accidentally merged without proper testing.

Change-Id: Iea6c3f7cd383357ac657fd15fde08cbab86bf809
Signed-off-by: David Brown <davidb@codeaurora.org>
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 288b570..48f1781 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -110,8 +110,6 @@
 
 source "drivers/usb/core/Kconfig"
 
-source "drivers/usb/dwc3/Kconfig"
-
 source "drivers/usb/mon/Kconfig"
 
 source "drivers/usb/wusbcore/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 0fd0bbd..ef69048 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -6,8 +6,6 @@
 
 obj-$(CONFIG_USB)		+= core/
 
-obj-$(CONFIG_USB_DWC3)		+= dwc3/
-
 obj-$(CONFIG_USB_MON)		+= mon/
 
 obj-$(CONFIG_USB_OTG_UTILS)	+= otg/
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
deleted file mode 100644
index 3c1d67d..0000000
--- a/drivers/usb/dwc3/Kconfig
+++ /dev/null
@@ -1,25 +0,0 @@
-config USB_DWC3
-	tristate "DesignWare USB3 DRD Core Support"
-	depends on (USB || USB_GADGET)
-	select USB_OTG_UTILS
-	help
-	  Say Y or M here if your system has a Dual Role SuperSpeed
-	  USB controller based on the DesignWare USB3 IP Core.
-
-	  If you choose to build this driver is a dynamically linked
-	  module, the module will be called dwc3.ko.
-
-if USB_DWC3
-
-config USB_DWC3_DEBUG
-	bool "Enable Debugging Messages"
-	help
-	  Say Y here to enable debugging messages on DWC3 Driver.
-
-config USB_DWC3_VERBOSE
-	bool "Enable Verbose Debugging Messages"
-	depends on USB_DWC3_DEBUG
-	help
-	  Say Y here to enable verbose debugging messages on DWC3 Driver.
-
-endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
deleted file mode 100644
index 593d1db..0000000
--- a/drivers/usb/dwc3/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-ccflags-$(CONFIG_USB_DWC3_DEBUG)	:= -DDEBUG
-ccflags-$(CONFIG_USB_DWC3_VERBOSE)	+= -DVERBOSE_DEBUG
-
-obj-$(CONFIG_USB_DWC3)			+= dwc3.o
-
-dwc3-y					:= core.o
-
-ifneq ($(CONFIG_USB_GADGET_DWC3),)
-	dwc3-y				+= gadget.o ep0.o
-endif
-
-ifneq ($(CONFIG_DEBUG_FS),)
-	dwc3-y				+= debugfs.o
-endif
-
-##
-# Platform-specific glue layers go here
-#
-# NOTICE: Make sure your glue layer doesn't depend on anything
-# which is arch-specific and that it compiles on all situations.
-#
-# We want to keep this requirement in order to be able to compile
-# the entire driver (with all its glue layers) on several architectures
-# and make sure it compiles fine. This will also help with allmodconfig
-# and allyesconfig builds.
-#
-# The only exception is the PCI glue layer, but that's only because
-# PCI doesn't provide nops if CONFIG_PCI isn't enabled.
-##
-
-obj-$(CONFIG_USB_DWC3)		+= dwc3-omap.o
-
-ifneq ($(CONFIG_PCI),)
-	obj-$(CONFIG_USB_DWC3)		+= dwc3-pci.o
-endif
-
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
deleted file mode 100644
index 717ebc9..0000000
--- a/drivers/usb/dwc3/core.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/**
- * core.c - DesignWare USB3 DRD Controller Core file
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/module.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-#include "debug.h"
-
-/**
- * dwc3_core_soft_reset - Issues core soft reset and PHY reset
- * @dwc: pointer to our context structure
- */
-static void dwc3_core_soft_reset(struct dwc3 *dwc)
-{
-	u32		reg;
-
-	/* Before Resetting PHY, put Core in Reset */
-	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-	reg |= DWC3_GCTL_CORESOFTRESET;
-	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
-	/* Assert USB3 PHY reset */
-	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-	reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
-	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-
-	/* Assert USB2 PHY reset */
-	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-	reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
-	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
-	mdelay(100);
-
-	/* Clear USB3 PHY reset */
-	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-	reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
-	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-
-	/* Clear USB2 PHY reset */
-	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-	reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
-	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
-	/* After PHYs are stable we can take Core out of reset state */
-	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-	reg &= ~DWC3_GCTL_CORESOFTRESET;
-	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-}
-
-/**
- * dwc3_free_one_event_buffer - Frees one event buffer
- * @dwc: Pointer to our controller context structure
- * @evt: Pointer to event buffer to be freed
- */
-static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
-		struct dwc3_event_buffer *evt)
-{
-	dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
-	kfree(evt);
-}
-
-/**
- * dwc3_alloc_one_event_buffer - Allocated one event buffer structure
- * @dwc: Pointer to our controller context structure
- * @length: size of the event buffer
- *
- * Returns a pointer to the allocated event buffer structure on succes
- * otherwise ERR_PTR(errno).
- */
-static struct dwc3_event_buffer *__devinit
-dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
-{
-	struct dwc3_event_buffer	*evt;
-
-	evt = kzalloc(sizeof(*evt), GFP_KERNEL);
-	if (!evt)
-		return ERR_PTR(-ENOMEM);
-
-	evt->dwc	= dwc;
-	evt->length	= length;
-	evt->buf	= dma_alloc_coherent(dwc->dev, length,
-			&evt->dma, GFP_KERNEL);
-	if (!evt->buf) {
-		kfree(evt);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	return evt;
-}
-
-/**
- * dwc3_free_event_buffers - frees all allocated event buffers
- * @dwc: Pointer to our controller context structure
- */
-static void dwc3_free_event_buffers(struct dwc3 *dwc)
-{
-	struct dwc3_event_buffer	*evt;
-	int i;
-
-	for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
-		evt = dwc->ev_buffs[i];
-		if (evt) {
-			dwc3_free_one_event_buffer(dwc, evt);
-			dwc->ev_buffs[i] = NULL;
-		}
-	}
-}
-
-/**
- * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
- * @dwc: Pointer to out controller context structure
- * @num: number of event buffers to allocate
- * @length: size of event buffer
- *
- * Returns 0 on success otherwise negative errno. In error the case, dwc
- * may contain some buffers allocated but not all which were requested.
- */
-static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned num,
-		unsigned length)
-{
-	int			i;
-
-	for (i = 0; i < num; i++) {
-		struct dwc3_event_buffer	*evt;
-
-		evt = dwc3_alloc_one_event_buffer(dwc, length);
-		if (IS_ERR(evt)) {
-			dev_err(dwc->dev, "can't allocate event buffer\n");
-			return PTR_ERR(evt);
-		}
-		dwc->ev_buffs[i] = evt;
-	}
-
-	return 0;
-}
-
-/**
- * dwc3_event_buffers_setup - setup our allocated event buffers
- * @dwc: Pointer to out controller context structure
- *
- * Returns 0 on success otherwise negative errno.
- */
-static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)
-{
-	struct dwc3_event_buffer	*evt;
-	int				n;
-
-	for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
-		evt = dwc->ev_buffs[n];
-		dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
-				evt->buf, (unsigned long long) evt->dma,
-				evt->length);
-
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
-				lower_32_bits(evt->dma));
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
-				upper_32_bits(evt->dma));
-		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
-				evt->length & 0xffff);
-		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
-	}
-
-	return 0;
-}
-
-static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
-{
-	struct dwc3_event_buffer	*evt;
-	int				n;
-
-	for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
-		evt = dwc->ev_buffs[n];
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
-		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0);
-		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
-	}
-}
-
-static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
-{
-	struct dwc3_hwparams	*parms = &dwc->hwparams;
-
-	parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
-	parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
-	parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
-	parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
-	parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
-	parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
-	parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
-	parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
-	parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
-}
-
-/**
- * dwc3_core_init - Low-level initialization of DWC3 Core
- * @dwc: Pointer to our controller context structure
- *
- * Returns 0 on success otherwise negative errno.
- */
-static int __devinit dwc3_core_init(struct dwc3 *dwc)
-{
-	unsigned long		timeout;
-	u32			reg;
-	int			ret;
-
-	reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
-	/* This should read as U3 followed by revision number */
-	if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
-		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
-		ret = -ENODEV;
-		goto err0;
-	}
-	dwc->revision = reg & DWC3_GSNPSREV_MASK;
-
-	dwc3_core_soft_reset(dwc);
-
-	/* issue device SoftReset too */
-	timeout = jiffies + msecs_to_jiffies(500);
-	dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
-	do {
-		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-		if (!(reg & DWC3_DCTL_CSFTRST))
-			break;
-
-		if (time_after(jiffies, timeout)) {
-			dev_err(dwc->dev, "Reset Timed Out\n");
-			ret = -ETIMEDOUT;
-			goto err0;
-		}
-
-		cpu_relax();
-	} while (true);
-
-	ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_NUM,
-			DWC3_EVENT_BUFFERS_SIZE);
-	if (ret) {
-		dev_err(dwc->dev, "failed to allocate event buffers\n");
-		ret = -ENOMEM;
-		goto err1;
-	}
-
-	ret = dwc3_event_buffers_setup(dwc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to setup event buffers\n");
-		goto err1;
-	}
-
-	dwc3_cache_hwparams(dwc);
-
-	return 0;
-
-err1:
-	dwc3_free_event_buffers(dwc);
-
-err0:
-	return ret;
-}
-
-static void dwc3_core_exit(struct dwc3 *dwc)
-{
-	dwc3_event_buffers_cleanup(dwc);
-	dwc3_free_event_buffers(dwc);
-}
-
-#define DWC3_ALIGN_MASK		(16 - 1)
-
-static int __devinit dwc3_probe(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	struct resource		*res;
-	struct dwc3		*dwc;
-	void __iomem		*regs;
-	unsigned int		features = id->driver_data;
-	int			ret = -ENOMEM;
-	int			irq;
-	void			*mem;
-
-	mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
-	if (!mem) {
-		dev_err(&pdev->dev, "not enough memory\n");
-		goto err0;
-	}
-	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
-	dwc->mem = mem;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "missing resource\n");
-		goto err1;
-	}
-
-	res = request_mem_region(res->start, resource_size(res),
-			dev_name(&pdev->dev));
-	if (!res) {
-		dev_err(&pdev->dev, "can't request mem region\n");
-		goto err1;
-	}
-
-	regs = ioremap(res->start, resource_size(res));
-	if (!regs) {
-		dev_err(&pdev->dev, "ioremap failed\n");
-		goto err2;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "missing IRQ\n");
-		goto err3;
-	}
-
-	spin_lock_init(&dwc->lock);
-	platform_set_drvdata(pdev, dwc);
-
-	dwc->regs	= regs;
-	dwc->regs_size	= resource_size(res);
-	dwc->dev	= &pdev->dev;
-	dwc->irq	= irq;
-
-	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
-	pm_runtime_forbid(&pdev->dev);
-
-	ret = dwc3_core_init(dwc);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize core\n");
-		goto err3;
-	}
-
-	if (features & DWC3_HAS_PERIPHERAL) {
-		ret = dwc3_gadget_init(dwc);
-		if (ret) {
-			dev_err(&pdev->dev, "failed to initialized gadget\n");
-			goto err4;
-		}
-	}
-
-	ret = dwc3_debugfs_init(dwc);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize debugfs\n");
-		goto err5;
-	}
-
-	pm_runtime_allow(&pdev->dev);
-
-	return 0;
-
-err5:
-	if (features & DWC3_HAS_PERIPHERAL)
-		dwc3_gadget_exit(dwc);
-
-err4:
-	dwc3_core_exit(dwc);
-
-err3:
-	iounmap(regs);
-
-err2:
-	release_mem_region(res->start, resource_size(res));
-
-err1:
-	kfree(dwc->mem);
-
-err0:
-	return ret;
-}
-
-static int __devexit dwc3_remove(struct platform_device *pdev)
-{
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	struct dwc3	*dwc = platform_get_drvdata(pdev);
-	struct resource	*res;
-	unsigned int	features = id->driver_data;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	pm_runtime_put(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
-
-	dwc3_debugfs_exit(dwc);
-
-	if (features & DWC3_HAS_PERIPHERAL)
-		dwc3_gadget_exit(dwc);
-
-	dwc3_core_exit(dwc);
-	release_mem_region(res->start, resource_size(res));
-	iounmap(dwc->regs);
-	kfree(dwc->mem);
-
-	return 0;
-}
-
-static const struct platform_device_id dwc3_id_table[] __devinitconst = {
-	{
-		.name	= "dwc3-omap",
-		.driver_data = (DWC3_HAS_PERIPHERAL
-			| DWC3_HAS_XHCI
-			| DWC3_HAS_OTG),
-	},
-	{
-		.name	= "dwc3-pci",
-		.driver_data = DWC3_HAS_PERIPHERAL,
-	},
-	{  },	/* Terminating Entry */
-};
-MODULE_DEVICE_TABLE(platform, dwc3_id_table);
-
-static struct platform_driver dwc3_driver = {
-	.probe		= dwc3_probe,
-	.remove		= __devexit_p(dwc3_remove),
-	.driver		= {
-		.name	= "dwc3",
-	},
-	.id_table	= dwc3_id_table,
-};
-
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
-
-static int __devinit dwc3_init(void)
-{
-	return platform_driver_register(&dwc3_driver);
-}
-module_init(dwc3_init);
-
-static void __exit dwc3_exit(void)
-{
-	platform_driver_unregister(&dwc3_driver);
-}
-module_exit(dwc3_exit);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
deleted file mode 100644
index 29a8e16..0000000
--- a/drivers/usb/dwc3/core.h
+++ /dev/null
@@ -1,768 +0,0 @@
-/**
- * core.h - DesignWare USB3 DRD Core Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DRIVERS_USB_DWC3_CORE_H
-#define __DRIVERS_USB_DWC3_CORE_H
-
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/debugfs.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-/* Global constants */
-#define DWC3_ENDPOINTS_NUM	32
-
-#define DWC3_EVENT_BUFFERS_NUM	2
-#define DWC3_EVENT_BUFFERS_SIZE	PAGE_SIZE
-#define DWC3_EVENT_TYPE_MASK	0xfe
-
-#define DWC3_EVENT_TYPE_DEV	0
-#define DWC3_EVENT_TYPE_CARKIT	3
-#define DWC3_EVENT_TYPE_I2C	4
-
-#define DWC3_DEVICE_EVENT_DISCONNECT		0
-#define DWC3_DEVICE_EVENT_RESET			1
-#define DWC3_DEVICE_EVENT_CONNECT_DONE		2
-#define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE	3
-#define DWC3_DEVICE_EVENT_WAKEUP		4
-#define DWC3_DEVICE_EVENT_EOPF			6
-#define DWC3_DEVICE_EVENT_SOF			7
-#define DWC3_DEVICE_EVENT_ERRATIC_ERROR		9
-#define DWC3_DEVICE_EVENT_CMD_CMPL		10
-#define DWC3_DEVICE_EVENT_OVERFLOW		11
-
-#define DWC3_GEVNTCOUNT_MASK	0xfffc
-#define DWC3_GSNPSID_MASK	0xffff0000
-#define DWC3_GSNPSREV_MASK	0xffff
-
-/* Global Registers */
-#define DWC3_GSBUSCFG0		0xc100
-#define DWC3_GSBUSCFG1		0xc104
-#define DWC3_GTXTHRCFG		0xc108
-#define DWC3_GRXTHRCFG		0xc10c
-#define DWC3_GCTL		0xc110
-#define DWC3_GEVTEN		0xc114
-#define DWC3_GSTS		0xc118
-#define DWC3_GSNPSID		0xc120
-#define DWC3_GGPIO		0xc124
-#define DWC3_GUID		0xc128
-#define DWC3_GUCTL		0xc12c
-#define DWC3_GBUSERRADDR0	0xc130
-#define DWC3_GBUSERRADDR1	0xc134
-#define DWC3_GPRTBIMAP0		0xc138
-#define DWC3_GPRTBIMAP1		0xc13c
-#define DWC3_GHWPARAMS0		0xc140
-#define DWC3_GHWPARAMS1		0xc144
-#define DWC3_GHWPARAMS2		0xc148
-#define DWC3_GHWPARAMS3		0xc14c
-#define DWC3_GHWPARAMS4		0xc150
-#define DWC3_GHWPARAMS5		0xc154
-#define DWC3_GHWPARAMS6		0xc158
-#define DWC3_GHWPARAMS7		0xc15c
-#define DWC3_GDBGFIFOSPACE	0xc160
-#define DWC3_GDBGLTSSM		0xc164
-#define DWC3_GPRTBIMAP_HS0	0xc180
-#define DWC3_GPRTBIMAP_HS1	0xc184
-#define DWC3_GPRTBIMAP_FS0	0xc188
-#define DWC3_GPRTBIMAP_FS1	0xc18c
-
-#define DWC3_GUSB2PHYCFG(n)	(0xc200 + (n * 0x04))
-#define DWC3_GUSB2I2CCTL(n)	(0xc240 + (n * 0x04))
-
-#define DWC3_GUSB2PHYACC(n)	(0xc280 + (n * 0x04))
-
-#define DWC3_GUSB3PIPECTL(n)	(0xc2c0 + (n * 0x04))
-
-#define DWC3_GTXFIFOSIZ(n)	(0xc300 + (n * 0x04))
-#define DWC3_GRXFIFOSIZ(n)	(0xc380 + (n * 0x04))
-
-#define DWC3_GEVNTADRLO(n)	(0xc400 + (n * 0x10))
-#define DWC3_GEVNTADRHI(n)	(0xc404 + (n * 0x10))
-#define DWC3_GEVNTSIZ(n)	(0xc408 + (n * 0x10))
-#define DWC3_GEVNTCOUNT(n)	(0xc40c + (n * 0x10))
-
-#define DWC3_GHWPARAMS8		0xc600
-
-/* Device Registers */
-#define DWC3_DCFG		0xc700
-#define DWC3_DCTL		0xc704
-#define DWC3_DEVTEN		0xc708
-#define DWC3_DSTS		0xc70c
-#define DWC3_DGCMDPAR		0xc710
-#define DWC3_DGCMD		0xc714
-#define DWC3_DALEPENA		0xc720
-#define DWC3_DEPCMDPAR2(n)	(0xc800 + (n * 0x10))
-#define DWC3_DEPCMDPAR1(n)	(0xc804 + (n * 0x10))
-#define DWC3_DEPCMDPAR0(n)	(0xc808 + (n * 0x10))
-#define DWC3_DEPCMD(n)		(0xc80c + (n * 0x10))
-
-/* OTG Registers */
-#define DWC3_OCFG		0xcc00
-#define DWC3_OCTL		0xcc04
-#define DWC3_OEVTEN		0xcc08
-#define DWC3_OSTS		0xcc0C
-
-/* Bit fields */
-
-/* Global Configuration Register */
-#define DWC3_GCTL_PWRDNSCALE(n)	(n << 19)
-#define DWC3_GCTL_U2RSTECN	(1 << 16)
-#define DWC3_GCTL_RAMCLKSEL(x)	((x & DWC3_GCTL_CLK_MASK) << 6)
-#define DWC3_GCTL_CLK_BUS	(0)
-#define DWC3_GCTL_CLK_PIPE	(1)
-#define DWC3_GCTL_CLK_PIPEHALF	(2)
-#define DWC3_GCTL_CLK_MASK	(3)
-
-#define DWC3_GCTL_PRTCAPDIR(n)	(n << 12)
-#define DWC3_GCTL_PRTCAP_HOST	1
-#define DWC3_GCTL_PRTCAP_DEVICE	2
-#define DWC3_GCTL_PRTCAP_OTG	3
-
-#define DWC3_GCTL_CORESOFTRESET	(1 << 11)
-#define DWC3_GCTL_SCALEDOWN(n)	(n << 4)
-#define DWC3_GCTL_DISSCRAMBLE	(1 << 3)
-#define DWC3_GCTL_DSBLCLKGTNG	(1 << 0)
-
-/* Global USB2 PHY Configuration Register */
-#define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31)
-#define DWC3_GUSB2PHYCFG_SUSPHY	(1 << 6)
-
-/* Global USB3 PIPE Control Register */
-#define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)
-#define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17)
-
-/* Global HWPARAMS1 Register */
-#define DWC3_GHWPARAMS1_EN_PWROPT(n)	((n & (3 << 24)) >> 24)
-#define DWC3_GHWPARAMS1_EN_PWROPT_NO	0
-#define DWC3_GHWPARAMS1_EN_PWROPT_CLK	1
-
-/* Device Configuration Register */
-#define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
-#define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
-
-#define DWC3_DCFG_SPEED_MASK	(7 << 0)
-#define DWC3_DCFG_SUPERSPEED	(4 << 0)
-#define DWC3_DCFG_HIGHSPEED	(0 << 0)
-#define DWC3_DCFG_FULLSPEED2	(1 << 0)
-#define DWC3_DCFG_LOWSPEED	(2 << 0)
-#define DWC3_DCFG_FULLSPEED1	(3 << 0)
-
-/* Device Control Register */
-#define DWC3_DCTL_RUN_STOP	(1 << 31)
-#define DWC3_DCTL_CSFTRST	(1 << 30)
-#define DWC3_DCTL_LSFTRST	(1 << 29)
-
-#define DWC3_DCTL_HIRD_THRES_MASK	(0x1f << 24)
-#define DWC3_DCTL_HIRD_THRES(n)	(((n) & DWC3_DCTL_HIRD_THRES_MASK) >> 24)
-
-#define DWC3_DCTL_APPL1RES	(1 << 23)
-
-#define DWC3_DCTL_INITU2ENA	(1 << 12)
-#define DWC3_DCTL_ACCEPTU2ENA	(1 << 11)
-#define DWC3_DCTL_INITU1ENA	(1 << 10)
-#define DWC3_DCTL_ACCEPTU1ENA	(1 << 9)
-#define DWC3_DCTL_TSTCTRL_MASK	(0xf << 1)
-
-#define DWC3_DCTL_ULSTCHNGREQ_MASK	(0x0f << 5)
-#define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK)
-
-#define DWC3_DCTL_ULSTCHNG_NO_ACTION	(DWC3_DCTL_ULSTCHNGREQ(0))
-#define DWC3_DCTL_ULSTCHNG_SS_DISABLED	(DWC3_DCTL_ULSTCHNGREQ(4))
-#define DWC3_DCTL_ULSTCHNG_RX_DETECT	(DWC3_DCTL_ULSTCHNGREQ(5))
-#define DWC3_DCTL_ULSTCHNG_SS_INACTIVE	(DWC3_DCTL_ULSTCHNGREQ(6))
-#define DWC3_DCTL_ULSTCHNG_RECOVERY	(DWC3_DCTL_ULSTCHNGREQ(8))
-#define DWC3_DCTL_ULSTCHNG_COMPLIANCE	(DWC3_DCTL_ULSTCHNGREQ(10))
-#define DWC3_DCTL_ULSTCHNG_LOOPBACK	(DWC3_DCTL_ULSTCHNGREQ(11))
-
-/* Device Event Enable Register */
-#define DWC3_DEVTEN_VNDRDEVTSTRCVEDEN	(1 << 12)
-#define DWC3_DEVTEN_EVNTOVERFLOWEN	(1 << 11)
-#define DWC3_DEVTEN_CMDCMPLTEN		(1 << 10)
-#define DWC3_DEVTEN_ERRTICERREN		(1 << 9)
-#define DWC3_DEVTEN_SOFEN		(1 << 7)
-#define DWC3_DEVTEN_EOPFEN		(1 << 6)
-#define DWC3_DEVTEN_WKUPEVTEN		(1 << 4)
-#define DWC3_DEVTEN_ULSTCNGEN		(1 << 3)
-#define DWC3_DEVTEN_CONNECTDONEEN	(1 << 2)
-#define DWC3_DEVTEN_USBRSTEN		(1 << 1)
-#define DWC3_DEVTEN_DISCONNEVTEN	(1 << 0)
-
-/* Device Status Register */
-#define DWC3_DSTS_PWRUPREQ		(1 << 24)
-#define DWC3_DSTS_COREIDLE		(1 << 23)
-#define DWC3_DSTS_DEVCTRLHLT		(1 << 22)
-
-#define DWC3_DSTS_USBLNKST_MASK		(0x0f << 18)
-#define DWC3_DSTS_USBLNKST(n)		(((n) & DWC3_DSTS_USBLNKST_MASK) >> 18)
-
-#define DWC3_DSTS_RXFIFOEMPTY		(1 << 17)
-
-#define DWC3_DSTS_SOFFN_MASK		(0x3ff << 3)
-#define DWC3_DSTS_SOFFN(n)		(((n) & DWC3_DSTS_SOFFN_MASK) >> 3)
-
-#define DWC3_DSTS_CONNECTSPD		(7 << 0)
-
-#define DWC3_DSTS_SUPERSPEED		(4 << 0)
-#define DWC3_DSTS_HIGHSPEED		(0 << 0)
-#define DWC3_DSTS_FULLSPEED2		(1 << 0)
-#define DWC3_DSTS_LOWSPEED		(2 << 0)
-#define DWC3_DSTS_FULLSPEED1		(3 << 0)
-
-/* Device Generic Command Register */
-#define DWC3_DGCMD_SET_LMP		0x01
-#define DWC3_DGCMD_SET_PERIODIC_PAR	0x02
-#define DWC3_DGCMD_XMIT_FUNCTION	0x03
-#define DWC3_DGCMD_SELECTED_FIFO_FLUSH	0x09
-#define DWC3_DGCMD_ALL_FIFO_FLUSH	0x0a
-#define DWC3_DGCMD_SET_ENDPOINT_NRDY	0x0c
-#define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK	0x10
-
-/* Device Endpoint Command Register */
-#define DWC3_DEPCMD_PARAM_SHIFT		16
-#define DWC3_DEPCMD_PARAM(x)		(x << DWC3_DEPCMD_PARAM_SHIFT)
-#define DWC3_DEPCMD_GET_RSC_IDX(x)	((x >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f)
-#define DWC3_DEPCMD_STATUS_MASK		(0x0f << 12)
-#define DWC3_DEPCMD_STATUS(x)		((x & DWC3_DEPCMD_STATUS_MASK) >> 12)
-#define DWC3_DEPCMD_HIPRI_FORCERM	(1 << 11)
-#define DWC3_DEPCMD_CMDACT		(1 << 10)
-#define DWC3_DEPCMD_CMDIOC		(1 << 8)
-
-#define DWC3_DEPCMD_DEPSTARTCFG		(0x09 << 0)
-#define DWC3_DEPCMD_ENDTRANSFER		(0x08 << 0)
-#define DWC3_DEPCMD_UPDATETRANSFER	(0x07 << 0)
-#define DWC3_DEPCMD_STARTTRANSFER	(0x06 << 0)
-#define DWC3_DEPCMD_CLEARSTALL		(0x05 << 0)
-#define DWC3_DEPCMD_SETSTALL		(0x04 << 0)
-#define DWC3_DEPCMD_GETSEQNUMBER	(0x03 << 0)
-#define DWC3_DEPCMD_SETTRANSFRESOURCE	(0x02 << 0)
-#define DWC3_DEPCMD_SETEPCONFIG		(0x01 << 0)
-
-/* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
-#define DWC3_DALEPENA_EP(n)		(1 << n)
-
-#define DWC3_DEPCMD_TYPE_CONTROL	0
-#define DWC3_DEPCMD_TYPE_ISOC		1
-#define DWC3_DEPCMD_TYPE_BULK		2
-#define DWC3_DEPCMD_TYPE_INTR		3
-
-/* Structures */
-
-struct dwc3_trb_hw;
-
-/**
- * struct dwc3_event_buffer - Software event buffer representation
- * @list: a list of event buffers
- * @buf: _THE_ buffer
- * @length: size of this buffer
- * @dma: dma_addr_t
- * @dwc: pointer to DWC controller
- */
-struct dwc3_event_buffer {
-	void			*buf;
-	unsigned		length;
-	unsigned int		lpos;
-
-	dma_addr_t		dma;
-
-	struct dwc3		*dwc;
-};
-
-#define DWC3_EP_FLAG_STALLED	(1 << 0)
-#define DWC3_EP_FLAG_WEDGED	(1 << 1)
-
-#define DWC3_EP_DIRECTION_TX	true
-#define DWC3_EP_DIRECTION_RX	false
-
-#define DWC3_TRB_NUM		32
-#define DWC3_TRB_MASK		(DWC3_TRB_NUM - 1)
-
-/**
- * struct dwc3_ep - device side endpoint representation
- * @endpoint: usb endpoint
- * @request_list: list of requests for this endpoint
- * @req_queued: list of requests on this ep which have TRBs setup
- * @trb_pool: array of transaction buffers
- * @trb_pool_dma: dma address of @trb_pool
- * @free_slot: next slot which is going to be used
- * @busy_slot: first slot which is owned by HW
- * @desc: usb_endpoint_descriptor pointer
- * @dwc: pointer to DWC controller
- * @flags: endpoint flags (wedged, stalled, ...)
- * @current_trb: index of current used trb
- * @number: endpoint number (1 - 15)
- * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
- * @res_trans_idx: Resource transfer index
- * @interval: the intervall on which the ISOC transfer is started
- * @name: a human readable name e.g. ep1out-bulk
- * @direction: true for TX, false for RX
- * @stream_capable: true when streams are enabled
- */
-struct dwc3_ep {
-	struct usb_ep		endpoint;
-	struct list_head	request_list;
-	struct list_head	req_queued;
-
-	struct dwc3_trb_hw	*trb_pool;
-	dma_addr_t		trb_pool_dma;
-	u32			free_slot;
-	u32			busy_slot;
-	const struct usb_endpoint_descriptor *desc;
-	struct dwc3		*dwc;
-
-	unsigned		flags;
-#define DWC3_EP_ENABLED		(1 << 0)
-#define DWC3_EP_STALL		(1 << 1)
-#define DWC3_EP_WEDGE		(1 << 2)
-#define DWC3_EP_BUSY		(1 << 4)
-#define DWC3_EP_PENDING_REQUEST	(1 << 5)
-
-	/* This last one is specific to EP0 */
-#define DWC3_EP0_DIR_IN		(1 << 31)
-
-	unsigned		current_trb;
-
-	u8			number;
-	u8			type;
-	u8			res_trans_idx;
-	u32			interval;
-
-	char			name[20];
-
-	unsigned		direction:1;
-	unsigned		stream_capable:1;
-};
-
-enum dwc3_phy {
-	DWC3_PHY_UNKNOWN = 0,
-	DWC3_PHY_USB3,
-	DWC3_PHY_USB2,
-};
-
-enum dwc3_ep0_next {
-	DWC3_EP0_UNKNOWN = 0,
-	DWC3_EP0_COMPLETE,
-	DWC3_EP0_NRDY_SETUP,
-	DWC3_EP0_NRDY_DATA,
-	DWC3_EP0_NRDY_STATUS,
-};
-
-enum dwc3_ep0_state {
-	EP0_UNCONNECTED		= 0,
-	EP0_SETUP_PHASE,
-	EP0_DATA_PHASE,
-	EP0_STATUS_PHASE,
-};
-
-enum dwc3_link_state {
-	/* In SuperSpeed */
-	DWC3_LINK_STATE_U0		= 0x00, /* in HS, means ON */
-	DWC3_LINK_STATE_U1		= 0x01,
-	DWC3_LINK_STATE_U2		= 0x02, /* in HS, means SLEEP */
-	DWC3_LINK_STATE_U3		= 0x03, /* in HS, means SUSPEND */
-	DWC3_LINK_STATE_SS_DIS		= 0x04,
-	DWC3_LINK_STATE_RX_DET		= 0x05, /* in HS, means Early Suspend */
-	DWC3_LINK_STATE_SS_INACT	= 0x06,
-	DWC3_LINK_STATE_POLL		= 0x07,
-	DWC3_LINK_STATE_RECOV		= 0x08,
-	DWC3_LINK_STATE_HRESET		= 0x09,
-	DWC3_LINK_STATE_CMPLY		= 0x0a,
-	DWC3_LINK_STATE_LPBK		= 0x0b,
-	DWC3_LINK_STATE_MASK		= 0x0f,
-};
-
-enum dwc3_device_state {
-	DWC3_DEFAULT_STATE,
-	DWC3_ADDRESS_STATE,
-	DWC3_CONFIGURED_STATE,
-};
-
-/**
- * struct dwc3_trb - transfer request block
- * @bpl: lower 32bit of the buffer
- * @bph: higher 32bit of the buffer
- * @length: buffer size (up to 16mb - 1)
- * @pcm1: packet count m1
- * @trbsts: trb status
- *	0 = ok
- *	1 = missed isoc
- *	2 = setup pending
- * @hwo: hardware owner of descriptor
- * @lst: last trb
- * @chn: chain buffers
- * @csp: continue on short packets (only supported on isoc eps)
- * @trbctl: trb control
- *	1 = normal
- *	2 = control-setup
- *	3 = control-status-2
- *	4 = control-status-3
- *	5 = control-data (first trb of data stage)
- *	6 = isochronous-first (first trb of service interval)
- *	7 = isochronous
- *	8 = link trb
- *	others = reserved
- * @isp_imi: interrupt on short packet / interrupt on missed isoc
- * @ioc: interrupt on complete
- * @sid_sofn: Stream ID / SOF Number
- */
-struct dwc3_trb {
-	u64             bplh;
-
-	union {
-		struct {
-			u32             length:24;
-			u32             pcm1:2;
-			u32             reserved27_26:2;
-			u32             trbsts:4;
-#define DWC3_TRB_STS_OKAY                       0
-#define DWC3_TRB_STS_MISSED_ISOC                1
-#define DWC3_TRB_STS_SETUP_PENDING              2
-		};
-		u32 len_pcm;
-	};
-
-	union {
-		struct {
-			u32             hwo:1;
-			u32             lst:1;
-			u32             chn:1;
-			u32             csp:1;
-			u32             trbctl:6;
-			u32             isp_imi:1;
-			u32             ioc:1;
-			u32             reserved13_12:2;
-			u32             sid_sofn:16;
-			u32             reserved31_30:2;
-		};
-		u32 control;
-	};
-} __packed;
-
-/**
- * struct dwc3_trb_hw - transfer request block (hw format)
- * @bpl: DW0-3
- * @bph: DW4-7
- * @size: DW8-B
- * @trl: DWC-F
- */
-struct dwc3_trb_hw {
-	__le32		bpl;
-	__le32		bph;
-	__le32		size;
-	__le32		ctrl;
-} __packed;
-
-static inline void dwc3_trb_to_hw(struct dwc3_trb *nat, struct dwc3_trb_hw *hw)
-{
-	hw->bpl = cpu_to_le32(lower_32_bits(nat->bplh));
-	hw->bph = cpu_to_le32(upper_32_bits(nat->bplh));
-	hw->size = cpu_to_le32p(&nat->len_pcm);
-	/* HWO is written last */
-	hw->ctrl = cpu_to_le32p(&nat->control);
-}
-
-static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
-{
-	u64 bplh;
-
-	bplh = le32_to_cpup(&hw->bpl);
-	bplh |= (u64) le32_to_cpup(&hw->bph) << 32;
-	nat->bplh = bplh;
-
-	nat->len_pcm = le32_to_cpup(&hw->size);
-	nat->control = le32_to_cpup(&hw->ctrl);
-}
-
-/**
- * dwc3_hwparams - copy of HWPARAMS registers
- * @hwparams0 - GHWPARAMS0
- * @hwparams1 - GHWPARAMS1
- * @hwparams2 - GHWPARAMS2
- * @hwparams3 - GHWPARAMS3
- * @hwparams4 - GHWPARAMS4
- * @hwparams5 - GHWPARAMS5
- * @hwparams6 - GHWPARAMS6
- * @hwparams7 - GHWPARAMS7
- * @hwparams8 - GHWPARAMS8
- */
-struct dwc3_hwparams {
-	u32	hwparams0;
-	u32	hwparams1;
-	u32	hwparams2;
-	u32	hwparams3;
-	u32	hwparams4;
-	u32	hwparams5;
-	u32	hwparams6;
-	u32	hwparams7;
-	u32	hwparams8;
-};
-
-/**
- * struct dwc3 - representation of our controller
- * @ctrl_req: usb control request which is used for ep0
- * @ep0_trb: trb which is used for the ctrl_req
- * @ep0_bounce: bounce buffer for ep0
- * @setup_buf: used while precessing STD USB requests
- * @ctrl_req_addr: dma address of ctrl_req
- * @ep0_trb: dma address of ep0_trb
- * @ep0_usb_req: dummy req used while handling STD USB requests
- * @setup_buf_addr: dma address of setup_buf
- * @ep0_bounce_addr: dma address of ep0_bounce
- * @lock: for synchronizing
- * @dev: pointer to our struct device
- * @event_buffer_list: a list of event buffers
- * @gadget: device side representation of the peripheral controller
- * @gadget_driver: pointer to the gadget driver
- * @regs: base address for our registers
- * @regs_size: address space size
- * @irq: IRQ number
- * @revision: revision register contents
- * @is_selfpowered: true when we are selfpowered
- * @three_stage_setup: set if we perform a three phase setup
- * @ep0_status_pending: ep0 status response without a req is pending
- * @ep0_bounced: true when we used bounce buffer
- * @ep0_expect_in: true when we expect a DATA IN transfer
- * @start_config_issued: true when StartConfig command has been issued
- * @ep0_next_event: hold the next expected event
- * @ep0state: state of endpoint zero
- * @link_state: link state
- * @speed: device speed (super, high, full, low)
- * @mem: points to start of memory which is used for this struct.
- * @hwparams: copy of hwparams registers
- * @root: debugfs root folder pointer
- */
-struct dwc3 {
-	struct usb_ctrlrequest	*ctrl_req;
-	struct dwc3_trb_hw	*ep0_trb;
-	void			*ep0_bounce;
-	u8			*setup_buf;
-	dma_addr_t		ctrl_req_addr;
-	dma_addr_t		ep0_trb_addr;
-	dma_addr_t		setup_buf_addr;
-	dma_addr_t		ep0_bounce_addr;
-	struct usb_request	ep0_usb_req;
-	/* device lock */
-	spinlock_t		lock;
-	struct device		*dev;
-
-	struct dwc3_event_buffer *ev_buffs[DWC3_EVENT_BUFFERS_NUM];
-	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
-
-	struct usb_gadget	gadget;
-	struct usb_gadget_driver *gadget_driver;
-
-	void __iomem		*regs;
-	size_t			regs_size;
-
-	int			irq;
-
-	u32			revision;
-
-#define DWC3_REVISION_173A	0x5533173a
-#define DWC3_REVISION_175A	0x5533175a
-#define DWC3_REVISION_180A	0x5533180a
-#define DWC3_REVISION_183A	0x5533183a
-#define DWC3_REVISION_185A	0x5533185a
-#define DWC3_REVISION_188A	0x5533188a
-#define DWC3_REVISION_190A	0x5533190a
-
-	unsigned		is_selfpowered:1;
-	unsigned		three_stage_setup:1;
-	unsigned		ep0_status_pending:1;
-	unsigned		ep0_bounced:1;
-	unsigned		ep0_expect_in:1;
-	unsigned		start_config_issued:1;
-
-	enum dwc3_ep0_next	ep0_next_event;
-	enum dwc3_ep0_state	ep0state;
-	enum dwc3_link_state	link_state;
-	enum dwc3_device_state	dev_state;
-
-	u8			speed;
-	void			*mem;
-
-	struct dwc3_hwparams	hwparams;
-	struct dentry		*root;
-};
-
-/* -------------------------------------------------------------------------- */
-
-#define DWC3_TRBSTS_OK			0
-#define DWC3_TRBSTS_MISSED_ISOC		1
-#define DWC3_TRBSTS_SETUP_PENDING	2
-
-#define DWC3_TRBCTL_NORMAL		1
-#define DWC3_TRBCTL_CONTROL_SETUP	2
-#define DWC3_TRBCTL_CONTROL_STATUS2	3
-#define DWC3_TRBCTL_CONTROL_STATUS3	4
-#define DWC3_TRBCTL_CONTROL_DATA	5
-#define DWC3_TRBCTL_ISOCHRONOUS_FIRST	6
-#define DWC3_TRBCTL_ISOCHRONOUS		7
-#define DWC3_TRBCTL_LINK_TRB		8
-
-/* -------------------------------------------------------------------------- */
-
-struct dwc3_event_type {
-	u32	is_devspec:1;
-	u32	type:6;
-	u32	reserved8_31:25;
-} __packed;
-
-#define DWC3_DEPEVT_XFERCOMPLETE	0x01
-#define DWC3_DEPEVT_XFERINPROGRESS	0x02
-#define DWC3_DEPEVT_XFERNOTREADY	0x03
-#define DWC3_DEPEVT_RXTXFIFOEVT		0x04
-#define DWC3_DEPEVT_STREAMEVT		0x06
-#define DWC3_DEPEVT_EPCMDCMPLT		0x07
-
-/**
- * struct dwc3_event_depvt - Device Endpoint Events
- * @one_bit: indicates this is an endpoint event (not used)
- * @endpoint_number: number of the endpoint
- * @endpoint_event: The event we have:
- *	0x00	- Reserved
- *	0x01	- XferComplete
- *	0x02	- XferInProgress
- *	0x03	- XferNotReady
- *	0x04	- RxTxFifoEvt (IN->Underrun, OUT->Overrun)
- *	0x05	- Reserved
- *	0x06	- StreamEvt
- *	0x07	- EPCmdCmplt
- * @reserved11_10: Reserved, don't use.
- * @status: Indicates the status of the event. Refer to databook for
- *	more information.
- * @parameters: Parameters of the current event. Refer to databook for
- *	more information.
- */
-struct dwc3_event_depevt {
-	u32	one_bit:1;
-	u32	endpoint_number:5;
-	u32	endpoint_event:4;
-	u32	reserved11_10:2;
-	u32	status:4;
-#define DEPEVT_STATUS_BUSERR    (1 << 0)
-#define DEPEVT_STATUS_SHORT     (1 << 1)
-#define DEPEVT_STATUS_IOC       (1 << 2)
-#define DEPEVT_STATUS_LST	(1 << 3)
-
-/* Stream event only */
-#define DEPEVT_STREAMEVT_FOUND		1
-#define DEPEVT_STREAMEVT_NOTFOUND	2
-
-/* Control-only Status */
-#define DEPEVT_STATUS_CONTROL_SETUP	0
-#define DEPEVT_STATUS_CONTROL_DATA	1
-#define DEPEVT_STATUS_CONTROL_STATUS	2
-
-	u32	parameters:16;
-} __packed;
-
-/**
- * struct dwc3_event_devt - Device Events
- * @one_bit: indicates this is a non-endpoint event (not used)
- * @device_event: indicates it's a device event. Should read as 0x00
- * @type: indicates the type of device event.
- *	0	- DisconnEvt
- *	1	- USBRst
- *	2	- ConnectDone
- *	3	- ULStChng
- *	4	- WkUpEvt
- *	5	- Reserved
- *	6	- EOPF
- *	7	- SOF
- *	8	- Reserved
- *	9	- ErrticErr
- *	10	- CmdCmplt
- *	11	- EvntOverflow
- *	12	- VndrDevTstRcved
- * @reserved15_12: Reserved, not used
- * @event_info: Information about this event
- * @reserved31_24: Reserved, not used
- */
-struct dwc3_event_devt {
-	u32	one_bit:1;
-	u32	device_event:7;
-	u32	type:4;
-	u32	reserved15_12:4;
-	u32	event_info:8;
-	u32	reserved31_24:8;
-} __packed;
-
-/**
- * struct dwc3_event_gevt - Other Core Events
- * @one_bit: indicates this is a non-endpoint event (not used)
- * @device_event: indicates it's (0x03) Carkit or (0x04) I2C event.
- * @phy_port_number: self-explanatory
- * @reserved31_12: Reserved, not used.
- */
-struct dwc3_event_gevt {
-	u32	one_bit:1;
-	u32	device_event:7;
-	u32	phy_port_number:4;
-	u32	reserved31_12:20;
-} __packed;
-
-/**
- * union dwc3_event - representation of Event Buffer contents
- * @raw: raw 32-bit event
- * @type: the type of the event
- * @depevt: Device Endpoint Event
- * @devt: Device Event
- * @gevt: Global Event
- */
-union dwc3_event {
-	u32				raw;
-	struct dwc3_event_type		type;
-	struct dwc3_event_depevt	depevt;
-	struct dwc3_event_devt		devt;
-	struct dwc3_event_gevt		gevt;
-};
-
-/*
- * DWC3 Features to be used as Driver Data
- */
-
-#define DWC3_HAS_PERIPHERAL		BIT(0)
-#define DWC3_HAS_XHCI			BIT(1)
-#define DWC3_HAS_OTG			BIT(3)
-
-#endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
deleted file mode 100644
index 5894ee8..0000000
--- a/drivers/usb/dwc3/debug.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * debug.h - DesignWare USB3 DRD Controller Debug Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "core.h"
-
-#ifdef CONFIG_DEBUG_FS
-extern int dwc3_debugfs_init(struct dwc3 *);
-extern void dwc3_debugfs_exit(struct dwc3 *);
-#else
-static inline int dwc3_debugfs_init(struct dwc3 *d)
-{  return 0;  }
-static inline void dwc3_debugfs_exit(struct dwc3 *d)
-{  }
-#endif
-
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
deleted file mode 100644
index da1ad77..0000000
--- a/drivers/usb/dwc3/debugfs.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/**
- * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/ptrace.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/delay.h>
-
-#include <asm/uaccess.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-struct dwc3_register {
-	const char	*name;
-	u32		offset;
-};
-
-#define dump_register(nm)				\
-{							\
-	.name	= __stringify(nm),			\
-	.offset	= DWC3_ ##nm,				\
-}
-
-static const struct dwc3_register dwc3_regs[] = {
-	dump_register(GSBUSCFG0),
-	dump_register(GSBUSCFG1),
-	dump_register(GTXTHRCFG),
-	dump_register(GRXTHRCFG),
-	dump_register(GCTL),
-	dump_register(GEVTEN),
-	dump_register(GSTS),
-	dump_register(GSNPSID),
-	dump_register(GGPIO),
-	dump_register(GUID),
-	dump_register(GUCTL),
-	dump_register(GBUSERRADDR0),
-	dump_register(GBUSERRADDR1),
-	dump_register(GPRTBIMAP0),
-	dump_register(GPRTBIMAP1),
-	dump_register(GHWPARAMS0),
-	dump_register(GHWPARAMS1),
-	dump_register(GHWPARAMS2),
-	dump_register(GHWPARAMS3),
-	dump_register(GHWPARAMS4),
-	dump_register(GHWPARAMS5),
-	dump_register(GHWPARAMS6),
-	dump_register(GHWPARAMS7),
-	dump_register(GDBGFIFOSPACE),
-	dump_register(GDBGLTSSM),
-	dump_register(GPRTBIMAP_HS0),
-	dump_register(GPRTBIMAP_HS1),
-	dump_register(GPRTBIMAP_FS0),
-	dump_register(GPRTBIMAP_FS1),
-
-	dump_register(GUSB2PHYCFG(0)),
-	dump_register(GUSB2PHYCFG(1)),
-	dump_register(GUSB2PHYCFG(2)),
-	dump_register(GUSB2PHYCFG(3)),
-	dump_register(GUSB2PHYCFG(4)),
-	dump_register(GUSB2PHYCFG(5)),
-	dump_register(GUSB2PHYCFG(6)),
-	dump_register(GUSB2PHYCFG(7)),
-	dump_register(GUSB2PHYCFG(8)),
-	dump_register(GUSB2PHYCFG(9)),
-	dump_register(GUSB2PHYCFG(10)),
-	dump_register(GUSB2PHYCFG(11)),
-	dump_register(GUSB2PHYCFG(12)),
-	dump_register(GUSB2PHYCFG(13)),
-	dump_register(GUSB2PHYCFG(14)),
-	dump_register(GUSB2PHYCFG(15)),
-
-	dump_register(GUSB2I2CCTL(0)),
-	dump_register(GUSB2I2CCTL(1)),
-	dump_register(GUSB2I2CCTL(2)),
-	dump_register(GUSB2I2CCTL(3)),
-	dump_register(GUSB2I2CCTL(4)),
-	dump_register(GUSB2I2CCTL(5)),
-	dump_register(GUSB2I2CCTL(6)),
-	dump_register(GUSB2I2CCTL(7)),
-	dump_register(GUSB2I2CCTL(8)),
-	dump_register(GUSB2I2CCTL(9)),
-	dump_register(GUSB2I2CCTL(10)),
-	dump_register(GUSB2I2CCTL(11)),
-	dump_register(GUSB2I2CCTL(12)),
-	dump_register(GUSB2I2CCTL(13)),
-	dump_register(GUSB2I2CCTL(14)),
-	dump_register(GUSB2I2CCTL(15)),
-
-	dump_register(GUSB2PHYACC(0)),
-	dump_register(GUSB2PHYACC(1)),
-	dump_register(GUSB2PHYACC(2)),
-	dump_register(GUSB2PHYACC(3)),
-	dump_register(GUSB2PHYACC(4)),
-	dump_register(GUSB2PHYACC(5)),
-	dump_register(GUSB2PHYACC(6)),
-	dump_register(GUSB2PHYACC(7)),
-	dump_register(GUSB2PHYACC(8)),
-	dump_register(GUSB2PHYACC(9)),
-	dump_register(GUSB2PHYACC(10)),
-	dump_register(GUSB2PHYACC(11)),
-	dump_register(GUSB2PHYACC(12)),
-	dump_register(GUSB2PHYACC(13)),
-	dump_register(GUSB2PHYACC(14)),
-	dump_register(GUSB2PHYACC(15)),
-
-	dump_register(GUSB3PIPECTL(0)),
-	dump_register(GUSB3PIPECTL(1)),
-	dump_register(GUSB3PIPECTL(2)),
-	dump_register(GUSB3PIPECTL(3)),
-	dump_register(GUSB3PIPECTL(4)),
-	dump_register(GUSB3PIPECTL(5)),
-	dump_register(GUSB3PIPECTL(6)),
-	dump_register(GUSB3PIPECTL(7)),
-	dump_register(GUSB3PIPECTL(8)),
-	dump_register(GUSB3PIPECTL(9)),
-	dump_register(GUSB3PIPECTL(10)),
-	dump_register(GUSB3PIPECTL(11)),
-	dump_register(GUSB3PIPECTL(12)),
-	dump_register(GUSB3PIPECTL(13)),
-	dump_register(GUSB3PIPECTL(14)),
-	dump_register(GUSB3PIPECTL(15)),
-
-	dump_register(GTXFIFOSIZ(0)),
-	dump_register(GTXFIFOSIZ(1)),
-	dump_register(GTXFIFOSIZ(2)),
-	dump_register(GTXFIFOSIZ(3)),
-	dump_register(GTXFIFOSIZ(4)),
-	dump_register(GTXFIFOSIZ(5)),
-	dump_register(GTXFIFOSIZ(6)),
-	dump_register(GTXFIFOSIZ(7)),
-	dump_register(GTXFIFOSIZ(8)),
-	dump_register(GTXFIFOSIZ(9)),
-	dump_register(GTXFIFOSIZ(10)),
-	dump_register(GTXFIFOSIZ(11)),
-	dump_register(GTXFIFOSIZ(12)),
-	dump_register(GTXFIFOSIZ(13)),
-	dump_register(GTXFIFOSIZ(14)),
-	dump_register(GTXFIFOSIZ(15)),
-	dump_register(GTXFIFOSIZ(16)),
-	dump_register(GTXFIFOSIZ(17)),
-	dump_register(GTXFIFOSIZ(18)),
-	dump_register(GTXFIFOSIZ(19)),
-	dump_register(GTXFIFOSIZ(20)),
-	dump_register(GTXFIFOSIZ(21)),
-	dump_register(GTXFIFOSIZ(22)),
-	dump_register(GTXFIFOSIZ(23)),
-	dump_register(GTXFIFOSIZ(24)),
-	dump_register(GTXFIFOSIZ(25)),
-	dump_register(GTXFIFOSIZ(26)),
-	dump_register(GTXFIFOSIZ(27)),
-	dump_register(GTXFIFOSIZ(28)),
-	dump_register(GTXFIFOSIZ(29)),
-	dump_register(GTXFIFOSIZ(30)),
-	dump_register(GTXFIFOSIZ(31)),
-
-	dump_register(GRXFIFOSIZ(0)),
-	dump_register(GRXFIFOSIZ(1)),
-	dump_register(GRXFIFOSIZ(2)),
-	dump_register(GRXFIFOSIZ(3)),
-	dump_register(GRXFIFOSIZ(4)),
-	dump_register(GRXFIFOSIZ(5)),
-	dump_register(GRXFIFOSIZ(6)),
-	dump_register(GRXFIFOSIZ(7)),
-	dump_register(GRXFIFOSIZ(8)),
-	dump_register(GRXFIFOSIZ(9)),
-	dump_register(GRXFIFOSIZ(10)),
-	dump_register(GRXFIFOSIZ(11)),
-	dump_register(GRXFIFOSIZ(12)),
-	dump_register(GRXFIFOSIZ(13)),
-	dump_register(GRXFIFOSIZ(14)),
-	dump_register(GRXFIFOSIZ(15)),
-	dump_register(GRXFIFOSIZ(16)),
-	dump_register(GRXFIFOSIZ(17)),
-	dump_register(GRXFIFOSIZ(18)),
-	dump_register(GRXFIFOSIZ(19)),
-	dump_register(GRXFIFOSIZ(20)),
-	dump_register(GRXFIFOSIZ(21)),
-	dump_register(GRXFIFOSIZ(22)),
-	dump_register(GRXFIFOSIZ(23)),
-	dump_register(GRXFIFOSIZ(24)),
-	dump_register(GRXFIFOSIZ(25)),
-	dump_register(GRXFIFOSIZ(26)),
-	dump_register(GRXFIFOSIZ(27)),
-	dump_register(GRXFIFOSIZ(28)),
-	dump_register(GRXFIFOSIZ(29)),
-	dump_register(GRXFIFOSIZ(30)),
-	dump_register(GRXFIFOSIZ(31)),
-
-	dump_register(GEVNTADRLO(0)),
-	dump_register(GEVNTADRHI(0)),
-	dump_register(GEVNTSIZ(0)),
-	dump_register(GEVNTCOUNT(0)),
-
-	dump_register(GHWPARAMS8),
-	dump_register(DCFG),
-	dump_register(DCTL),
-	dump_register(DEVTEN),
-	dump_register(DSTS),
-	dump_register(DGCMDPAR),
-	dump_register(DGCMD),
-	dump_register(DALEPENA),
-
-	dump_register(DEPCMDPAR2(0)),
-	dump_register(DEPCMDPAR2(1)),
-	dump_register(DEPCMDPAR2(2)),
-	dump_register(DEPCMDPAR2(3)),
-	dump_register(DEPCMDPAR2(4)),
-	dump_register(DEPCMDPAR2(5)),
-	dump_register(DEPCMDPAR2(6)),
-	dump_register(DEPCMDPAR2(7)),
-	dump_register(DEPCMDPAR2(8)),
-	dump_register(DEPCMDPAR2(9)),
-	dump_register(DEPCMDPAR2(10)),
-	dump_register(DEPCMDPAR2(11)),
-	dump_register(DEPCMDPAR2(12)),
-	dump_register(DEPCMDPAR2(13)),
-	dump_register(DEPCMDPAR2(14)),
-	dump_register(DEPCMDPAR2(15)),
-	dump_register(DEPCMDPAR2(16)),
-	dump_register(DEPCMDPAR2(17)),
-	dump_register(DEPCMDPAR2(18)),
-	dump_register(DEPCMDPAR2(19)),
-	dump_register(DEPCMDPAR2(20)),
-	dump_register(DEPCMDPAR2(21)),
-	dump_register(DEPCMDPAR2(22)),
-	dump_register(DEPCMDPAR2(23)),
-	dump_register(DEPCMDPAR2(24)),
-	dump_register(DEPCMDPAR2(25)),
-	dump_register(DEPCMDPAR2(26)),
-	dump_register(DEPCMDPAR2(27)),
-	dump_register(DEPCMDPAR2(28)),
-	dump_register(DEPCMDPAR2(29)),
-	dump_register(DEPCMDPAR2(30)),
-	dump_register(DEPCMDPAR2(31)),
-
-	dump_register(DEPCMDPAR1(0)),
-	dump_register(DEPCMDPAR1(1)),
-	dump_register(DEPCMDPAR1(2)),
-	dump_register(DEPCMDPAR1(3)),
-	dump_register(DEPCMDPAR1(4)),
-	dump_register(DEPCMDPAR1(5)),
-	dump_register(DEPCMDPAR1(6)),
-	dump_register(DEPCMDPAR1(7)),
-	dump_register(DEPCMDPAR1(8)),
-	dump_register(DEPCMDPAR1(9)),
-	dump_register(DEPCMDPAR1(10)),
-	dump_register(DEPCMDPAR1(11)),
-	dump_register(DEPCMDPAR1(12)),
-	dump_register(DEPCMDPAR1(13)),
-	dump_register(DEPCMDPAR1(14)),
-	dump_register(DEPCMDPAR1(15)),
-	dump_register(DEPCMDPAR1(16)),
-	dump_register(DEPCMDPAR1(17)),
-	dump_register(DEPCMDPAR1(18)),
-	dump_register(DEPCMDPAR1(19)),
-	dump_register(DEPCMDPAR1(20)),
-	dump_register(DEPCMDPAR1(21)),
-	dump_register(DEPCMDPAR1(22)),
-	dump_register(DEPCMDPAR1(23)),
-	dump_register(DEPCMDPAR1(24)),
-	dump_register(DEPCMDPAR1(25)),
-	dump_register(DEPCMDPAR1(26)),
-	dump_register(DEPCMDPAR1(27)),
-	dump_register(DEPCMDPAR1(28)),
-	dump_register(DEPCMDPAR1(29)),
-	dump_register(DEPCMDPAR1(30)),
-	dump_register(DEPCMDPAR1(31)),
-
-	dump_register(DEPCMDPAR0(0)),
-	dump_register(DEPCMDPAR0(1)),
-	dump_register(DEPCMDPAR0(2)),
-	dump_register(DEPCMDPAR0(3)),
-	dump_register(DEPCMDPAR0(4)),
-	dump_register(DEPCMDPAR0(5)),
-	dump_register(DEPCMDPAR0(6)),
-	dump_register(DEPCMDPAR0(7)),
-	dump_register(DEPCMDPAR0(8)),
-	dump_register(DEPCMDPAR0(9)),
-	dump_register(DEPCMDPAR0(10)),
-	dump_register(DEPCMDPAR0(11)),
-	dump_register(DEPCMDPAR0(12)),
-	dump_register(DEPCMDPAR0(13)),
-	dump_register(DEPCMDPAR0(14)),
-	dump_register(DEPCMDPAR0(15)),
-	dump_register(DEPCMDPAR0(16)),
-	dump_register(DEPCMDPAR0(17)),
-	dump_register(DEPCMDPAR0(18)),
-	dump_register(DEPCMDPAR0(19)),
-	dump_register(DEPCMDPAR0(20)),
-	dump_register(DEPCMDPAR0(21)),
-	dump_register(DEPCMDPAR0(22)),
-	dump_register(DEPCMDPAR0(23)),
-	dump_register(DEPCMDPAR0(24)),
-	dump_register(DEPCMDPAR0(25)),
-	dump_register(DEPCMDPAR0(26)),
-	dump_register(DEPCMDPAR0(27)),
-	dump_register(DEPCMDPAR0(28)),
-	dump_register(DEPCMDPAR0(29)),
-	dump_register(DEPCMDPAR0(30)),
-	dump_register(DEPCMDPAR0(31)),
-
-	dump_register(DEPCMD(0)),
-	dump_register(DEPCMD(1)),
-	dump_register(DEPCMD(2)),
-	dump_register(DEPCMD(3)),
-	dump_register(DEPCMD(4)),
-	dump_register(DEPCMD(5)),
-	dump_register(DEPCMD(6)),
-	dump_register(DEPCMD(7)),
-	dump_register(DEPCMD(8)),
-	dump_register(DEPCMD(9)),
-	dump_register(DEPCMD(10)),
-	dump_register(DEPCMD(11)),
-	dump_register(DEPCMD(12)),
-	dump_register(DEPCMD(13)),
-	dump_register(DEPCMD(14)),
-	dump_register(DEPCMD(15)),
-	dump_register(DEPCMD(16)),
-	dump_register(DEPCMD(17)),
-	dump_register(DEPCMD(18)),
-	dump_register(DEPCMD(19)),
-	dump_register(DEPCMD(20)),
-	dump_register(DEPCMD(21)),
-	dump_register(DEPCMD(22)),
-	dump_register(DEPCMD(23)),
-	dump_register(DEPCMD(24)),
-	dump_register(DEPCMD(25)),
-	dump_register(DEPCMD(26)),
-	dump_register(DEPCMD(27)),
-	dump_register(DEPCMD(28)),
-	dump_register(DEPCMD(29)),
-	dump_register(DEPCMD(30)),
-	dump_register(DEPCMD(31)),
-
-	dump_register(OCFG),
-	dump_register(OCTL),
-	dump_register(OEVTEN),
-	dump_register(OSTS),
-};
-
-static int dwc3_regdump_show(struct seq_file *s, void *unused)
-{
-	struct dwc3		*dwc = s->private;
-	int			i;
-
-	seq_printf(s, "DesignWare USB3 Core Register Dump\n");
-
-	for (i = 0; i < ARRAY_SIZE(dwc3_regs); i++) {
-		seq_printf(s, "%-20s :    %08x\n", dwc3_regs[i].name,
-				dwc3_readl(dwc->regs, dwc3_regs[i].offset));
-	}
-
-	return 0;
-}
-
-static int dwc3_regdump_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, dwc3_regdump_show, inode->i_private);
-}
-
-static const struct file_operations dwc3_regdump_fops = {
-	.open			= dwc3_regdump_open,
-	.read			= seq_read,
-	.release		= single_release,
-};
-
-int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
-{
-	struct dentry		*root;
-	struct dentry		*file;
-	int			ret;
-
-	root = debugfs_create_dir(dev_name(dwc->dev), NULL);
-	if (IS_ERR(root)){
-		ret = PTR_ERR(root);
-		goto err0;
-	}
-
-	dwc->root = root;
-
-	file = debugfs_create_file("regdump", S_IRUGO, root, dwc,
-			&dwc3_regdump_fops);
-	if (IS_ERR(file)) {
-		ret = PTR_ERR(file);
-		goto err1;
-	}
-	return 0;
-
-err1:
-	debugfs_remove_recursive(root);
-
-err0:
-	return ret;
-}
-
-void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
-{
-	debugfs_remove_recursive(dwc->root);
-	dwc->root = NULL;
-}
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
deleted file mode 100644
index 062552b..0000000
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/**
- * dwc3-omap.c - OMAP Specific Glue layer
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/dwc3-omap.h>
-#include <linux/dma-mapping.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/module.h>
-
-#include "io.h"
-
-/*
- * All these registers belong to OMAP's Wrapper around the
- * DesignWare USB3 Core.
- */
-
-#define USBOTGSS_REVISION			0x0000
-#define USBOTGSS_SYSCONFIG			0x0010
-#define USBOTGSS_IRQ_EOI			0x0020
-#define USBOTGSS_IRQSTATUS_RAW_0		0x0024
-#define USBOTGSS_IRQSTATUS_0			0x0028
-#define USBOTGSS_IRQENABLE_SET_0		0x002c
-#define USBOTGSS_IRQENABLE_CLR_0		0x0030
-#define USBOTGSS_IRQSTATUS_RAW_1		0x0034
-#define USBOTGSS_IRQSTATUS_1			0x0038
-#define USBOTGSS_IRQENABLE_SET_1		0x003c
-#define USBOTGSS_IRQENABLE_CLR_1		0x0040
-#define USBOTGSS_UTMI_OTG_CTRL			0x0080
-#define USBOTGSS_UTMI_OTG_STATUS		0x0084
-#define USBOTGSS_MMRAM_OFFSET			0x0100
-#define USBOTGSS_FLADJ				0x0104
-#define USBOTGSS_DEBUG_CFG			0x0108
-#define USBOTGSS_DEBUG_DATA			0x010c
-
-/* SYSCONFIG REGISTER */
-#define USBOTGSS_SYSCONFIG_DMADISABLE		(1 << 16)
-#define USBOTGSS_SYSCONFIG_STANDBYMODE(x)	((x) << 4)
-
-#define USBOTGSS_STANDBYMODE_FORCE_STANDBY	0
-#define USBOTGSS_STANDBYMODE_NO_STANDBY		1
-#define USBOTGSS_STANDBYMODE_SMART_STANDBY	2
-#define USBOTGSS_STANDBYMODE_SMART_WAKEUP	3
-
-#define USBOTGSS_STANDBYMODE_MASK		(0x03 << 4)
-
-#define USBOTGSS_SYSCONFIG_IDLEMODE(x)		((x) << 2)
-
-#define USBOTGSS_IDLEMODE_FORCE_IDLE		0
-#define USBOTGSS_IDLEMODE_NO_IDLE		1
-#define USBOTGSS_IDLEMODE_SMART_IDLE		2
-#define USBOTGSS_IDLEMODE_SMART_WAKEUP		3
-
-#define USBOTGSS_IDLEMODE_MASK			(0x03 << 2)
-
-/* IRQ_EOI REGISTER */
-#define USBOTGSS_IRQ_EOI_LINE_NUMBER		(1 << 0)
-
-/* IRQS0 BITS */
-#define USBOTGSS_IRQO_COREIRQ_ST		(1 << 0)
-
-/* IRQ1 BITS */
-#define USBOTGSS_IRQ1_DMADISABLECLR		(1 << 17)
-#define USBOTGSS_IRQ1_OEVT			(1 << 16)
-#define USBOTGSS_IRQ1_DRVVBUS_RISE		(1 << 13)
-#define USBOTGSS_IRQ1_CHRGVBUS_RISE		(1 << 12)
-#define USBOTGSS_IRQ1_DISCHRGVBUS_RISE		(1 << 11)
-#define USBOTGSS_IRQ1_IDPULLUP_RISE		(1 << 8)
-#define USBOTGSS_IRQ1_DRVVBUS_FALL		(1 << 5)
-#define USBOTGSS_IRQ1_CHRGVBUS_FALL		(1 << 4)
-#define USBOTGSS_IRQ1_DISCHRGVBUS_FALL		(1 << 3)
-#define USBOTGSS_IRQ1_IDPULLUP_FALL		(1 << 0)
-
-/* UTMI_OTG_CTRL REGISTER */
-#define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS		(1 << 5)
-#define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS		(1 << 4)
-#define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS	(1 << 3)
-#define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP		(1 << 0)
-
-/* UTMI_OTG_STATUS REGISTER */
-#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE	(1 << 31)
-#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT	(1 << 9)
-#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8)
-#define USBOTGSS_UTMI_OTG_STATUS_IDDIG		(1 << 4)
-#define USBOTGSS_UTMI_OTG_STATUS_SESSEND	(1 << 3)
-#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID	(1 << 2)
-#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID	(1 << 1)
-
-struct dwc3_omap {
-	/* device lock */
-	spinlock_t		lock;
-
-	struct platform_device	*dwc3;
-	struct device		*dev;
-
-	int			irq;
-	void __iomem		*base;
-
-	void			*context;
-	u32			resource_size;
-
-	u32			dma_status:1;
-};
-
-static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
-{
-	struct dwc3_omap	*omap = _omap;
-	u32			reg;
-
-	spin_lock(&omap->lock);
-
-	reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1);
-
-	if (reg & USBOTGSS_IRQ1_DMADISABLECLR) {
-		dev_dbg(omap->dev, "DMA Disable was Cleared\n");
-		omap->dma_status = false;
-	}
-
-	if (reg & USBOTGSS_IRQ1_OEVT)
-		dev_dbg(omap->dev, "OTG Event\n");
-
-	if (reg & USBOTGSS_IRQ1_DRVVBUS_RISE)
-		dev_dbg(omap->dev, "DRVVBUS Rise\n");
-
-	if (reg & USBOTGSS_IRQ1_CHRGVBUS_RISE)
-		dev_dbg(omap->dev, "CHRGVBUS Rise\n");
-
-	if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_RISE)
-		dev_dbg(omap->dev, "DISCHRGVBUS Rise\n");
-
-	if (reg & USBOTGSS_IRQ1_IDPULLUP_RISE)
-		dev_dbg(omap->dev, "IDPULLUP Rise\n");
-
-	if (reg & USBOTGSS_IRQ1_DRVVBUS_FALL)
-		dev_dbg(omap->dev, "DRVVBUS Fall\n");
-
-	if (reg & USBOTGSS_IRQ1_CHRGVBUS_FALL)
-		dev_dbg(omap->dev, "CHRGVBUS Fall\n");
-
-	if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_FALL)
-		dev_dbg(omap->dev, "DISCHRGVBUS Fall\n");
-
-	if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL)
-		dev_dbg(omap->dev, "IDPULLUP Fall\n");
-
-	dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg);
-
-	reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_0);
-	dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg);
-
-	spin_unlock(&omap->lock);
-
-	return IRQ_HANDLED;
-}
-
-static int __devinit dwc3_omap_probe(struct platform_device *pdev)
-{
-	struct dwc3_omap_data	*pdata = pdev->dev.platform_data;
-	struct platform_device	*dwc3;
-	struct dwc3_omap	*omap;
-	struct resource		*res;
-
-	int			ret = -ENOMEM;
-	int			irq;
-
-	u32			reg;
-
-	void __iomem		*base;
-	void			*context;
-
-	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
-	if (!omap) {
-		dev_err(&pdev->dev, "not enough memory\n");
-		goto err0;
-	}
-
-	platform_set_drvdata(pdev, omap);
-
-	irq = platform_get_irq(pdev, 1);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "missing IRQ resource\n");
-		ret = -EINVAL;
-		goto err1;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!res) {
-		dev_err(&pdev->dev, "missing memory base resource\n");
-		ret = -EINVAL;
-		goto err1;
-	}
-
-	base = ioremap_nocache(res->start, resource_size(res));
-	if (!base) {
-		dev_err(&pdev->dev, "ioremap failed\n");
-		goto err1;
-	}
-
-	dwc3 = platform_device_alloc("dwc3-omap", -1);
-	if (!dwc3) {
-		dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
-		goto err2;
-	}
-
-	context = kzalloc(resource_size(res), GFP_KERNEL);
-	if (!context) {
-		dev_err(&pdev->dev, "couldn't allocate dwc3 context memory\n");
-		goto err3;
-	}
-
-	spin_lock_init(&omap->lock);
-	dma_set_coherent_mask(&dwc3->dev, pdev->dev.coherent_dma_mask);
-
-	dwc3->dev.parent = &pdev->dev;
-	dwc3->dev.dma_mask = pdev->dev.dma_mask;
-	dwc3->dev.dma_parms = pdev->dev.dma_parms;
-	omap->resource_size = resource_size(res);
-	omap->context	= context;
-	omap->dev	= &pdev->dev;
-	omap->irq	= irq;
-	omap->base	= base;
-	omap->dwc3	= dwc3;
-
-	reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
-
-	if (!pdata) {
-		dev_dbg(&pdev->dev, "missing platform data\n");
-	} else {
-		switch (pdata->utmi_mode) {
-		case DWC3_OMAP_UTMI_MODE_SW:
-			reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-			break;
-		case DWC3_OMAP_UTMI_MODE_HW:
-			reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
-			break;
-		default:
-			dev_dbg(&pdev->dev, "UNKNOWN utmi mode %d\n",
-					pdata->utmi_mode);
-		}
-	}
-
-	dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg);
-
-	/* check the DMA Status */
-	reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);
-	omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE);
-
-	/* Set No-Idle and No-Standby */
-	reg &= ~(USBOTGSS_STANDBYMODE_MASK
-			| USBOTGSS_IDLEMODE_MASK);
-
-	reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY)
-		| USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE));
-
-	dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg);
-
-	ret = request_irq(omap->irq, dwc3_omap_interrupt, 0,
-			"dwc3-omap", omap);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to request IRQ #%d --> %d\n",
-				omap->irq, ret);
-		goto err4;
-	}
-
-	/* enable all IRQs */
-	reg = USBOTGSS_IRQO_COREIRQ_ST;
-	dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg);
-
-	reg = (USBOTGSS_IRQ1_OEVT |
-			USBOTGSS_IRQ1_DRVVBUS_RISE |
-			USBOTGSS_IRQ1_CHRGVBUS_RISE |
-			USBOTGSS_IRQ1_DISCHRGVBUS_RISE |
-			USBOTGSS_IRQ1_IDPULLUP_RISE |
-			USBOTGSS_IRQ1_DRVVBUS_FALL |
-			USBOTGSS_IRQ1_CHRGVBUS_FALL |
-			USBOTGSS_IRQ1_DISCHRGVBUS_FALL |
-			USBOTGSS_IRQ1_IDPULLUP_FALL);
-
-	dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg);
-
-	ret = platform_device_add_resources(dwc3, pdev->resource,
-			pdev->num_resources);
-	if (ret) {
-		dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n");
-		goto err5;
-	}
-
-	ret = platform_device_add(dwc3);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register dwc3 device\n");
-		goto err5;
-	}
-
-	return 0;
-
-err5:
-	free_irq(omap->irq, omap);
-
-err4:
-	kfree(omap->context);
-
-err3:
-	platform_device_put(dwc3);
-
-err2:
-	iounmap(base);
-
-err1:
-	kfree(omap);
-
-err0:
-	return ret;
-}
-
-static int __devexit dwc3_omap_remove(struct platform_device *pdev)
-{
-	struct dwc3_omap	*omap = platform_get_drvdata(pdev);
-
-	platform_device_unregister(omap->dwc3);
-
-	free_irq(omap->irq, omap);
-	iounmap(omap->base);
-
-	kfree(omap->context);
-	kfree(omap);
-
-	return 0;
-}
-
-static const struct of_device_id of_dwc3_matach[] = {
-	{
-		"ti,dwc3",
-	},
-	{ },
-};
-MODULE_DEVICE_TABLE(of, of_dwc3_matach);
-
-static struct platform_driver dwc3_omap_driver = {
-	.probe		= dwc3_omap_probe,
-	.remove		= __devexit_p(dwc3_omap_remove),
-	.driver		= {
-		.name	= "omap-dwc3",
-		.of_match_table	= of_dwc3_matach,
-	},
-};
-
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");
-
-static int __devinit dwc3_omap_init(void)
-{
-	return platform_driver_register(&dwc3_omap_driver);
-}
-module_init(dwc3_omap_init);
-
-static void __exit dwc3_omap_exit(void)
-{
-	platform_driver_unregister(&dwc3_omap_driver);
-}
-module_exit(dwc3_omap_exit);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
deleted file mode 100644
index f77c000..0000000
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * dwc3-pci.c - PCI Specific glue layer
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-
-/* FIXME define these in <linux/pci_ids.h> */
-#define PCI_VENDOR_ID_SYNOPSYS		0x16c3
-#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
-
-#define DWC3_PCI_DEVS_POSSIBLE	32
-
-struct dwc3_pci {
-	struct device		*dev;
-	struct platform_device	*dwc3;
-};
-
-static DECLARE_BITMAP(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE);
-
-static int dwc3_pci_get_device_id(struct dwc3_pci *glue)
-{
-	int		id;
-
-again:
-	id = find_first_zero_bit(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE);
-	if (id < DWC3_PCI_DEVS_POSSIBLE) {
-		int old;
-
-		old = test_and_set_bit(id, dwc3_pci_devs);
-		if (old)
-			goto again;
-	} else {
-		dev_err(glue->dev, "no space for new device\n");
-		id = -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void dwc3_pci_put_device_id(struct dwc3_pci *glue, int id)
-{
-	int			ret;
-
-	if (id < 0)
-		return;
-
-	ret = test_bit(id, dwc3_pci_devs);
-	WARN(!ret, "Device: %s\nID %d not in use\n",
-			dev_driver_string(glue->dev), id);
-	clear_bit(id, dwc3_pci_devs);
-}
-
-static int __devinit dwc3_pci_probe(struct pci_dev *pci,
-		const struct pci_device_id *id)
-{
-	struct resource		res[2];
-	struct platform_device	*dwc3;
-	struct dwc3_pci		*glue;
-	int			ret = -ENOMEM;
-	int			devid;
-
-	glue = kzalloc(sizeof(*glue), GFP_KERNEL);
-	if (!glue) {
-		dev_err(&pci->dev, "not enough memory\n");
-		goto err0;
-	}
-
-	glue->dev	= &pci->dev;
-
-	ret = pci_enable_device(pci);
-	if (ret) {
-		dev_err(&pci->dev, "failed to enable pci device\n");
-		goto err1;
-	}
-
-	pci_set_power_state(pci, PCI_D0);
-	pci_set_master(pci);
-
-	devid = dwc3_pci_get_device_id(glue);
-	if (devid < 0)
-		goto err2;
-
-	dwc3 = platform_device_alloc("dwc3-pci", devid);
-	if (!dwc3) {
-		dev_err(&pci->dev, "couldn't allocate dwc3 device\n");
-		goto err3;
-	}
-
-	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
-
-	res[0].start	= pci_resource_start(pci, 0);
-	res[0].end	= pci_resource_end(pci, 0);
-	res[0].name	= "dwc_usb3";
-	res[0].flags	= IORESOURCE_MEM;
-
-	res[1].start	= pci->irq;
-	res[1].name	= "dwc_usb3";
-	res[1].flags	= IORESOURCE_IRQ;
-
-	ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
-	if (ret) {
-		dev_err(&pci->dev, "couldn't add resources to dwc3 device\n");
-		goto err4;
-	}
-
-	pci_set_drvdata(pci, glue);
-
-	dma_set_coherent_mask(&dwc3->dev, pci->dev.coherent_dma_mask);
-
-	dwc3->dev.dma_mask = pci->dev.dma_mask;
-	dwc3->dev.dma_parms = pci->dev.dma_parms;
-	dwc3->dev.parent = &pci->dev;
-	glue->dwc3	= dwc3;
-
-	ret = platform_device_add(dwc3);
-	if (ret) {
-		dev_err(&pci->dev, "failed to register dwc3 device\n");
-		goto err4;
-	}
-
-	return 0;
-
-err4:
-	pci_set_drvdata(pci, NULL);
-	platform_device_put(dwc3);
-
-err3:
-	dwc3_pci_put_device_id(glue, devid);
-
-err2:
-	pci_disable_device(pci);
-
-err1:
-	kfree(pci);
-
-err0:
-	return ret;
-}
-
-static void __devexit dwc3_pci_remove(struct pci_dev *pci)
-{
-	struct dwc3_pci	*glue = pci_get_drvdata(pci);
-
-	dwc3_pci_put_device_id(glue, glue->dwc3->id);
-	platform_device_unregister(glue->dwc3);
-	pci_set_drvdata(pci, NULL);
-	pci_disable_device(pci);
-	kfree(glue);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = {
-	{
-		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
-				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
-	},
-	{  }	/* Terminating Entry */
-};
-MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
-
-static struct pci_driver dwc3_pci_driver = {
-	.name		= "pci-dwc3",
-	.id_table	= dwc3_pci_id_table,
-	.probe		= dwc3_pci_probe,
-	.remove		= __devexit_p(dwc3_pci_remove),
-};
-
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer");
-
-static int __devinit dwc3_pci_init(void)
-{
-	return pci_register_driver(&dwc3_pci_driver);
-}
-module_init(dwc3_pci_init);
-
-static void __exit dwc3_pci_exit(void)
-{
-	pci_unregister_driver(&dwc3_pci_driver);
-}
-module_exit(dwc3_pci_exit);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
deleted file mode 100644
index 69a4e43..0000000
--- a/drivers/usb/dwc3/ep0.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/**
- * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event);
-
-static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
-{
-	switch (state) {
-	case EP0_UNCONNECTED:
-		return "Unconnected";
-	case EP0_SETUP_PHASE:
-		return "Setup Phase";
-	case EP0_DATA_PHASE:
-		return "Data Phase";
-	case EP0_STATUS_PHASE:
-		return "Status Phase";
-	default:
-		return "UNKNOWN";
-	}
-}
-
-static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
-		u32 len, u32 type)
-{
-	struct dwc3_gadget_ep_cmd_params params;
-	struct dwc3_trb_hw		*trb_hw;
-	struct dwc3_trb			trb;
-	struct dwc3_ep			*dep;
-
-	int				ret;
-
-	dep = dwc->eps[epnum];
-	if (dep->flags & DWC3_EP_BUSY) {
-		dev_vdbg(dwc->dev, "%s: still busy\n", dep->name);
-		return 0;
-	}
-
-	trb_hw = dwc->ep0_trb;
-	memset(&trb, 0, sizeof(trb));
-
-	trb.trbctl = type;
-	trb.bplh = buf_dma;
-	trb.length = len;
-
-	trb.hwo	= 1;
-	trb.lst	= 1;
-	trb.ioc	= 1;
-	trb.isp_imi = 1;
-
-	dwc3_trb_to_hw(&trb, trb_hw);
-
-	memset(&params, 0, sizeof(params));
-	params.param0 = upper_32_bits(dwc->ep0_trb_addr);
-	params.param1 = lower_32_bits(dwc->ep0_trb_addr);
-
-	ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
-			DWC3_DEPCMD_STARTTRANSFER, &params);
-	if (ret < 0) {
-		dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
-		return ret;
-	}
-
-	dep->flags |= DWC3_EP_BUSY;
-	dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
-			dep->number);
-
-	dwc->ep0_next_event = DWC3_EP0_COMPLETE;
-
-	return 0;
-}
-
-static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
-		struct dwc3_request *req)
-{
-	int			ret = 0;
-
-	req->request.actual	= 0;
-	req->request.status	= -EINPROGRESS;
-	req->epnum		= dep->number;
-
-	list_add_tail(&req->list, &dep->request_list);
-
-	/*
-	 * Gadget driver might not be quick enough to queue a request
-	 * before we get a Transfer Not Ready event on this endpoint.
-	 *
-	 * In that case, we will set DWC3_EP_PENDING_REQUEST. When that
-	 * flag is set, it's telling us that as soon as Gadget queues the
-	 * required request, we should kick the transfer here because the
-	 * IRQ we were waiting for is long gone.
-	 */
-	if (dep->flags & DWC3_EP_PENDING_REQUEST) {
-		struct dwc3	*dwc = dep->dwc;
-		unsigned	direction;
-		u32		type;
-
-		direction = !!(dep->flags & DWC3_EP0_DIR_IN);
-
-		if (dwc->ep0state == EP0_STATUS_PHASE) {
-			type = dwc->three_stage_setup
-				? DWC3_TRBCTL_CONTROL_STATUS3
-				: DWC3_TRBCTL_CONTROL_STATUS2;
-		} else if (dwc->ep0state == EP0_DATA_PHASE) {
-			type = DWC3_TRBCTL_CONTROL_DATA;
-		} else {
-			/* should never happen */
-			WARN_ON(1);
-			return 0;
-		}
-
-		ret = dwc3_ep0_start_trans(dwc, direction,
-				req->request.dma, req->request.length, type);
-		dep->flags &= ~(DWC3_EP_PENDING_REQUEST |
-				DWC3_EP0_DIR_IN);
-	}
-
-	return ret;
-}
-
-int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
-		gfp_t gfp_flags)
-{
-	struct dwc3_request		*req = to_dwc3_request(request);
-	struct dwc3_ep			*dep = to_dwc3_ep(ep);
-	struct dwc3			*dwc = dep->dwc;
-
-	unsigned long			flags;
-
-	int				ret;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	if (!dep->desc) {
-		dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
-				request, dep->name);
-		ret = -ESHUTDOWN;
-		goto out;
-	}
-
-	/* we share one TRB for ep0/1 */
-	if (!list_empty(&dwc->eps[0]->request_list) ||
-			!list_empty(&dwc->eps[1]->request_list) ||
-			dwc->ep0_status_pending) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	dev_vdbg(dwc->dev, "queueing request %p to %s length %d, state '%s'\n",
-			request, dep->name, request->length,
-			dwc3_ep0_state_string(dwc->ep0state));
-
-	ret = __dwc3_gadget_ep0_queue(dep, req);
-
-out:
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
-{
-	struct dwc3_ep		*dep = dwc->eps[0];
-
-	/* stall is always issued on EP0 */
-	__dwc3_gadget_ep_set_halt(dwc->eps[0], 1);
-	dwc->eps[0]->flags = DWC3_EP_ENABLED;
-
-	if (!list_empty(&dep->request_list)) {
-		struct dwc3_request	*req;
-
-		req = next_request(&dep->request_list);
-		dwc3_gadget_giveback(dep, req, -ECONNRESET);
-	}
-
-	dwc->ep0state = EP0_SETUP_PHASE;
-	dwc3_ep0_out_start(dwc);
-}
-
-void dwc3_ep0_out_start(struct dwc3 *dwc)
-{
-	int				ret;
-
-	ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
-			DWC3_TRBCTL_CONTROL_SETUP);
-	WARN_ON(ret < 0);
-}
-
-static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
-{
-	struct dwc3_ep		*dep;
-	u32			windex = le16_to_cpu(wIndex_le);
-	u32			epnum;
-
-	epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1;
-	if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
-		epnum |= 1;
-
-	dep = dwc->eps[epnum];
-	if (dep->flags & DWC3_EP_ENABLED)
-		return dep;
-
-	return NULL;
-}
-
-static void dwc3_ep0_send_status_response(struct dwc3 *dwc)
-{
-	dwc3_ep0_start_trans(dwc, 1, dwc->setup_buf_addr,
-			dwc->ep0_usb_req.length,
-			DWC3_TRBCTL_CONTROL_DATA);
-}
-
-/*
- * ch 9.4.5
- */
-static int dwc3_ep0_handle_status(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
-	struct dwc3_ep		*dep;
-	u32			recip;
-	u16			usb_status = 0;
-	__le16			*response_pkt;
-
-	recip = ctrl->bRequestType & USB_RECIP_MASK;
-	switch (recip) {
-	case USB_RECIP_DEVICE:
-		/*
-		 * We are self-powered. U1/U2/LTM will be set later
-		 * once we handle this states. RemoteWakeup is 0 on SS
-		 */
-		usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED;
-		break;
-
-	case USB_RECIP_INTERFACE:
-		/*
-		 * Function Remote Wake Capable	D0
-		 * Function Remote Wakeup	D1
-		 */
-		break;
-
-	case USB_RECIP_ENDPOINT:
-		dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
-		if (!dep)
-		       return -EINVAL;
-
-		if (dep->flags & DWC3_EP_STALL)
-			usb_status = 1 << USB_ENDPOINT_HALT;
-		break;
-	default:
-		return -EINVAL;
-	};
-
-	response_pkt = (__le16 *) dwc->setup_buf;
-	*response_pkt = cpu_to_le16(usb_status);
-	dwc->ep0_usb_req.length = sizeof(*response_pkt);
-	dwc->ep0_status_pending = 1;
-
-	return 0;
-}
-
-static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
-		struct usb_ctrlrequest *ctrl, int set)
-{
-	struct dwc3_ep		*dep;
-	u32			recip;
-	u32			wValue;
-	u32			wIndex;
-	u32			reg;
-	int			ret;
-	u32			mode;
-
-	wValue = le16_to_cpu(ctrl->wValue);
-	wIndex = le16_to_cpu(ctrl->wIndex);
-	recip = ctrl->bRequestType & USB_RECIP_MASK;
-	switch (recip) {
-	case USB_RECIP_DEVICE:
-
-		/*
-		 * 9.4.1 says only only for SS, in AddressState only for
-		 * default control pipe
-		 */
-		switch (wValue) {
-		case USB_DEVICE_U1_ENABLE:
-		case USB_DEVICE_U2_ENABLE:
-		case USB_DEVICE_LTM_ENABLE:
-			if (dwc->dev_state != DWC3_CONFIGURED_STATE)
-				return -EINVAL;
-			if (dwc->speed != DWC3_DSTS_SUPERSPEED)
-				return -EINVAL;
-		}
-
-		/* XXX add U[12] & LTM */
-		switch (wValue) {
-		case USB_DEVICE_REMOTE_WAKEUP:
-			break;
-		case USB_DEVICE_U1_ENABLE:
-			break;
-		case USB_DEVICE_U2_ENABLE:
-			break;
-		case USB_DEVICE_LTM_ENABLE:
-			break;
-
-		case USB_DEVICE_TEST_MODE:
-			if ((wIndex & 0xff) != 0)
-				return -EINVAL;
-			if (!set)
-				return -EINVAL;
-
-			mode = wIndex >> 8;
-			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-			reg &= ~DWC3_DCTL_TSTCTRL_MASK;
-
-			switch (mode) {
-			case TEST_J:
-			case TEST_K:
-			case TEST_SE0_NAK:
-			case TEST_PACKET:
-			case TEST_FORCE_EN:
-				reg |= mode << 1;
-				break;
-			default:
-				return -EINVAL;
-			}
-			dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-
-	case USB_RECIP_INTERFACE:
-		switch (wValue) {
-		case USB_INTRF_FUNC_SUSPEND:
-			if (wIndex & USB_INTRF_FUNC_SUSPEND_LP)
-				/* XXX enable Low power suspend */
-				;
-			if (wIndex & USB_INTRF_FUNC_SUSPEND_RW)
-				/* XXX enable remote wakeup */
-				;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-
-	case USB_RECIP_ENDPOINT:
-		switch (wValue) {
-		case USB_ENDPOINT_HALT:
-
-			dep =  dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
-			if (!dep)
-				return -EINVAL;
-			ret = __dwc3_gadget_ep_set_halt(dep, set);
-			if (ret)
-				return -EINVAL;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-
-	default:
-		return -EINVAL;
-	};
-
-	return 0;
-}
-
-static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
-	u32 addr;
-	u32 reg;
-
-	addr = le16_to_cpu(ctrl->wValue);
-	if (addr > 127)
-		return -EINVAL;
-
-	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
-	reg &= ~(DWC3_DCFG_DEVADDR_MASK);
-	reg |= DWC3_DCFG_DEVADDR(addr);
-	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
-	if (addr)
-		dwc->dev_state = DWC3_ADDRESS_STATE;
-	else
-		dwc->dev_state = DWC3_DEFAULT_STATE;
-
-	return 0;
-}
-
-static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
-	int ret;
-
-	spin_unlock(&dwc->lock);
-	ret = dwc->gadget_driver->setup(&dwc->gadget, ctrl);
-	spin_lock(&dwc->lock);
-	return ret;
-}
-
-static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
-	u32 cfg;
-	int ret;
-
-	dwc->start_config_issued = false;
-	cfg = le16_to_cpu(ctrl->wValue);
-
-	switch (dwc->dev_state) {
-	case DWC3_DEFAULT_STATE:
-		return -EINVAL;
-		break;
-
-	case DWC3_ADDRESS_STATE:
-		ret = dwc3_ep0_delegate_req(dwc, ctrl);
-		/* if the cfg matches and the cfg is non zero */
-		if (!ret && cfg)
-			dwc->dev_state = DWC3_CONFIGURED_STATE;
-		break;
-
-	case DWC3_CONFIGURED_STATE:
-		ret = dwc3_ep0_delegate_req(dwc, ctrl);
-		if (!cfg)
-			dwc->dev_state = DWC3_ADDRESS_STATE;
-		break;
-	}
-	return 0;
-}
-
-static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
-	int ret;
-
-	switch (ctrl->bRequest) {
-	case USB_REQ_GET_STATUS:
-		dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n");
-		ret = dwc3_ep0_handle_status(dwc, ctrl);
-		break;
-	case USB_REQ_CLEAR_FEATURE:
-		dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n");
-		ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
-		break;
-	case USB_REQ_SET_FEATURE:
-		dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n");
-		ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
-		break;
-	case USB_REQ_SET_ADDRESS:
-		dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n");
-		ret = dwc3_ep0_set_address(dwc, ctrl);
-		break;
-	case USB_REQ_SET_CONFIGURATION:
-		dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");
-		ret = dwc3_ep0_set_config(dwc, ctrl);
-		break;
-	default:
-		dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
-		ret = dwc3_ep0_delegate_req(dwc, ctrl);
-		break;
-	};
-
-	return ret;
-}
-
-static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	struct usb_ctrlrequest *ctrl = dwc->ctrl_req;
-	int ret;
-	u32 len;
-
-	if (!dwc->gadget_driver)
-		goto err;
-
-	len = le16_to_cpu(ctrl->wLength);
-	if (!len) {
-		dwc->three_stage_setup = false;
-		dwc->ep0_expect_in = false;
-		dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
-	} else {
-		dwc->three_stage_setup = true;
-		dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN);
-		dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
-	}
-
-	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
-		ret = dwc3_ep0_std_request(dwc, ctrl);
-	else
-		ret = dwc3_ep0_delegate_req(dwc, ctrl);
-
-	if (ret >= 0)
-		return;
-
-err:
-	dwc3_ep0_stall_and_restart(dwc);
-}
-
-static void dwc3_ep0_complete_data(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	struct dwc3_request	*r = NULL;
-	struct usb_request	*ur;
-	struct dwc3_trb		trb;
-	struct dwc3_ep		*dep;
-	u32			transferred;
-	u8			epnum;
-
-	epnum = event->endpoint_number;
-	dep = dwc->eps[epnum];
-
-	dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
-
-	if (!dwc->ep0_status_pending) {
-		r = next_request(&dwc->eps[0]->request_list);
-		ur = &r->request;
-	} else {
-		ur = &dwc->ep0_usb_req;
-		dwc->ep0_status_pending = 0;
-	}
-
-	dwc3_trb_to_nat(dwc->ep0_trb, &trb);
-
-	if (dwc->ep0_bounced) {
-		struct dwc3_ep	*ep0 = dwc->eps[0];
-
-		transferred = min_t(u32, ur->length,
-				ep0->endpoint.maxpacket - trb.length);
-		memcpy(ur->buf, dwc->ep0_bounce, transferred);
-		dwc->ep0_bounced = false;
-	} else {
-		transferred = ur->length - trb.length;
-		ur->actual += transferred;
-	}
-
-	if ((epnum & 1) && ur->actual < ur->length) {
-		/* for some reason we did not get everything out */
-
-		dwc3_ep0_stall_and_restart(dwc);
-	} else {
-		/*
-		 * handle the case where we have to send a zero packet. This
-		 * seems to be case when req.length > maxpacket. Could it be?
-		 */
-		if (r)
-			dwc3_gadget_giveback(dep, r, 0);
-	}
-}
-
-static void dwc3_ep0_complete_req(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	struct dwc3_request	*r;
-	struct dwc3_ep		*dep;
-
-	dep = dwc->eps[0];
-
-	if (!list_empty(&dep->request_list)) {
-		r = next_request(&dep->request_list);
-
-		dwc3_gadget_giveback(dep, r, 0);
-	}
-
-	dwc->ep0state = EP0_SETUP_PHASE;
-	dwc3_ep0_out_start(dwc);
-}
-
-static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
-			const struct dwc3_event_depevt *event)
-{
-	struct dwc3_ep		*dep = dwc->eps[event->endpoint_number];
-
-	dep->flags &= ~DWC3_EP_BUSY;
-
-	switch (dwc->ep0state) {
-	case EP0_SETUP_PHASE:
-		dev_vdbg(dwc->dev, "Inspecting Setup Bytes\n");
-		dwc3_ep0_inspect_setup(dwc, event);
-		break;
-
-	case EP0_DATA_PHASE:
-		dev_vdbg(dwc->dev, "Data Phase\n");
-		dwc3_ep0_complete_data(dwc, event);
-		break;
-
-	case EP0_STATUS_PHASE:
-		dev_vdbg(dwc->dev, "Status Phase\n");
-		dwc3_ep0_complete_req(dwc, event);
-		break;
-	default:
-		WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state);
-	}
-}
-
-static void dwc3_ep0_do_control_setup(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	dwc->ep0state = EP0_SETUP_PHASE;
-	dwc3_ep0_out_start(dwc);
-}
-
-static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	struct dwc3_ep		*dep;
-	struct dwc3_request	*req;
-	int			ret;
-
-	dep = dwc->eps[0];
-	dwc->ep0state = EP0_DATA_PHASE;
-
-	if (dwc->ep0_status_pending) {
-		dwc3_ep0_send_status_response(dwc);
-		return;
-	}
-
-	if (list_empty(&dep->request_list)) {
-		dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n");
-		dep->flags |= DWC3_EP_PENDING_REQUEST;
-
-		if (event->endpoint_number)
-			dep->flags |= DWC3_EP0_DIR_IN;
-		return;
-	}
-
-	req = next_request(&dep->request_list);
-	req->direction = !!event->endpoint_number;
-
-	dwc->ep0state = EP0_DATA_PHASE;
-	if (req->request.length == 0) {
-		ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
-				dwc->ctrl_req_addr, 0,
-				DWC3_TRBCTL_CONTROL_DATA);
-	} else if ((req->request.length % dep->endpoint.maxpacket)
-			&& (event->endpoint_number == 0)) {
-		dwc3_map_buffer_to_dma(req);
-
-		WARN_ON(req->request.length > dep->endpoint.maxpacket);
-
-		dwc->ep0_bounced = true;
-
-		/*
-		 * REVISIT in case request length is bigger than EP0
-		 * wMaxPacketSize, we will need two chained TRBs to handle
-		 * the transfer.
-		 */
-		ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
-				dwc->ep0_bounce_addr, dep->endpoint.maxpacket,
-				DWC3_TRBCTL_CONTROL_DATA);
-	} else {
-		dwc3_map_buffer_to_dma(req);
-
-		ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
-				req->request.dma, req->request.length,
-				DWC3_TRBCTL_CONTROL_DATA);
-	}
-
-	WARN_ON(ret < 0);
-}
-
-static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	u32			type;
-	int			ret;
-
-	dwc->ep0state = EP0_STATUS_PHASE;
-
-	type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3
-		: DWC3_TRBCTL_CONTROL_STATUS2;
-
-	ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
-			dwc->ctrl_req_addr, 0, type);
-
-	WARN_ON(ret < 0);
-}
-
-static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	switch (event->status) {
-	case DEPEVT_STATUS_CONTROL_SETUP:
-		dev_vdbg(dwc->dev, "Control Setup\n");
-		dwc3_ep0_do_control_setup(dwc, event);
-		break;
-
-	case DEPEVT_STATUS_CONTROL_DATA:
-		dev_vdbg(dwc->dev, "Control Data\n");
-
-		if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) {
-			dev_vdbg(dwc->dev, "Expected %d got %d\n",
-					dwc->ep0_next_event,
-					DWC3_EP0_NRDY_DATA);
-
-			dwc3_ep0_stall_and_restart(dwc);
-			return;
-		}
-
-		/*
-		 * One of the possible error cases is when Host _does_
-		 * request for Data Phase, but it does so on the wrong
-		 * direction.
-		 *
-		 * Here, we already know ep0_next_event is DATA (see above),
-		 * so we only need to check for direction.
-		 */
-		if (dwc->ep0_expect_in != event->endpoint_number) {
-			dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
-			dwc3_ep0_stall_and_restart(dwc);
-			return;
-		}
-
-		dwc3_ep0_do_control_data(dwc, event);
-		break;
-
-	case DEPEVT_STATUS_CONTROL_STATUS:
-		dev_vdbg(dwc->dev, "Control Status\n");
-
-		if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) {
-			dev_vdbg(dwc->dev, "Expected %d got %d\n",
-					dwc->ep0_next_event,
-					DWC3_EP0_NRDY_STATUS);
-
-			dwc3_ep0_stall_and_restart(dwc);
-			return;
-		}
-		dwc3_ep0_do_control_status(dwc, event);
-	}
-}
-
-void dwc3_ep0_interrupt(struct dwc3 *dwc,
-		const const struct dwc3_event_depevt *event)
-{
-	u8			epnum = event->endpoint_number;
-
-	dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n",
-			dwc3_ep_event_string(event->endpoint_event),
-			epnum >> 1, (epnum & 1) ? "in" : "out",
-			dwc3_ep0_state_string(dwc->ep0state));
-
-	switch (event->endpoint_event) {
-	case DWC3_DEPEVT_XFERCOMPLETE:
-		dwc3_ep0_xfer_complete(dwc, event);
-		break;
-
-	case DWC3_DEPEVT_XFERNOTREADY:
-		dwc3_ep0_xfernotready(dwc, event);
-		break;
-
-	case DWC3_DEPEVT_XFERINPROGRESS:
-	case DWC3_DEPEVT_RXTXFIFOEVT:
-	case DWC3_DEPEVT_STREAMEVT:
-	case DWC3_DEPEVT_EPCMDCMPLT:
-		break;
-	}
-}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
deleted file mode 100644
index fa824cf..0000000
--- a/drivers/usb/dwc3/gadget.c
+++ /dev/null
@@ -1,2104 +0,0 @@
-/**
- * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-#define	DMA_ADDR_INVALID	(~(dma_addr_t)0)
-
-void dwc3_map_buffer_to_dma(struct dwc3_request *req)
-{
-	struct dwc3			*dwc = req->dep->dwc;
-
-	if (req->request.length == 0) {
-		/* req->request.dma = dwc->setup_buf_addr; */
-		return;
-	}
-
-	if (req->request.dma == DMA_ADDR_INVALID) {
-		req->request.dma = dma_map_single(dwc->dev, req->request.buf,
-				req->request.length, req->direction
-				? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-		req->mapped = true;
-	}
-}
-
-void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
-{
-	struct dwc3			*dwc = req->dep->dwc;
-
-	if (req->request.length == 0) {
-		req->request.dma = DMA_ADDR_INVALID;
-		return;
-	}
-
-	if (req->mapped) {
-		dma_unmap_single(dwc->dev, req->request.dma,
-				req->request.length, req->direction
-				? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-		req->mapped = 0;
-		req->request.dma = DMA_ADDR_INVALID;
-	}
-}
-
-void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
-		int status)
-{
-	struct dwc3			*dwc = dep->dwc;
-
-	if (req->queued) {
-		dep->busy_slot++;
-		/*
-		 * Skip LINK TRB. We can't use req->trb and check for
-		 * DWC3_TRBCTL_LINK_TRB because it points the TRB we just
-		 * completed (not the LINK TRB).
-		 */
-		if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
-				usb_endpoint_xfer_isoc(dep->desc))
-			dep->busy_slot++;
-	}
-	list_del(&req->list);
-
-	if (req->request.status == -EINPROGRESS)
-		req->request.status = status;
-
-	dwc3_unmap_buffer_from_dma(req);
-
-	dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
-			req, dep->name, req->request.actual,
-			req->request.length, status);
-
-	spin_unlock(&dwc->lock);
-	req->request.complete(&req->dep->endpoint, &req->request);
-	spin_lock(&dwc->lock);
-}
-
-static const char *dwc3_gadget_ep_cmd_string(u8 cmd)
-{
-	switch (cmd) {
-	case DWC3_DEPCMD_DEPSTARTCFG:
-		return "Start New Configuration";
-	case DWC3_DEPCMD_ENDTRANSFER:
-		return "End Transfer";
-	case DWC3_DEPCMD_UPDATETRANSFER:
-		return "Update Transfer";
-	case DWC3_DEPCMD_STARTTRANSFER:
-		return "Start Transfer";
-	case DWC3_DEPCMD_CLEARSTALL:
-		return "Clear Stall";
-	case DWC3_DEPCMD_SETSTALL:
-		return "Set Stall";
-	case DWC3_DEPCMD_GETSEQNUMBER:
-		return "Get Data Sequence Number";
-	case DWC3_DEPCMD_SETTRANSFRESOURCE:
-		return "Set Endpoint Transfer Resource";
-	case DWC3_DEPCMD_SETEPCONFIG:
-		return "Set Endpoint Configuration";
-	default:
-		return "UNKNOWN command";
-	}
-}
-
-int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
-		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
-{
-	struct dwc3_ep		*dep = dwc->eps[ep];
-	u32			timeout = 500;
-	u32			reg;
-
-	dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n",
-			dep->name,
-			dwc3_gadget_ep_cmd_string(cmd), params->param0,
-			params->param1, params->param2);
-
-	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
-	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
-	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
-
-	dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);
-	do {
-		reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep));
-		if (!(reg & DWC3_DEPCMD_CMDACT)) {
-			dev_vdbg(dwc->dev, "Command Complete --> %d\n",
-					DWC3_DEPCMD_STATUS(reg));
-			return 0;
-		}
-
-		/*
-		 * We can't sleep here, because it is also called from
-		 * interrupt context.
-		 */
-		timeout--;
-		if (!timeout)
-			return -ETIMEDOUT;
-
-		udelay(1);
-	} while (1);
-}
-
-static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
-		struct dwc3_trb_hw *trb)
-{
-	u32		offset = (char *) trb - (char *) dep->trb_pool;
-
-	return dep->trb_pool_dma + offset;
-}
-
-static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
-{
-	struct dwc3		*dwc = dep->dwc;
-
-	if (dep->trb_pool)
-		return 0;
-
-	if (dep->number == 0 || dep->number == 1)
-		return 0;
-
-	dep->trb_pool = dma_alloc_coherent(dwc->dev,
-			sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
-			&dep->trb_pool_dma, GFP_KERNEL);
-	if (!dep->trb_pool) {
-		dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n",
-				dep->name);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void dwc3_free_trb_pool(struct dwc3_ep *dep)
-{
-	struct dwc3		*dwc = dep->dwc;
-
-	dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
-			dep->trb_pool, dep->trb_pool_dma);
-
-	dep->trb_pool = NULL;
-	dep->trb_pool_dma = 0;
-}
-
-static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
-{
-	struct dwc3_gadget_ep_cmd_params params;
-	u32			cmd;
-
-	memset(&params, 0x00, sizeof(params));
-
-	if (dep->number != 1) {
-		cmd = DWC3_DEPCMD_DEPSTARTCFG;
-		/* XferRscIdx == 0 for ep0 and 2 for the remaining */
-		if (dep->number > 1) {
-			if (dwc->start_config_issued)
-				return 0;
-			dwc->start_config_issued = true;
-			cmd |= DWC3_DEPCMD_PARAM(2);
-		}
-
-		return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
-	}
-
-	return 0;
-}
-
-static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
-		const struct usb_endpoint_descriptor *desc)
-{
-	struct dwc3_gadget_ep_cmd_params params;
-
-	memset(&params, 0x00, sizeof(params));
-
-	params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc))
-		| DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc))
-		| DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst);
-
-	params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN
-		| DWC3_DEPCFG_XFER_NOT_READY_EN;
-
-	if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) {
-		params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE
-			| DWC3_DEPCFG_STREAM_EVENT_EN;
-		dep->stream_capable = true;
-	}
-
-	if (usb_endpoint_xfer_isoc(desc))
-		params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;
-
-	/*
-	 * We are doing 1:1 mapping for endpoints, meaning
-	 * Physical Endpoints 2 maps to Logical Endpoint 2 and
-	 * so on. We consider the direction bit as part of the physical
-	 * endpoint number. So USB endpoint 0x81 is 0x03.
-	 */
-	params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number);
-
-	/*
-	 * We must use the lower 16 TX FIFOs even though
-	 * HW might have more
-	 */
-	if (dep->direction)
-		params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(dep->number >> 1);
-
-	if (desc->bInterval) {
-		params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(desc->bInterval - 1);
-		dep->interval = 1 << (desc->bInterval - 1);
-	}
-
-	return dwc3_send_gadget_ep_cmd(dwc, dep->number,
-			DWC3_DEPCMD_SETEPCONFIG, &params);
-}
-
-static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep)
-{
-	struct dwc3_gadget_ep_cmd_params params;
-
-	memset(&params, 0x00, sizeof(params));
-
-	params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1);
-
-	return dwc3_send_gadget_ep_cmd(dwc, dep->number,
-			DWC3_DEPCMD_SETTRANSFRESOURCE, &params);
-}
-
-/**
- * __dwc3_gadget_ep_enable - Initializes a HW endpoint
- * @dep: endpoint to be initialized
- * @desc: USB Endpoint Descriptor
- *
- * Caller should take care of locking
- */
-static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
-		const struct usb_endpoint_descriptor *desc)
-{
-	struct dwc3		*dwc = dep->dwc;
-	u32			reg;
-	int			ret = -ENOMEM;
-
-	if (!(dep->flags & DWC3_EP_ENABLED)) {
-		ret = dwc3_gadget_start_config(dwc, dep);
-		if (ret)
-			return ret;
-	}
-
-	ret = dwc3_gadget_set_ep_config(dwc, dep, desc);
-	if (ret)
-		return ret;
-
-	if (!(dep->flags & DWC3_EP_ENABLED)) {
-		struct dwc3_trb_hw	*trb_st_hw;
-		struct dwc3_trb_hw	*trb_link_hw;
-		struct dwc3_trb		trb_link;
-
-		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
-		if (ret)
-			return ret;
-
-		dep->desc = desc;
-		dep->type = usb_endpoint_type(desc);
-		dep->flags |= DWC3_EP_ENABLED;
-
-		reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
-		reg |= DWC3_DALEPENA_EP(dep->number);
-		dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
-
-		if (!usb_endpoint_xfer_isoc(desc))
-			return 0;
-
-		memset(&trb_link, 0, sizeof(trb_link));
-
-		/* Link TRB for ISOC. The HWO but is never reset */
-		trb_st_hw = &dep->trb_pool[0];
-
-		trb_link.bplh = dwc3_trb_dma_offset(dep, trb_st_hw);
-		trb_link.trbctl = DWC3_TRBCTL_LINK_TRB;
-		trb_link.hwo = true;
-
-		trb_link_hw = &dep->trb_pool[DWC3_TRB_NUM - 1];
-		dwc3_trb_to_hw(&trb_link, trb_link_hw);
-	}
-
-	return 0;
-}
-
-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum);
-static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
-{
-	struct dwc3_request		*req;
-
-	if (!list_empty(&dep->req_queued))
-		dwc3_stop_active_transfer(dwc, dep->number);
-
-	while (!list_empty(&dep->request_list)) {
-		req = next_request(&dep->request_list);
-
-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
-	}
-}
-
-/**
- * __dwc3_gadget_ep_disable - Disables a HW endpoint
- * @dep: the endpoint to disable
- *
- * This function also removes requests which are currently processed ny the
- * hardware and those which are not yet scheduled.
- * Caller should take care of locking.
- */
-static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
-{
-	struct dwc3		*dwc = dep->dwc;
-	u32			reg;
-
-	dwc3_remove_requests(dwc, dep);
-
-	reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
-	reg &= ~DWC3_DALEPENA_EP(dep->number);
-	dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
-
-	dep->stream_capable = false;
-	dep->desc = NULL;
-	dep->type = 0;
-	dep->flags = 0;
-
-	return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-static int dwc3_gadget_ep0_enable(struct usb_ep *ep,
-		const struct usb_endpoint_descriptor *desc)
-{
-	return -EINVAL;
-}
-
-static int dwc3_gadget_ep0_disable(struct usb_ep *ep)
-{
-	return -EINVAL;
-}
-
-/* -------------------------------------------------------------------------- */
-
-static int dwc3_gadget_ep_enable(struct usb_ep *ep,
-		const struct usb_endpoint_descriptor *desc)
-{
-	struct dwc3_ep			*dep;
-	struct dwc3			*dwc;
-	unsigned long			flags;
-	int				ret;
-
-	if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
-		pr_debug("dwc3: invalid parameters\n");
-		return -EINVAL;
-	}
-
-	if (!desc->wMaxPacketSize) {
-		pr_debug("dwc3: missing wMaxPacketSize\n");
-		return -EINVAL;
-	}
-
-	dep = to_dwc3_ep(ep);
-	dwc = dep->dwc;
-
-	switch (usb_endpoint_type(desc)) {
-	case USB_ENDPOINT_XFER_CONTROL:
-		strncat(dep->name, "-control", sizeof(dep->name));
-		break;
-	case USB_ENDPOINT_XFER_ISOC:
-		strncat(dep->name, "-isoc", sizeof(dep->name));
-		break;
-	case USB_ENDPOINT_XFER_BULK:
-		strncat(dep->name, "-bulk", sizeof(dep->name));
-		break;
-	case USB_ENDPOINT_XFER_INT:
-		strncat(dep->name, "-int", sizeof(dep->name));
-		break;
-	default:
-		dev_err(dwc->dev, "invalid endpoint transfer type\n");
-	}
-
-	if (dep->flags & DWC3_EP_ENABLED) {
-		dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n",
-				dep->name);
-		return 0;
-	}
-
-	dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	ret = __dwc3_gadget_ep_enable(dep, desc);
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static int dwc3_gadget_ep_disable(struct usb_ep *ep)
-{
-	struct dwc3_ep			*dep;
-	struct dwc3			*dwc;
-	unsigned long			flags;
-	int				ret;
-
-	if (!ep) {
-		pr_debug("dwc3: invalid parameters\n");
-		return -EINVAL;
-	}
-
-	dep = to_dwc3_ep(ep);
-	dwc = dep->dwc;
-
-	if (!(dep->flags & DWC3_EP_ENABLED)) {
-		dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n",
-				dep->name);
-		return 0;
-	}
-
-	snprintf(dep->name, sizeof(dep->name), "ep%d%s",
-			dep->number >> 1,
-			(dep->number & 1) ? "in" : "out");
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	ret = __dwc3_gadget_ep_disable(dep);
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
-	gfp_t gfp_flags)
-{
-	struct dwc3_request		*req;
-	struct dwc3_ep			*dep = to_dwc3_ep(ep);
-	struct dwc3			*dwc = dep->dwc;
-
-	req = kzalloc(sizeof(*req), gfp_flags);
-	if (!req) {
-		dev_err(dwc->dev, "not enough memory\n");
-		return NULL;
-	}
-
-	req->epnum	= dep->number;
-	req->dep	= dep;
-	req->request.dma = DMA_ADDR_INVALID;
-
-	return &req->request;
-}
-
-static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
-		struct usb_request *request)
-{
-	struct dwc3_request		*req = to_dwc3_request(request);
-
-	kfree(req);
-}
-
-/*
- * dwc3_prepare_trbs - setup TRBs from requests
- * @dep: endpoint for which requests are being prepared
- * @starting: true if the endpoint is idle and no requests are queued.
- *
- * The functions goes through the requests list and setups TRBs for the
- * transfers. The functions returns once there are not more TRBs available or
- * it run out of requests.
- */
-static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
-		bool starting)
-{
-	struct dwc3_request	*req, *n, *ret = NULL;
-	struct dwc3_trb_hw	*trb_hw;
-	struct dwc3_trb		trb;
-	u32			trbs_left;
-
-	BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
-
-	/* the first request must not be queued */
-	trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
-	/*
-	 * if busy & slot are equal than it is either full or empty. If we are
-	 * starting to proceed requests then we are empty. Otherwise we ar
-	 * full and don't do anything
-	 */
-	if (!trbs_left) {
-		if (!starting)
-			return NULL;
-		trbs_left = DWC3_TRB_NUM;
-		/*
-		 * In case we start from scratch, we queue the ISOC requests
-		 * starting from slot 1. This is done because we use ring
-		 * buffer and have no LST bit to stop us. Instead, we place
-		 * IOC bit TRB_NUM/4. We try to avoid to having an interrupt
-		 * after the first request so we start at slot 1 and have
-		 * 7 requests proceed before we hit the first IOC.
-		 * Other transfer types don't use the ring buffer and are
-		 * processed from the first TRB until the last one. Since we
-		 * don't wrap around we have to start at the beginning.
-		 */
-		if (usb_endpoint_xfer_isoc(dep->desc)) {
-			dep->busy_slot = 1;
-			dep->free_slot = 1;
-		} else {
-			dep->busy_slot = 0;
-			dep->free_slot = 0;
-		}
-	}
-
-	/* The last TRB is a link TRB, not used for xfer */
-	if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc))
-		return NULL;
-
-	list_for_each_entry_safe(req, n, &dep->request_list, list) {
-		unsigned int last_one = 0;
-		unsigned int cur_slot;
-
-		trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
-		cur_slot = dep->free_slot;
-		dep->free_slot++;
-
-		/* Skip the LINK-TRB on ISOC */
-		if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
-				usb_endpoint_xfer_isoc(dep->desc))
-			continue;
-
-		dwc3_gadget_move_request_queued(req);
-		memset(&trb, 0, sizeof(trb));
-		trbs_left--;
-
-		/* Is our TRB pool empty? */
-		if (!trbs_left)
-			last_one = 1;
-		/* Is this the last request? */
-		if (list_empty(&dep->request_list))
-			last_one = 1;
-
-		/*
-		 * FIXME we shouldn't need to set LST bit always but we are
-		 * facing some weird problem with the Hardware where it doesn't
-		 * complete even though it has been previously started.
-		 *
-		 * While we're debugging the problem, as a workaround to
-		 * multiple TRBs handling, use only one TRB at a time.
-		 */
-		last_one = 1;
-
-		req->trb = trb_hw;
-		if (!ret)
-			ret = req;
-
-		trb.bplh = req->request.dma;
-
-		if (usb_endpoint_xfer_isoc(dep->desc)) {
-			trb.isp_imi = true;
-			trb.csp = true;
-		} else {
-			trb.lst = last_one;
-		}
-
-		if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
-			trb.sid_sofn = req->request.stream_id;
-
-		switch (usb_endpoint_type(dep->desc)) {
-		case USB_ENDPOINT_XFER_CONTROL:
-			trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
-			break;
-
-		case USB_ENDPOINT_XFER_ISOC:
-			trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
-
-			/* IOC every DWC3_TRB_NUM / 4 so we can refill */
-			if (!(cur_slot % (DWC3_TRB_NUM / 4)))
-				trb.ioc = last_one;
-			break;
-
-		case USB_ENDPOINT_XFER_BULK:
-		case USB_ENDPOINT_XFER_INT:
-			trb.trbctl = DWC3_TRBCTL_NORMAL;
-			break;
-		default:
-			/*
-			 * This is only possible with faulty memory because we
-			 * checked it already :)
-			 */
-			BUG();
-		}
-
-		trb.length	= req->request.length;
-		trb.hwo = true;
-
-		dwc3_trb_to_hw(&trb, trb_hw);
-		req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);
-
-		if (last_one)
-			break;
-	}
-
-	return ret;
-}
-
-static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
-		int start_new)
-{
-	struct dwc3_gadget_ep_cmd_params params;
-	struct dwc3_request		*req;
-	struct dwc3			*dwc = dep->dwc;
-	int				ret;
-	u32				cmd;
-
-	if (start_new && (dep->flags & DWC3_EP_BUSY)) {
-		dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name);
-		return -EBUSY;
-	}
-	dep->flags &= ~DWC3_EP_PENDING_REQUEST;
-
-	/*
-	 * If we are getting here after a short-out-packet we don't enqueue any
-	 * new requests as we try to set the IOC bit only on the last request.
-	 */
-	if (start_new) {
-		if (list_empty(&dep->req_queued))
-			dwc3_prepare_trbs(dep, start_new);
-
-		/* req points to the first request which will be sent */
-		req = next_request(&dep->req_queued);
-	} else {
-		/*
-		 * req points to the first request where HWO changed
-		 * from 0 to 1
-		 */
-		req = dwc3_prepare_trbs(dep, start_new);
-	}
-	if (!req) {
-		dep->flags |= DWC3_EP_PENDING_REQUEST;
-		return 0;
-	}
-
-	memset(&params, 0, sizeof(params));
-	params.param0 = upper_32_bits(req->trb_dma);
-	params.param1 = lower_32_bits(req->trb_dma);
-
-	if (start_new)
-		cmd = DWC3_DEPCMD_STARTTRANSFER;
-	else
-		cmd = DWC3_DEPCMD_UPDATETRANSFER;
-
-	cmd |= DWC3_DEPCMD_PARAM(cmd_param);
-	ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
-	if (ret < 0) {
-		dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
-
-		/*
-		 * FIXME we need to iterate over the list of requests
-		 * here and stop, unmap, free and del each of the linked
-		 * requests instead of we do now.
-		 */
-		dwc3_unmap_buffer_from_dma(req);
-		list_del(&req->list);
-		return ret;
-	}
-
-	dep->flags |= DWC3_EP_BUSY;
-	dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
-			dep->number);
-	if (!dep->res_trans_idx)
-		printk_once(KERN_ERR "%s() res_trans_idx is invalid\n", __func__);
-	return 0;
-}
-
-static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
-{
-	req->request.actual	= 0;
-	req->request.status	= -EINPROGRESS;
-	req->direction		= dep->direction;
-	req->epnum		= dep->number;
-
-	/*
-	 * We only add to our list of requests now and
-	 * start consuming the list once we get XferNotReady
-	 * IRQ.
-	 *
-	 * That way, we avoid doing anything that we don't need
-	 * to do now and defer it until the point we receive a
-	 * particular token from the Host side.
-	 *
-	 * This will also avoid Host cancelling URBs due to too
-	 * many NACKs.
-	 */
-	dwc3_map_buffer_to_dma(req);
-	list_add_tail(&req->list, &dep->request_list);
-
-	/*
-	 * There is one special case: XferNotReady with
-	 * empty list of requests. We need to kick the
-	 * transfer here in that situation, otherwise
-	 * we will be NAKing forever.
-	 *
-	 * If we get XferNotReady before gadget driver
-	 * has a chance to queue a request, we will ACK
-	 * the IRQ but won't be able to receive the data
-	 * until the next request is queued. The following
-	 * code is handling exactly that.
-	 */
-	if (dep->flags & DWC3_EP_PENDING_REQUEST) {
-		int ret;
-		int start_trans;
-
-		start_trans = 1;
-		if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
-				dep->flags & DWC3_EP_BUSY)
-			start_trans = 0;
-
-		ret =  __dwc3_gadget_kick_transfer(dep, 0, start_trans);
-		if (ret && ret != -EBUSY) {
-			struct dwc3	*dwc = dep->dwc;
-
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-		}
-	};
-
-	return 0;
-}
-
-static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
-	gfp_t gfp_flags)
-{
-	struct dwc3_request		*req = to_dwc3_request(request);
-	struct dwc3_ep			*dep = to_dwc3_ep(ep);
-	struct dwc3			*dwc = dep->dwc;
-
-	unsigned long			flags;
-
-	int				ret;
-
-	if (!dep->desc) {
-		dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
-				request, ep->name);
-		return -ESHUTDOWN;
-	}
-
-	dev_vdbg(dwc->dev, "queing request %p to %s length %d\n",
-			request, ep->name, request->length);
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	ret = __dwc3_gadget_ep_queue(dep, req);
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
-		struct usb_request *request)
-{
-	struct dwc3_request		*req = to_dwc3_request(request);
-	struct dwc3_request		*r = NULL;
-
-	struct dwc3_ep			*dep = to_dwc3_ep(ep);
-	struct dwc3			*dwc = dep->dwc;
-
-	unsigned long			flags;
-	int				ret = 0;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	list_for_each_entry(r, &dep->request_list, list) {
-		if (r == req)
-			break;
-	}
-
-	if (r != req) {
-		list_for_each_entry(r, &dep->req_queued, list) {
-			if (r == req)
-				break;
-		}
-		if (r == req) {
-			/* wait until it is processed */
-			dwc3_stop_active_transfer(dwc, dep->number);
-			goto out0;
-		}
-		dev_err(dwc->dev, "request %p was not queued to %s\n",
-				request, ep->name);
-		ret = -EINVAL;
-		goto out0;
-	}
-
-	/* giveback the request */
-	dwc3_gadget_giveback(dep, req, -ECONNRESET);
-
-out0:
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
-{
-	struct dwc3_gadget_ep_cmd_params	params;
-	struct dwc3				*dwc = dep->dwc;
-	int					ret;
-
-	memset(&params, 0x00, sizeof(params));
-
-	if (value) {
-		if (dep->number == 0 || dep->number == 1) {
-			/*
-			 * Whenever EP0 is stalled, we will restart
-			 * the state machine, thus moving back to
-			 * Setup Phase
-			 */
-			dwc->ep0state = EP0_SETUP_PHASE;
-		}
-
-		ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
-			DWC3_DEPCMD_SETSTALL, &params);
-		if (ret)
-			dev_err(dwc->dev, "failed to %s STALL on %s\n",
-					value ? "set" : "clear",
-					dep->name);
-		else
-			dep->flags |= DWC3_EP_STALL;
-	} else {
-		if (dep->flags & DWC3_EP_WEDGE)
-			return 0;
-
-		ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
-			DWC3_DEPCMD_CLEARSTALL, &params);
-		if (ret)
-			dev_err(dwc->dev, "failed to %s STALL on %s\n",
-					value ? "set" : "clear",
-					dep->name);
-		else
-			dep->flags &= ~DWC3_EP_STALL;
-	}
-
-	return ret;
-}
-
-static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value)
-{
-	struct dwc3_ep			*dep = to_dwc3_ep(ep);
-	struct dwc3			*dwc = dep->dwc;
-
-	unsigned long			flags;
-
-	int				ret;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	if (usb_endpoint_xfer_isoc(dep->desc)) {
-		dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);
-		ret = -EINVAL;
-		goto out;
-	}
-
-	ret = __dwc3_gadget_ep_set_halt(dep, value);
-out:
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
-{
-	struct dwc3_ep			*dep = to_dwc3_ep(ep);
-
-	dep->flags |= DWC3_EP_WEDGE;
-
-	return dwc3_gadget_ep_set_halt(ep, 1);
-}
-
-/* -------------------------------------------------------------------------- */
-
-static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = {
-	.bLength	= USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType = USB_DT_ENDPOINT,
-	.bmAttributes	= USB_ENDPOINT_XFER_CONTROL,
-};
-
-static const struct usb_ep_ops dwc3_gadget_ep0_ops = {
-	.enable		= dwc3_gadget_ep0_enable,
-	.disable	= dwc3_gadget_ep0_disable,
-	.alloc_request	= dwc3_gadget_ep_alloc_request,
-	.free_request	= dwc3_gadget_ep_free_request,
-	.queue		= dwc3_gadget_ep0_queue,
-	.dequeue	= dwc3_gadget_ep_dequeue,
-	.set_halt	= dwc3_gadget_ep_set_halt,
-	.set_wedge	= dwc3_gadget_ep_set_wedge,
-};
-
-static const struct usb_ep_ops dwc3_gadget_ep_ops = {
-	.enable		= dwc3_gadget_ep_enable,
-	.disable	= dwc3_gadget_ep_disable,
-	.alloc_request	= dwc3_gadget_ep_alloc_request,
-	.free_request	= dwc3_gadget_ep_free_request,
-	.queue		= dwc3_gadget_ep_queue,
-	.dequeue	= dwc3_gadget_ep_dequeue,
-	.set_halt	= dwc3_gadget_ep_set_halt,
-	.set_wedge	= dwc3_gadget_ep_set_wedge,
-};
-
-/* -------------------------------------------------------------------------- */
-
-static int dwc3_gadget_get_frame(struct usb_gadget *g)
-{
-	struct dwc3		*dwc = gadget_to_dwc(g);
-	u32			reg;
-
-	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-	return DWC3_DSTS_SOFFN(reg);
-}
-
-static int dwc3_gadget_wakeup(struct usb_gadget *g)
-{
-	struct dwc3		*dwc = gadget_to_dwc(g);
-
-	unsigned long		timeout;
-	unsigned long		flags;
-
-	u32			reg;
-
-	int			ret = 0;
-
-	u8			link_state;
-	u8			speed;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	/*
-	 * According to the Databook Remote wakeup request should
-	 * be issued only when the device is in early suspend state.
-	 *
-	 * We can check that via USB Link State bits in DSTS register.
-	 */
-	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-
-	speed = reg & DWC3_DSTS_CONNECTSPD;
-	if (speed == DWC3_DSTS_SUPERSPEED) {
-		dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n");
-		ret = -EINVAL;
-		goto out;
-	}
-
-	link_state = DWC3_DSTS_USBLNKST(reg);
-
-	switch (link_state) {
-	case DWC3_LINK_STATE_RX_DET:	/* in HS, means Early Suspend */
-	case DWC3_LINK_STATE_U3:	/* in HS, means SUSPEND */
-		break;
-	default:
-		dev_dbg(dwc->dev, "can't wakeup from link state %d\n",
-				link_state);
-		ret = -EINVAL;
-		goto out;
-	}
-
-	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-
-	/*
-	 * Switch link state to Recovery. In HS/FS/LS this means
-	 * RemoteWakeup Request
-	 */
-	reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;
-	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-	/* wait for at least 2000us */
-	usleep_range(2000, 2500);
-
-	/* write zeroes to Link Change Request */
-	reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
-	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-	/* pool until Link State change to ON */
-	timeout = jiffies + msecs_to_jiffies(100);
-
-	while (!(time_after(jiffies, timeout))) {
-		reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-
-		/* in HS, means ON */
-		if (DWC3_DSTS_USBLNKST(reg) == DWC3_LINK_STATE_U0)
-			break;
-	}
-
-	if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) {
-		dev_err(dwc->dev, "failed to send remote wakeup\n");
-		ret = -EINVAL;
-	}
-
-out:
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
-		int is_selfpowered)
-{
-	struct dwc3		*dwc = gadget_to_dwc(g);
-
-	dwc->is_selfpowered = !!is_selfpowered;
-
-	return 0;
-}
-
-static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
-{
-	u32			reg;
-	u32			timeout = 500;
-
-	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-	if (is_on)
-		reg |= DWC3_DCTL_RUN_STOP;
-	else
-		reg &= ~DWC3_DCTL_RUN_STOP;
-
-	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-	do {
-		reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-		if (is_on) {
-			if (!(reg & DWC3_DSTS_DEVCTRLHLT))
-				break;
-		} else {
-			if (reg & DWC3_DSTS_DEVCTRLHLT)
-				break;
-		}
-		timeout--;
-		if (!timeout)
-			break;
-		udelay(1);
-	} while (1);
-
-	dev_vdbg(dwc->dev, "gadget %s data soft-%s\n",
-			dwc->gadget_driver
-			? dwc->gadget_driver->function : "no-function",
-			is_on ? "connect" : "disconnect");
-}
-
-static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
-{
-	struct dwc3		*dwc = gadget_to_dwc(g);
-	unsigned long		flags;
-
-	is_on = !!is_on;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	dwc3_gadget_run_stop(dwc, is_on);
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return 0;
-}
-
-static int dwc3_gadget_start(struct usb_gadget *g,
-		struct usb_gadget_driver *driver)
-{
-	struct dwc3		*dwc = gadget_to_dwc(g);
-	struct dwc3_ep		*dep;
-	unsigned long		flags;
-	int			ret = 0;
-	u32			reg;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	if (dwc->gadget_driver) {
-		dev_err(dwc->dev, "%s is already bound to %s\n",
-				dwc->gadget.name,
-				dwc->gadget_driver->driver.name);
-		ret = -EBUSY;
-		goto err0;
-	}
-
-	dwc->gadget_driver	= driver;
-	dwc->gadget.dev.driver	= &driver->driver;
-
-	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-
-	reg &= ~DWC3_GCTL_SCALEDOWN(3);
-	reg &= ~DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG);
-	reg &= ~DWC3_GCTL_DISSCRAMBLE;
-	reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
-
-	switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams0)) {
-	case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
-		reg &= ~DWC3_GCTL_DSBLCLKGTNG;
-		break;
-	default:
-		dev_dbg(dwc->dev, "No power optimization available\n");
-	}
-
-	/*
-	 * WORKAROUND: DWC3 revisions <1.90a have a bug
-	 * when The device fails to connect at SuperSpeed
-	 * and falls back to high-speed mode which causes
-	 * the device to enter in a Connect/Disconnect loop
-	 */
-	if (dwc->revision < DWC3_REVISION_190A)
-		reg |= DWC3_GCTL_U2RSTECN;
-
-	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
-	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
-	reg &= ~(DWC3_DCFG_SPEED_MASK);
-	reg |= DWC3_DCFG_SUPERSPEED;
-	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
-	dwc->start_config_issued = false;
-
-	/* Start with SuperSpeed Default */
-	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
-
-	dep = dwc->eps[0];
-	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
-		goto err0;
-	}
-
-	dep = dwc->eps[1];
-	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
-		goto err1;
-	}
-
-	/* begin to receive SETUP packets */
-	dwc->ep0state = EP0_SETUP_PHASE;
-	dwc3_ep0_out_start(dwc);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return 0;
-
-err1:
-	__dwc3_gadget_ep_disable(dwc->eps[0]);
-
-err0:
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return ret;
-}
-
-static int dwc3_gadget_stop(struct usb_gadget *g,
-		struct usb_gadget_driver *driver)
-{
-	struct dwc3		*dwc = gadget_to_dwc(g);
-	unsigned long		flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	__dwc3_gadget_ep_disable(dwc->eps[0]);
-	__dwc3_gadget_ep_disable(dwc->eps[1]);
-
-	dwc->gadget_driver	= NULL;
-	dwc->gadget.dev.driver	= NULL;
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return 0;
-}
-static const struct usb_gadget_ops dwc3_gadget_ops = {
-	.get_frame		= dwc3_gadget_get_frame,
-	.wakeup			= dwc3_gadget_wakeup,
-	.set_selfpowered	= dwc3_gadget_set_selfpowered,
-	.pullup			= dwc3_gadget_pullup,
-	.udc_start		= dwc3_gadget_start,
-	.udc_stop		= dwc3_gadget_stop,
-};
-
-/* -------------------------------------------------------------------------- */
-
-static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
-{
-	struct dwc3_ep			*dep;
-	u8				epnum;
-
-	INIT_LIST_HEAD(&dwc->gadget.ep_list);
-
-	for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
-		dep = kzalloc(sizeof(*dep), GFP_KERNEL);
-		if (!dep) {
-			dev_err(dwc->dev, "can't allocate endpoint %d\n",
-					epnum);
-			return -ENOMEM;
-		}
-
-		dep->dwc = dwc;
-		dep->number = epnum;
-		dwc->eps[epnum] = dep;
-
-		snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
-				(epnum & 1) ? "in" : "out");
-		dep->endpoint.name = dep->name;
-		dep->direction = (epnum & 1);
-
-		if (epnum == 0 || epnum == 1) {
-			dep->endpoint.maxpacket = 512;
-			dep->endpoint.ops = &dwc3_gadget_ep0_ops;
-			if (!epnum)
-				dwc->gadget.ep0 = &dep->endpoint;
-		} else {
-			int		ret;
-
-			dep->endpoint.maxpacket = 1024;
-			dep->endpoint.ops = &dwc3_gadget_ep_ops;
-			list_add_tail(&dep->endpoint.ep_list,
-					&dwc->gadget.ep_list);
-
-			ret = dwc3_alloc_trb_pool(dep);
-			if (ret) {
-				dev_err(dwc->dev, "%s: failed to allocate TRB pool\n", dep->name);
-				return ret;
-			}
-		}
-		INIT_LIST_HEAD(&dep->request_list);
-		INIT_LIST_HEAD(&dep->req_queued);
-	}
-
-	return 0;
-}
-
-static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
-{
-	struct dwc3_ep			*dep;
-	u8				epnum;
-
-	for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
-		dep = dwc->eps[epnum];
-		dwc3_free_trb_pool(dep);
-
-		if (epnum != 0 && epnum != 1)
-			list_del(&dep->endpoint.ep_list);
-
-		kfree(dep);
-	}
-}
-
-static void dwc3_gadget_release(struct device *dev)
-{
-	dev_dbg(dev, "%s\n", __func__);
-}
-
-/* -------------------------------------------------------------------------- */
-static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
-		const struct dwc3_event_depevt *event, int status)
-{
-	struct dwc3_request	*req;
-	struct dwc3_trb         trb;
-	unsigned int		count;
-	unsigned int		s_pkt = 0;
-
-	do {
-		req = next_request(&dep->req_queued);
-		if (!req)
-			break;
-
-		dwc3_trb_to_nat(req->trb, &trb);
-
-		if (trb.hwo && status != -ESHUTDOWN)
-			/*
-			 * We continue despite the error. There is not much we
-			 * can do. If we don't clean in up we loop for ever. If
-			 * we skip the TRB than it gets overwritten reused after
-			 * a while since we use them in a ring buffer. a BUG()
-			 * would help. Lets hope that if this occures, someone
-			 * fixes the root cause instead of looking away :)
-			 */
-			dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n",
-					dep->name, req->trb);
-		count = trb.length;
-
-		if (dep->direction) {
-			if (count) {
-				dev_err(dwc->dev, "incomplete IN transfer %s\n",
-						dep->name);
-				status = -ECONNRESET;
-			}
-		} else {
-			if (count && (event->status & DEPEVT_STATUS_SHORT))
-				s_pkt = 1;
-		}
-
-		/*
-		 * We assume here we will always receive the entire data block
-		 * which we should receive. Meaning, if we program RX to
-		 * receive 4K but we receive only 2K, we assume that's all we
-		 * should receive and we simply bounce the request back to the
-		 * gadget driver for further processing.
-		 */
-		req->request.actual += req->request.length - count;
-		dwc3_gadget_giveback(dep, req, status);
-		if (s_pkt)
-			break;
-		if ((event->status & DEPEVT_STATUS_LST) && trb.lst)
-			break;
-		if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc)
-			break;
-	} while (1);
-
-	if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc)
-		return 0;
-	return 1;
-}
-
-static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
-		struct dwc3_ep *dep, const struct dwc3_event_depevt *event,
-		int start_new)
-{
-	unsigned		status = 0;
-	int			clean_busy;
-
-	if (event->status & DEPEVT_STATUS_BUSERR)
-		status = -ECONNRESET;
-
-	clean_busy =  dwc3_cleanup_done_reqs(dwc, dep, event, status);
-	if (clean_busy) {
-		dep->flags &= ~DWC3_EP_BUSY;
-		dep->res_trans_idx = 0;
-	}
-}
-
-static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
-		struct dwc3_ep *dep, const struct dwc3_event_depevt *event)
-{
-	u32 uf;
-
-	if (list_empty(&dep->request_list)) {
-		dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",
-			dep->name);
-		return;
-	}
-
-	if (event->parameters) {
-		u32 mask;
-
-		mask = ~(dep->interval - 1);
-		uf = event->parameters & mask;
-		/* 4 micro frames in the future */
-		uf += dep->interval * 4;
-	} else {
-		uf = 0;
-	}
-
-	__dwc3_gadget_kick_transfer(dep, uf, 1);
-}
-
-static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep,
-		const struct dwc3_event_depevt *event)
-{
-	struct dwc3 *dwc = dep->dwc;
-	struct dwc3_event_depevt mod_ev = *event;
-
-	/*
-	 * We were asked to remove one requests. It is possible that this
-	 * request and a few other were started together and have the same
-	 * transfer index. Since we stopped the complete endpoint we don't
-	 * know how many requests were already completed (and not yet)
-	 * reported and how could be done (later). We purge them all until
-	 * the end of the list.
-	 */
-	mod_ev.status = DEPEVT_STATUS_LST;
-	dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN);
-	dep->flags &= ~DWC3_EP_BUSY;
-	/* pending requets are ignored and are queued on XferNotReady */
-}
-
-static void dwc3_ep_cmd_compl(struct dwc3_ep *dep,
-		const struct dwc3_event_depevt *event)
-{
-	u32 param = event->parameters;
-	u32 cmd_type = (param >> 8) & ((1 << 5) - 1);
-
-	switch (cmd_type) {
-	case DWC3_DEPCMD_ENDTRANSFER:
-		dwc3_process_ep_cmd_complete(dep, event);
-		break;
-	case DWC3_DEPCMD_STARTTRANSFER:
-		dep->res_trans_idx = param & 0x7f;
-		break;
-	default:
-		printk(KERN_ERR "%s() unknown /unexpected type: %d\n",
-				__func__, cmd_type);
-		break;
-	};
-}
-
-static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
-		const struct dwc3_event_depevt *event)
-{
-	struct dwc3_ep		*dep;
-	u8			epnum = event->endpoint_number;
-
-	dep = dwc->eps[epnum];
-
-	dev_vdbg(dwc->dev, "%s: %s\n", dep->name,
-			dwc3_ep_event_string(event->endpoint_event));
-
-	if (epnum == 0 || epnum == 1) {
-		dwc3_ep0_interrupt(dwc, event);
-		return;
-	}
-
-	switch (event->endpoint_event) {
-	case DWC3_DEPEVT_XFERCOMPLETE:
-		if (usb_endpoint_xfer_isoc(dep->desc)) {
-			dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n",
-					dep->name);
-			return;
-		}
-
-		dwc3_endpoint_transfer_complete(dwc, dep, event, 1);
-		break;
-	case DWC3_DEPEVT_XFERINPROGRESS:
-		if (!usb_endpoint_xfer_isoc(dep->desc)) {
-			dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",
-					dep->name);
-			return;
-		}
-
-		dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
-		break;
-	case DWC3_DEPEVT_XFERNOTREADY:
-		if (usb_endpoint_xfer_isoc(dep->desc)) {
-			dwc3_gadget_start_isoc(dwc, dep, event);
-		} else {
-			int ret;
-
-			dev_vdbg(dwc->dev, "%s: reason %s\n",
-					dep->name, event->status
-					? "Transfer Active"
-					: "Transfer Not Active");
-
-			ret = __dwc3_gadget_kick_transfer(dep, 0, 1);
-			if (!ret || ret == -EBUSY)
-				return;
-
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-		}
-
-		break;
-	case DWC3_DEPEVT_STREAMEVT:
-		if (!usb_endpoint_xfer_bulk(dep->desc)) {
-			dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
-					dep->name);
-			return;
-		}
-
-		switch (event->status) {
-		case DEPEVT_STREAMEVT_FOUND:
-			dev_vdbg(dwc->dev, "Stream %d found and started\n",
-					event->parameters);
-
-			break;
-		case DEPEVT_STREAMEVT_NOTFOUND:
-			/* FALLTHROUGH */
-		default:
-			dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
-		}
-		break;
-	case DWC3_DEPEVT_RXTXFIFOEVT:
-		dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
-		break;
-	case DWC3_DEPEVT_EPCMDCMPLT:
-		dwc3_ep_cmd_compl(dep, event);
-		break;
-	}
-}
-
-static void dwc3_disconnect_gadget(struct dwc3 *dwc)
-{
-	if (dwc->gadget_driver && dwc->gadget_driver->disconnect) {
-		spin_unlock(&dwc->lock);
-		dwc->gadget_driver->disconnect(&dwc->gadget);
-		spin_lock(&dwc->lock);
-	}
-}
-
-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
-{
-	struct dwc3_ep *dep;
-	struct dwc3_gadget_ep_cmd_params params;
-	u32 cmd;
-	int ret;
-
-	dep = dwc->eps[epnum];
-
-	WARN_ON(!dep->res_trans_idx);
-	if (dep->res_trans_idx) {
-		cmd = DWC3_DEPCMD_ENDTRANSFER;
-		cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC;
-		cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx);
-		memset(&params, 0, sizeof(params));
-		ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
-		WARN_ON_ONCE(ret);
-		dep->res_trans_idx = 0;
-	}
-}
-
-static void dwc3_stop_active_transfers(struct dwc3 *dwc)
-{
-	u32 epnum;
-
-	for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
-		struct dwc3_ep *dep;
-
-		dep = dwc->eps[epnum];
-		if (!(dep->flags & DWC3_EP_ENABLED))
-			continue;
-
-		dwc3_remove_requests(dwc, dep);
-	}
-}
-
-static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
-{
-	u32 epnum;
-
-	for (epnum = 1; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
-		struct dwc3_ep *dep;
-		struct dwc3_gadget_ep_cmd_params params;
-		int ret;
-
-		dep = dwc->eps[epnum];
-
-		if (!(dep->flags & DWC3_EP_STALL))
-			continue;
-
-		dep->flags &= ~DWC3_EP_STALL;
-
-		memset(&params, 0, sizeof(params));
-		ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
-				DWC3_DEPCMD_CLEARSTALL, &params);
-		WARN_ON_ONCE(ret);
-	}
-}
-
-static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
-{
-	dev_vdbg(dwc->dev, "%s\n", __func__);
-#if 0
-	XXX
-	U1/U2 is powersave optimization. Skip it for now. Anyway we need to
-	enable it before we can disable it.
-
-	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-	reg &= ~DWC3_DCTL_INITU1ENA;
-	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-	reg &= ~DWC3_DCTL_INITU2ENA;
-	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-#endif
-
-	dwc3_stop_active_transfers(dwc);
-	dwc3_disconnect_gadget(dwc);
-	dwc->start_config_issued = false;
-
-	dwc->gadget.speed = USB_SPEED_UNKNOWN;
-}
-
-static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on)
-{
-	u32			reg;
-
-	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-
-	if (on)
-		reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
-	else
-		reg |= DWC3_GUSB3PIPECTL_SUSPHY;
-
-	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-}
-
-static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on)
-{
-	u32			reg;
-
-	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-
-	if (on)
-		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
-	else
-		reg |= DWC3_GUSB2PHYCFG_SUSPHY;
-
-	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-}
-
-static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
-{
-	u32			reg;
-
-	dev_vdbg(dwc->dev, "%s\n", __func__);
-
-	/* Enable PHYs */
-	dwc3_gadget_usb2_phy_power(dwc, true);
-	dwc3_gadget_usb3_phy_power(dwc, true);
-
-	if (dwc->gadget.speed != USB_SPEED_UNKNOWN)
-		dwc3_disconnect_gadget(dwc);
-
-	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-	reg &= ~DWC3_DCTL_TSTCTRL_MASK;
-	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-	dwc3_stop_active_transfers(dwc);
-	dwc3_clear_stall_all_ep(dwc);
-	dwc->start_config_issued = false;
-
-	/* Reset device address to zero */
-	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
-	reg &= ~(DWC3_DCFG_DEVADDR_MASK);
-	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-}
-
-static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed)
-{
-	u32 reg;
-	u32 usb30_clock = DWC3_GCTL_CLK_BUS;
-
-	/*
-	 * We change the clock only at SS but I dunno why I would want to do
-	 * this. Maybe it becomes part of the power saving plan.
-	 */
-
-	if (speed != DWC3_DSTS_SUPERSPEED)
-		return;
-
-	/*
-	 * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed
-	 * each time on Connect Done.
-	 */
-	if (!usb30_clock)
-		return;
-
-	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-	reg |= DWC3_GCTL_RAMCLKSEL(usb30_clock);
-	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-}
-
-static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed)
-{
-	switch (speed) {
-	case USB_SPEED_SUPER:
-		dwc3_gadget_usb2_phy_power(dwc, false);
-		break;
-	case USB_SPEED_HIGH:
-	case USB_SPEED_FULL:
-	case USB_SPEED_LOW:
-		dwc3_gadget_usb3_phy_power(dwc, false);
-		break;
-	}
-}
-
-static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
-{
-	struct dwc3_gadget_ep_cmd_params params;
-	struct dwc3_ep		*dep;
-	int			ret;
-	u32			reg;
-	u8			speed;
-
-	dev_vdbg(dwc->dev, "%s\n", __func__);
-
-	memset(&params, 0x00, sizeof(params));
-
-	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-	speed = reg & DWC3_DSTS_CONNECTSPD;
-	dwc->speed = speed;
-
-	dwc3_update_ram_clk_sel(dwc, speed);
-
-	switch (speed) {
-	case DWC3_DCFG_SUPERSPEED:
-		dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
-		dwc->gadget.ep0->maxpacket = 512;
-		dwc->gadget.speed = USB_SPEED_SUPER;
-		break;
-	case DWC3_DCFG_HIGHSPEED:
-		dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
-		dwc->gadget.ep0->maxpacket = 64;
-		dwc->gadget.speed = USB_SPEED_HIGH;
-		break;
-	case DWC3_DCFG_FULLSPEED2:
-	case DWC3_DCFG_FULLSPEED1:
-		dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
-		dwc->gadget.ep0->maxpacket = 64;
-		dwc->gadget.speed = USB_SPEED_FULL;
-		break;
-	case DWC3_DCFG_LOWSPEED:
-		dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8);
-		dwc->gadget.ep0->maxpacket = 8;
-		dwc->gadget.speed = USB_SPEED_LOW;
-		break;
-	}
-
-	/* Disable unneded PHY */
-	dwc3_gadget_disable_phy(dwc, dwc->gadget.speed);
-
-	dep = dwc->eps[0];
-	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
-		return;
-	}
-
-	dep = dwc->eps[1];
-	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
-		return;
-	}
-
-	/*
-	 * Configure PHY via GUSB3PIPECTLn if required.
-	 *
-	 * Update GTXFIFOSIZn
-	 *
-	 * In both cases reset values should be sufficient.
-	 */
-}
-
-static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
-{
-	dev_vdbg(dwc->dev, "%s\n", __func__);
-
-	/*
-	 * TODO take core out of low power mode when that's
-	 * implemented.
-	 */
-
-	dwc->gadget_driver->resume(&dwc->gadget);
-}
-
-static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
-		unsigned int evtinfo)
-{
-	/*  The fith bit says SuperSpeed yes or no. */
-	dwc->link_state = evtinfo & DWC3_LINK_STATE_MASK;
-
-	dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state);
-}
-
-static void dwc3_gadget_interrupt(struct dwc3 *dwc,
-		const struct dwc3_event_devt *event)
-{
-	switch (event->type) {
-	case DWC3_DEVICE_EVENT_DISCONNECT:
-		dwc3_gadget_disconnect_interrupt(dwc);
-		break;
-	case DWC3_DEVICE_EVENT_RESET:
-		dwc3_gadget_reset_interrupt(dwc);
-		break;
-	case DWC3_DEVICE_EVENT_CONNECT_DONE:
-		dwc3_gadget_conndone_interrupt(dwc);
-		break;
-	case DWC3_DEVICE_EVENT_WAKEUP:
-		dwc3_gadget_wakeup_interrupt(dwc);
-		break;
-	case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
-		dwc3_gadget_linksts_change_interrupt(dwc, event->event_info);
-		break;
-	case DWC3_DEVICE_EVENT_EOPF:
-		dev_vdbg(dwc->dev, "End of Periodic Frame\n");
-		break;
-	case DWC3_DEVICE_EVENT_SOF:
-		dev_vdbg(dwc->dev, "Start of Periodic Frame\n");
-		break;
-	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
-		dev_vdbg(dwc->dev, "Erratic Error\n");
-		break;
-	case DWC3_DEVICE_EVENT_CMD_CMPL:
-		dev_vdbg(dwc->dev, "Command Complete\n");
-		break;
-	case DWC3_DEVICE_EVENT_OVERFLOW:
-		dev_vdbg(dwc->dev, "Overflow\n");
-		break;
-	default:
-		dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type);
-	}
-}
-
-static void dwc3_process_event_entry(struct dwc3 *dwc,
-		const union dwc3_event *event)
-{
-	/* Endpoint IRQ, handle it and return early */
-	if (event->type.is_devspec == 0) {
-		/* depevt */
-		return dwc3_endpoint_interrupt(dwc, &event->depevt);
-	}
-
-	switch (event->type.type) {
-	case DWC3_EVENT_TYPE_DEV:
-		dwc3_gadget_interrupt(dwc, &event->devt);
-		break;
-	/* REVISIT what to do with Carkit and I2C events ? */
-	default:
-		dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw);
-	}
-}
-
-static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
-{
-	struct dwc3_event_buffer *evt;
-	int left;
-	u32 count;
-
-	count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
-	count &= DWC3_GEVNTCOUNT_MASK;
-	if (!count)
-		return IRQ_NONE;
-
-	evt = dwc->ev_buffs[buf];
-	left = count;
-
-	while (left > 0) {
-		union dwc3_event event;
-
-		memcpy(&event.raw, (evt->buf + evt->lpos), sizeof(event.raw));
-		dwc3_process_event_entry(dwc, &event);
-		/*
-		 * XXX we wrap around correctly to the next entry as almost all
-		 * entries are 4 bytes in size. There is one entry which has 12
-		 * bytes which is a regular entry followed by 8 bytes data. ATM
-		 * I don't know how things are organized if were get next to the
-		 * a boundary so I worry about that once we try to handle that.
-		 */
-		evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;
-		left -= 4;
-
-		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);
-	}
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
-{
-	struct dwc3			*dwc = _dwc;
-	int				i;
-	irqreturn_t			ret = IRQ_NONE;
-
-	spin_lock(&dwc->lock);
-
-	for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
-		irqreturn_t status;
-
-		status = dwc3_process_event_buf(dwc, i);
-		if (status == IRQ_HANDLED)
-			ret = status;
-	}
-
-	spin_unlock(&dwc->lock);
-
-	return ret;
-}
-
-/**
- * dwc3_gadget_init - Initializes gadget related registers
- * @dwc: Pointer to out controller context structure
- *
- * Returns 0 on success otherwise negative errno.
- */
-int __devinit dwc3_gadget_init(struct dwc3 *dwc)
-{
-	u32					reg;
-	int					ret;
-	int					irq;
-
-	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
-			&dwc->ctrl_req_addr, GFP_KERNEL);
-	if (!dwc->ctrl_req) {
-		dev_err(dwc->dev, "failed to allocate ctrl request\n");
-		ret = -ENOMEM;
-		goto err0;
-	}
-
-	dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
-			&dwc->ep0_trb_addr, GFP_KERNEL);
-	if (!dwc->ep0_trb) {
-		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
-		ret = -ENOMEM;
-		goto err1;
-	}
-
-	dwc->setup_buf = dma_alloc_coherent(dwc->dev,
-			sizeof(*dwc->setup_buf) * 2,
-			&dwc->setup_buf_addr, GFP_KERNEL);
-	if (!dwc->setup_buf) {
-		dev_err(dwc->dev, "failed to allocate setup buffer\n");
-		ret = -ENOMEM;
-		goto err2;
-	}
-
-	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
-			512, &dwc->ep0_bounce_addr, GFP_KERNEL);
-	if (!dwc->ep0_bounce) {
-		dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
-		ret = -ENOMEM;
-		goto err3;
-	}
-
-	dev_set_name(&dwc->gadget.dev, "gadget");
-
-	dwc->gadget.ops			= &dwc3_gadget_ops;
-	dwc->gadget.is_dualspeed	= true;
-	dwc->gadget.speed		= USB_SPEED_UNKNOWN;
-	dwc->gadget.dev.parent		= dwc->dev;
-
-	dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask);
-
-	dwc->gadget.dev.dma_parms	= dwc->dev->dma_parms;
-	dwc->gadget.dev.dma_mask	= dwc->dev->dma_mask;
-	dwc->gadget.dev.release		= dwc3_gadget_release;
-	dwc->gadget.name		= "dwc3-gadget";
-
-	/*
-	 * REVISIT: Here we should clear all pending IRQs to be
-	 * sure we're starting from a well known location.
-	 */
-
-	ret = dwc3_gadget_init_endpoints(dwc);
-	if (ret)
-		goto err4;
-
-	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-
-	ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED,
-			"dwc3", dwc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
-				irq, ret);
-		goto err5;
-	}
-
-	/* Enable all but Start and End of Frame IRQs */
-	reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN |
-			DWC3_DEVTEN_EVNTOVERFLOWEN |
-			DWC3_DEVTEN_CMDCMPLTEN |
-			DWC3_DEVTEN_ERRTICERREN |
-			DWC3_DEVTEN_WKUPEVTEN |
-			DWC3_DEVTEN_ULSTCNGEN |
-			DWC3_DEVTEN_CONNECTDONEEN |
-			DWC3_DEVTEN_USBRSTEN |
-			DWC3_DEVTEN_DISCONNEVTEN);
-	dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
-
-	ret = device_register(&dwc->gadget.dev);
-	if (ret) {
-		dev_err(dwc->dev, "failed to register gadget device\n");
-		put_device(&dwc->gadget.dev);
-		goto err6;
-	}
-
-	ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
-	if (ret) {
-		dev_err(dwc->dev, "failed to register udc\n");
-		goto err7;
-	}
-
-	return 0;
-
-err7:
-	device_unregister(&dwc->gadget.dev);
-
-err6:
-	dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
-	free_irq(irq, dwc);
-
-err5:
-	dwc3_gadget_free_endpoints(dwc);
-
-err4:
-	dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
-			dwc->ep0_bounce_addr);
-
-err3:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
-			dwc->setup_buf, dwc->setup_buf_addr);
-
-err2:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
-			dwc->ep0_trb, dwc->ep0_trb_addr);
-
-err1:
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
-			dwc->ctrl_req, dwc->ctrl_req_addr);
-
-err0:
-	return ret;
-}
-
-void dwc3_gadget_exit(struct dwc3 *dwc)
-{
-	int			irq;
-	int			i;
-
-	usb_del_gadget_udc(&dwc->gadget);
-	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-
-	dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
-	free_irq(irq, dwc);
-
-	for (i = 0; i < ARRAY_SIZE(dwc->eps); i++)
-		__dwc3_gadget_ep_disable(dwc->eps[i]);
-
-	dwc3_gadget_free_endpoints(dwc);
-
-	dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
-			dwc->ep0_bounce_addr);
-
-	dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
-			dwc->setup_buf, dwc->setup_buf_addr);
-
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
-			dwc->ep0_trb, dwc->ep0_trb_addr);
-
-	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
-			dwc->ctrl_req, dwc->ctrl_req_addr);
-
-	device_unregister(&dwc->gadget.dev);
-}
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
deleted file mode 100644
index 71145a4..0000000
--- a/drivers/usb/dwc3/gadget.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * gadget.h - DesignWare USB3 DRD Gadget Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DRIVERS_USB_DWC3_GADGET_H
-#define __DRIVERS_USB_DWC3_GADGET_H
-
-#include <linux/list.h>
-#include <linux/usb/gadget.h>
-#include "io.h"
-
-struct dwc3;
-#define to_dwc3_ep(ep)		(container_of(ep, struct dwc3_ep, endpoint))
-#define gadget_to_dwc(g)	(container_of(g, struct dwc3, gadget))
-
-/* DEPCFG parameter 1 */
-#define DWC3_DEPCFG_INT_NUM(n)		((n) << 0)
-#define DWC3_DEPCFG_XFER_COMPLETE_EN	(1 << 8)
-#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN	(1 << 9)
-#define DWC3_DEPCFG_XFER_NOT_READY_EN	(1 << 10)
-#define DWC3_DEPCFG_FIFO_ERROR_EN	(1 << 11)
-#define DWC3_DEPCFG_STREAM_EVENT_EN	(1 << 13)
-#define DWC3_DEPCFG_BINTERVAL_M1(n)	((n) << 16)
-#define DWC3_DEPCFG_STREAM_CAPABLE	(1 << 24)
-#define DWC3_DEPCFG_EP_NUMBER(n)	((n) << 25)
-#define DWC3_DEPCFG_BULK_BASED		(1 << 30)
-#define DWC3_DEPCFG_FIFO_BASED		(1 << 31)
-
-/* DEPCFG parameter 0 */
-#define DWC3_DEPCFG_EP_TYPE(n)		((n) << 1)
-#define DWC3_DEPCFG_MAX_PACKET_SIZE(n)	((n) << 3)
-#define DWC3_DEPCFG_FIFO_NUMBER(n)	((n) << 17)
-#define DWC3_DEPCFG_BURST_SIZE(n)	((n) << 22)
-#define DWC3_DEPCFG_DATA_SEQ_NUM(n)	((n) << 26)
-#define DWC3_DEPCFG_IGN_SEQ_NUM		(1 << 31)
-
-/* DEPXFERCFG parameter 0 */
-#define DWC3_DEPXFERCFG_NUM_XFER_RES(n)	((n) & 0xffff)
-
-struct dwc3_gadget_ep_cmd_params {
-	u32	param2;
-	u32	param1;
-	u32	param0;
-};
-
-/* -------------------------------------------------------------------------- */
-
-struct dwc3_request {
-	struct usb_request	request;
-	struct list_head	list;
-	struct dwc3_ep		*dep;
-
-	u8			epnum;
-	struct dwc3_trb_hw	*trb;
-	dma_addr_t		trb_dma;
-
-	unsigned		direction:1;
-	unsigned		mapped:1;
-	unsigned		queued:1;
-};
-#define to_dwc3_request(r)	(container_of(r, struct dwc3_request, request))
-
-static inline struct dwc3_request *next_request(struct list_head *list)
-{
-	if (list_empty(list))
-		return NULL;
-
-	return list_first_entry(list, struct dwc3_request, list);
-}
-
-static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
-{
-	struct dwc3_ep		*dep = req->dep;
-
-	req->queued = true;
-	list_move_tail(&req->list, &dep->req_queued);
-}
-
-#if defined(CONFIG_USB_GADGET_DWC3) || defined(CONFIG_USB_GADGET_DWC3_MODULE)
-int dwc3_gadget_init(struct dwc3 *dwc);
-void dwc3_gadget_exit(struct dwc3 *dwc);
-#else
-static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; }
-static inline void dwc3_gadget_exit(struct dwc3 *dwc) { }
-static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
-		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
-{
-	return 0;
-}
-#endif
-
-void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
-		int status);
-
-void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event);
-void dwc3_ep0_out_start(struct dwc3 *dwc);
-int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
-		gfp_t gfp_flags);
-int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
-int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
-		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
-void dwc3_map_buffer_to_dma(struct dwc3_request *req);
-void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);
-
-/**
- * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
- * @dwc: DesignWare USB3 Pointer
- * @number: DWC endpoint number
- *
- * Caller should take care of locking
- */
-static inline u32 dwc3_gadget_ep_get_transfer_index(struct dwc3 *dwc, u8 number)
-{
-	u32			res_id;
-
-	res_id = dwc3_readl(dwc->regs, DWC3_DEPCMD(number));
-
-	return DWC3_DEPCMD_GET_RSC_IDX(res_id);
-}
-
-/**
- * dwc3_gadget_event_string - returns event name
- * @event: the event code
- */
-static inline const char *dwc3_gadget_event_string(u8 event)
-{
-	switch (event) {
-	case DWC3_DEVICE_EVENT_DISCONNECT:
-		return "Disconnect";
-	case DWC3_DEVICE_EVENT_RESET:
-		return "Reset";
-	case DWC3_DEVICE_EVENT_CONNECT_DONE:
-		return "Connection Done";
-	case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
-		return "Link Status Change";
-	case DWC3_DEVICE_EVENT_WAKEUP:
-		return "WakeUp";
-	case DWC3_DEVICE_EVENT_EOPF:
-		return "End-Of-Frame";
-	case DWC3_DEVICE_EVENT_SOF:
-		return "Start-Of-Frame";
-	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
-		return "Erratic Error";
-	case DWC3_DEVICE_EVENT_CMD_CMPL:
-		return "Command Complete";
-	case DWC3_DEVICE_EVENT_OVERFLOW:
-		return "Overflow";
-	}
-
-	return "UNKNOWN";
-}
-
-/**
- * dwc3_ep_event_string - returns event name
- * @event: then event code
- */
-static inline const char *dwc3_ep_event_string(u8 event)
-{
-	switch (event) {
-	case DWC3_DEPEVT_XFERCOMPLETE:
-		return "Transfer Complete";
-	case DWC3_DEPEVT_XFERINPROGRESS:
-		return "Transfer In-Progress";
-	case DWC3_DEPEVT_XFERNOTREADY:
-		return "Transfer Not Ready";
-	case DWC3_DEPEVT_RXTXFIFOEVT:
-		return "FIFO";
-	case DWC3_DEPEVT_STREAMEVT:
-		return "Stream";
-	case DWC3_DEPEVT_EPCMDCMPLT:
-		return "Endpoint Command Complete";
-	}
-
-	return "UNKNOWN";
-}
-
-#endif /* __DRIVERS_USB_DWC3_GADGET_H */
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
deleted file mode 100644
index bc957db..0000000
--- a/drivers/usb/dwc3/io.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * io.h - DesignWare USB3 DRD IO Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DRIVERS_USB_DWC3_IO_H
-#define __DRIVERS_USB_DWC3_IO_H
-
-#include <asm/io.h>
-
-static inline u32 dwc3_readl(void __iomem *base, u32 offset)
-{
-	return readl(base + offset);
-}
-
-static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
-{
-	writel(value, base + offset);
-}
-
-#endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 092e115..97e7aa4 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -386,18 +386,6 @@
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config USB_GADGET_DWC3
-	tristate "DesignWare USB3.0 (DRD) Controller"
-	depends on USB_DWC3
-	select USB_GADGET_DUALSPEED
-	select USB_GADGET_SUPERSPEED
-	help
-	  DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller
-	  which can be configured for peripheral-only, host-only, hub-only
-	  and Dual-Role operation. This Controller was first integrated into
-	  the OMAP5 series of processors. More information about the OMAP5
-	  version of this controller, refer to http://www.ti.com/omap5.
-
 #
 # Controllers available in both integrated and discrete versions
 #
@@ -685,12 +673,6 @@
 	bool
 	depends on USB_GADGET
 
-# Selected by UDC drivers that support super-speed opperation
-config USB_GADGET_SUPERSPEED
-	bool
-	depends on USB_GADGET
-	depends on USB_GADGET_DUALSPEED
-
 #
 # USB Gadget Drivers
 #
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 655a7ee..141f649 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -3,7 +3,6 @@
 #
 ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
 
-obj-$(CONFIG_USB_GADGET)	+= udc-core.o
 obj-$(CONFIG_USB_DUMMY_HCD)	+= dummy_hcd.o
 obj-$(CONFIG_USB_NET2280)	+= net2280.o
 obj-$(CONFIG_USB_AMD5536UDC)	+= amd5536udc.o
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index 70f2b37..95e8138 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -1438,15 +1438,10 @@
 	return 0;
 }
 
-static int amd5536_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int amd5536_stop(struct usb_gadget_driver *driver);
 /* gadget operations */
 static const struct usb_gadget_ops udc_ops = {
 	.wakeup		= udc_wakeup,
 	.get_frame	= udc_get_frame,
-	.start		= amd5536_start,
-	.stop		= amd5536_stop,
 };
 
 /* Setups endpoint parameters, adds endpoints to linked list */
@@ -1960,7 +1955,7 @@
 }
 
 /* Called by gadget driver to register itself */
-static int amd5536_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct udc		*dev = udc;
@@ -2007,6 +2002,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /* shutdown requests and disconnect from gadget */
 static void
@@ -2031,7 +2027,7 @@
 }
 
 /* Called by gadget driver to unregister itself */
-static int amd5536_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct udc	*dev = udc;
 	unsigned long	flags;
@@ -2061,6 +2057,8 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 
 /* Clear pending NAK bits */
 static void udc_process_cnak_queue(struct udc *dev)
@@ -3136,7 +3134,6 @@
 
 	dev = pci_get_drvdata(pdev);
 
-	usb_del_gadget_udc(&udc->gadget);
 	/* gadget driver must not be registered */
 	BUG_ON(dev->driver != NULL);
 
@@ -3385,13 +3382,8 @@
 		"driver version: %s(for Geode5536 B1)\n", tmp);
 	udc = dev;
 
-	retval = usb_add_gadget_udc(&udc->pdev->dev, &dev->gadget);
-	if (retval)
-		goto finished;
-
 	retval = device_register(&dev->gadget.dev);
 	if (retval) {
-		usb_del_gadget_udc(&dev->gadget);
 		put_device(&dev->gadget.dev);
 		goto finished;
 	}
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 98cbc06..f4690ff 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -985,18 +985,12 @@
 	return 0;
 }
 
-static int at91_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int at91_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops at91_udc_ops = {
 	.get_frame		= at91_get_frame,
 	.wakeup			= at91_wakeup,
 	.set_selfpowered	= at91_set_selfpowered,
 	.vbus_session		= at91_vbus_session,
 	.pullup			= at91_pullup,
-	.start			= at91_start,
-	.stop			= at91_stop,
 
 	/*
 	 * VBUS-powered devices may also also want to support bigger
@@ -1634,7 +1628,7 @@
 		schedule_work(&udc->vbus_timer_work);
 }
 
-static int at91_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct at91_udc	*udc = &controller;
@@ -1678,8 +1672,9 @@
 	DBG("bound to %s\n", driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int at91_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
 	struct at91_udc *udc = &controller;
 	unsigned long	flags;
@@ -1701,6 +1696,7 @@
 	DBG("unbound from %s\n", driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------*/
 
@@ -1858,18 +1854,13 @@
 		DBG("no VBUS detection, assuming always-on\n");
 		udc->vbus = 1;
 	}
-	retval = usb_add_gadget_udc(dev, &udc->gadget);
-	if (retval)
-		goto fail4;
 	dev_set_drvdata(dev, udc);
 	device_init_wakeup(dev, 1);
 	create_debug_file(udc);
 
 	INFO("%s version %s\n", driver_name, DRIVER_VERSION);
 	return 0;
-fail4:
-	if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled)
-		free_irq(udc->board.vbus_pin, udc);
+
 fail3:
 	if (udc->board.vbus_pin > 0)
 		gpio_free(udc->board.vbus_pin);
@@ -1896,7 +1887,6 @@
 
 	DBG("remove\n");
 
-	usb_del_gadget_udc(&udc->gadget);
 	if (udc->driver)
 		return -EBUSY;
 
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index e6b970a..db1a659 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1007,16 +1007,10 @@
 	return 0;
 }
 
-static int atmel_usba_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int atmel_usba_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops usba_udc_ops = {
 	.get_frame		= usba_udc_get_frame,
 	.wakeup			= usba_udc_wakeup,
 	.set_selfpowered	= usba_udc_set_selfpowered,
-	.start			= atmel_usba_start,
-	.stop			= atmel_usba_stop,
 };
 
 static struct usb_endpoint_descriptor usba_ep0_desc = {
@@ -1795,7 +1789,7 @@
 	return IRQ_HANDLED;
 }
 
-static int atmel_usba_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct usba_udc *udc = &the_udc;
@@ -1848,8 +1842,9 @@
 	udc->gadget.dev.driver = NULL;
 	return ret;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int atmel_usba_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct usba_udc *udc = &the_udc;
 	unsigned long flags;
@@ -1885,6 +1880,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static int __init usba_udc_probe(struct platform_device *pdev)
 {
@@ -2025,24 +2021,12 @@
 		}
 	}
 
-	ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
-	if (ret)
-		goto err_add_udc;
-
 	usba_init_debugfs(udc);
 	for (i = 1; i < pdata->num_ep; i++)
 		usba_ep_init_debugfs(udc, &usba_ep[i]);
 
 	return 0;
 
-err_add_udc:
-	if (gpio_is_valid(pdata->vbus_pin)) {
-		free_irq(gpio_to_irq(udc->vbus_pin), udc);
-		gpio_free(udc->vbus_pin);
-	}
-
-	device_unregister(&udc->gadget.dev);
-
 err_device_add:
 	free_irq(irq, udc);
 err_request_irq:
@@ -2069,8 +2053,6 @@
 
 	udc = platform_get_drvdata(pdev);
 
-	usb_del_gadget_udc(&udc->gadget);
-
 	for (i = 1; i < pdata->num_ep; i++)
 		usba_ep_cleanup_debugfs(&usba_ep[i]);
 	usba_cleanup_debugfs(udc);
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index 9d89ae47..93b999e 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -165,7 +165,6 @@
 	.name		= "g_audio",
 	.dev		= &device_desc,
 	.strings	= audio_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(audio_unbind),
 };
 
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index b1c1afb..2720ab0 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -244,7 +244,6 @@
 	.name		= "g_cdc",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(cdc_unbind),
 };
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 406b238..35327cc 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2182,7 +2182,7 @@
 		int type, num, dir, err = -EINVAL;
 		struct usb_ctrlrequest req;
 
-		if (mEp->ep.desc == NULL)
+		if (mEp->desc == NULL)
 			continue;   /* not configured */
 
 		if (hw_test_and_clear_complete(i)) {
@@ -2381,7 +2381,7 @@
 
 	/* only internal SW should enable ctrl endpts */
 
-	mEp->ep.desc = desc;
+	mEp->desc = desc;
 
 	if (!list_empty(&mEp->qh.queue))
 		warn("enabling a non-empty endpoint!");
@@ -2436,7 +2436,7 @@
 
 	if (ep == NULL)
 		return -EINVAL;
-	else if (mEp->ep.desc == NULL)
+	else if (mEp->desc == NULL)
 		return -EBUSY;
 
 	spin_lock_irqsave(mEp->lock, flags);
@@ -2455,7 +2455,7 @@
 
 	} while (mEp->dir != direction);
 
-	mEp->ep.desc = NULL;
+	mEp->desc = NULL;
 
 	spin_unlock_irqrestore(mEp->lock, flags);
 	return retval;
@@ -2543,7 +2543,7 @@
 
 	trace("%p, %p, %X", ep, req, gfp_flags);
 
-	if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
+	if (ep == NULL || req == NULL || mEp->desc == NULL)
 		return -EINVAL;
 
 	spin_lock_irqsave(mEp->lock, flags);
@@ -2616,7 +2616,7 @@
 	trace("%p, %p", ep, req);
 
 	if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
-		mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
+		mEp->desc == NULL || list_empty(&mReq->queue) ||
 		list_empty(&mEp->qh.queue))
 		return -EINVAL;
 
@@ -2662,7 +2662,7 @@
 
 	trace("%p, %i", ep, value);
 
-	if (ep == NULL || mEp->ep.desc == NULL)
+	if (ep == NULL || mEp->desc == NULL)
 		return -EINVAL;
 
 	spin_lock_irqsave(mEp->lock, flags);
@@ -2705,7 +2705,7 @@
 
 	trace("%p", ep);
 
-	if (ep == NULL || mEp->ep.desc == NULL)
+	if (ep == NULL || mEp->desc == NULL)
 		return -EINVAL;
 
 	spin_lock_irqsave(mEp->lock, flags);
@@ -2828,9 +2828,7 @@
 	return 0;
 }
 
-static int ci13xxx_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int ci13xxx_stop(struct usb_gadget_driver *driver);
+
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
@@ -2841,19 +2839,17 @@
 	.wakeup		= ci13xxx_wakeup,
 	.vbus_draw	= ci13xxx_vbus_draw,
 	.pullup		= ci13xxx_pullup,
-	.start		= ci13xxx_start,
-	.stop		= ci13xxx_stop,
 };
 
 /**
- * ci13xxx_start: register a gadget driver
+ * usb_gadget_probe_driver: register a gadget driver
  * @driver: the driver being registered
  * @bind: the driver's bind callback
  *
- * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
+ * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
  * Interrupts are enabled here.
  */
-static int ci13xxx_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct ci13xxx *udc = _udc;
@@ -2935,12 +2931,10 @@
 	if (retval)
 		goto done;
 	spin_unlock_irqrestore(udc->lock, flags);
-	udc->ep0out.ep.desc = &ctrl_endpt_out_desc;
-	retval = usb_ep_enable(&udc->ep0out.ep);
+	retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
 	if (retval)
 		return retval;
-	udc->ep0in.ep.desc = &ctrl_endpt_in_desc;
-	retval = usb_ep_enable(&udc->ep0in.ep);
+	retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
 	if (retval)
 		return retval;
 	spin_lock_irqsave(udc->lock, flags);
@@ -2985,13 +2979,14 @@
 		pm_runtime_put_sync(&udc->gadget.dev);
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /**
- * ci13xxx_stop: unregister a gadget driver
+ * usb_gadget_unregister_driver: unregister a gadget driver
  *
  * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
  */
-static int ci13xxx_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct ci13xxx *udc = _udc;
 	unsigned long i, flags;
@@ -3050,6 +3045,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /******************************************************************************
  * BUS block
@@ -3224,23 +3220,12 @@
 		if (retval)
 			goto remove_dbg;
 	}
-
-	retval = usb_add_gadget_udc(dev, &udc->gadget);
-	if (retval)
-		goto remove_trans;
-
 	pm_runtime_no_callbacks(&udc->gadget.dev);
 	pm_runtime_enable(&udc->gadget.dev);
 
 	_udc = udc;
 	return retval;
 
-remove_trans:
-	if (udc->transceiver) {
-		otg_set_peripheral(udc->transceiver, &udc->gadget);
-		otg_put_transceiver(udc->transceiver);
-	}
-
 	err("error = %i", retval);
 remove_dbg:
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
@@ -3270,7 +3255,6 @@
 		err("EINVAL");
 		return;
 	}
-	usb_del_gadget_udc(&udc->gadget);
 
 	if (udc->transceiver) {
 		otg_set_peripheral(udc->transceiver, &udc->gadget);
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 54b8790..fce611a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -97,6 +97,7 @@
 /* Extension of usb_ep */
 struct ci13xxx_ep {
 	struct usb_ep                          ep;
+	const struct usb_endpoint_descriptor  *desc;
 	u8                                     dir;
 	u8                                     num;
 	u8                                     type;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index daa796e..4c33695 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -27,7 +27,7 @@
 #include <linux/utsname.h>
 
 #include <linux/usb/composite.h>
-#include <asm/unaligned.h>
+
 
 /*
  * The code in this file is utility code, used to build a gadget driver
@@ -74,130 +74,6 @@
 static char composite_manufacturer[50];
 
 /*-------------------------------------------------------------------------*/
-/**
- * next_ep_desc() - advance to the next EP descriptor
- * @t: currect pointer within descriptor array
- *
- * Return: next EP descriptor or NULL
- *
- * Iterate over @t until either EP descriptor found or
- * NULL (that indicates end of list) encountered
- */
-static struct usb_descriptor_header**
-next_ep_desc(struct usb_descriptor_header **t)
-{
-	for (; *t; t++) {
-		if ((*t)->bDescriptorType == USB_DT_ENDPOINT)
-			return t;
-	}
-	return NULL;
-}
-
-/*
- * for_each_ep_desc()- iterate over endpoint descriptors in the
- *		descriptors list
- * @start:	pointer within descriptor array.
- * @ep_desc:	endpoint descriptor to use as the loop cursor
- */
-#define for_each_ep_desc(start, ep_desc) \
-	for (ep_desc = next_ep_desc(start); \
-	      ep_desc; ep_desc = next_ep_desc(ep_desc+1))
-
-/**
- * config_ep_by_speed() - configures the given endpoint
- * according to gadget speed.
- * @g: pointer to the gadget
- * @f: usb function
- * @_ep: the endpoint to configure
- *
- * Return: error code, 0 on success
- *
- * This function chooses the right descriptors for a given
- * endpoint according to gadget speed and saves it in the
- * endpoint desc field. If the endpoint already has a descriptor
- * assigned to it - overwrites it with currently corresponding
- * descriptor. The endpoint maxpacket field is updated according
- * to the chosen descriptor.
- * Note: the supplied function should hold all the descriptors
- * for supported speeds
- */
-int config_ep_by_speed(struct usb_gadget *g,
-			struct usb_function *f,
-			struct usb_ep *_ep)
-{
-	struct usb_endpoint_descriptor *chosen_desc = NULL;
-	struct usb_descriptor_header **speed_desc = NULL;
-
-	struct usb_ss_ep_comp_descriptor *comp_desc = NULL;
-	int want_comp_desc = 0;
-
-	struct usb_descriptor_header **d_spd; /* cursor for speed desc */
-
-	if (!g || !f || !_ep)
-		return -EIO;
-
-	/* select desired speed */
-	switch (g->speed) {
-	case USB_SPEED_SUPER:
-		if (gadget_is_superspeed(g)) {
-			speed_desc = f->ss_descriptors;
-			want_comp_desc = 1;
-			break;
-		}
-		/* else: Fall trough */
-	case USB_SPEED_HIGH:
-		if (gadget_is_dualspeed(g)) {
-			speed_desc = f->hs_descriptors;
-			break;
-		}
-		/* else: fall through */
-	default:
-		speed_desc = f->descriptors;
-	}
-	/* find descriptors */
-	for_each_ep_desc(speed_desc, d_spd) {
-		chosen_desc = (struct usb_endpoint_descriptor *)*d_spd;
-		if (chosen_desc->bEndpointAddress == _ep->address)
-			goto ep_found;
-	}
-	return -EIO;
-
-ep_found:
-	/* commit results */
-	_ep->maxpacket = le16_to_cpu(chosen_desc->wMaxPacketSize);
-	_ep->desc = chosen_desc;
-	_ep->comp_desc = NULL;
-	_ep->maxburst = 0;
-	_ep->mult = 0;
-	if (!want_comp_desc)
-		return 0;
-
-	/*
-	 * Companion descriptor should follow EP descriptor
-	 * USB 3.0 spec, #9.6.7
-	 */
-	comp_desc = (struct usb_ss_ep_comp_descriptor *)*(++d_spd);
-	if (!comp_desc ||
-	    (comp_desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP))
-		return -EIO;
-	_ep->comp_desc = comp_desc;
-	if (g->speed == USB_SPEED_SUPER) {
-		switch (usb_endpoint_type(_ep->desc)) {
-		case USB_ENDPOINT_XFER_BULK:
-		case USB_ENDPOINT_XFER_INT:
-			_ep->maxburst = comp_desc->bMaxBurst;
-			break;
-		case USB_ENDPOINT_XFER_ISOC:
-			/* mult: bits 1:0 of bmAttributes */
-			_ep->mult = comp_desc->bmAttributes & 0x3;
-			break;
-		default:
-			/* Do nothing for control endpoints */
-			break;
-		}
-	}
-	return 0;
-}
 
 /**
  * usb_add_function() - add a function to a configuration
@@ -247,8 +123,6 @@
 		config->fullspeed = true;
 	if (!config->highspeed && function->hs_descriptors)
 		config->highspeed = true;
-	if (!config->superspeed && function->ss_descriptors)
-		config->superspeed = true;
 
 done:
 	if (value)
@@ -392,17 +266,10 @@
 	list_for_each_entry(f, &config->functions, list) {
 		struct usb_descriptor_header **descriptors;
 
-		switch (speed) {
-		case USB_SPEED_SUPER:
-			descriptors = f->ss_descriptors;
-			break;
-		case USB_SPEED_HIGH:
+		if (speed == USB_SPEED_HIGH)
 			descriptors = f->hs_descriptors;
-			break;
-		default:
+		else
 			descriptors = f->descriptors;
-		}
-
 		if (!descriptors)
 			continue;
 		status = usb_descriptor_fillbuf(next, len,
@@ -425,10 +292,9 @@
 	u8				type = w_value >> 8;
 	enum usb_device_speed		speed = USB_SPEED_UNKNOWN;
 
-	if (gadget->speed == USB_SPEED_SUPER)
-		speed = gadget->speed;
-	else if (gadget_is_dualspeed(gadget)) {
-		int	hs = 0;
+	if (gadget_is_dualspeed(gadget)) {
+		int			hs = 0;
+
 		if (gadget->speed == USB_SPEED_HIGH)
 			hs = 1;
 		if (type == USB_DT_OTHER_SPEED_CONFIG)
@@ -442,20 +308,13 @@
 	w_value &= 0xff;
 	list_for_each_entry(c, &cdev->configs, list) {
 		/* ignore configs that won't work at this speed */
-		switch (speed) {
-		case USB_SPEED_SUPER:
-			if (!c->superspeed)
-				continue;
-			break;
-		case USB_SPEED_HIGH:
+		if (speed == USB_SPEED_HIGH) {
 			if (!c->highspeed)
 				continue;
-			break;
-		default:
+		} else {
 			if (!c->fullspeed)
 				continue;
 		}
-
 		if (w_value == 0)
 			return config_buf(c, speed, cdev->req->buf, type);
 		w_value--;
@@ -469,22 +328,16 @@
 	struct usb_configuration	*c;
 	unsigned			count = 0;
 	int				hs = 0;
-	int				ss = 0;
 
 	if (gadget_is_dualspeed(gadget)) {
 		if (gadget->speed == USB_SPEED_HIGH)
 			hs = 1;
-		if (gadget->speed == USB_SPEED_SUPER)
-			ss = 1;
 		if (type == USB_DT_DEVICE_QUALIFIER)
 			hs = !hs;
 	}
 	list_for_each_entry(c, &cdev->configs, list) {
 		/* ignore configs that won't work at this speed */
-		if (ss) {
-			if (!c->superspeed)
-				continue;
-		} else if (hs) {
+		if (hs) {
 			if (!c->highspeed)
 				continue;
 		} else {
@@ -496,71 +349,6 @@
 	return count;
 }
 
-/**
- * bos_desc() - prepares the BOS descriptor.
- * @cdev: pointer to usb_composite device to generate the bos
- *	descriptor for
- *
- * This function generates the BOS (Binary Device Object)
- * descriptor and its device capabilities descriptors. The BOS
- * descriptor should be supported by a SuperSpeed device.
- */
-static int bos_desc(struct usb_composite_dev *cdev)
-{
-	struct usb_ext_cap_descriptor	*usb_ext;
-	struct usb_ss_cap_descriptor	*ss_cap;
-	struct usb_dcd_config_params	dcd_config_params;
-	struct usb_bos_descriptor	*bos = cdev->req->buf;
-
-	bos->bLength = USB_DT_BOS_SIZE;
-	bos->bDescriptorType = USB_DT_BOS;
-
-	bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE);
-	bos->bNumDeviceCaps = 0;
-
-	/*
-	 * A SuperSpeed device shall include the USB2.0 extension descriptor
-	 * and shall support LPM when operating in USB2.0 HS mode.
-	 */
-	usb_ext = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
-	bos->bNumDeviceCaps++;
-	le16_add_cpu(&bos->wTotalLength, USB_DT_USB_EXT_CAP_SIZE);
-	usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE;
-	usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
-	usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT;
-	usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT);
-
-	/*
-	 * The Superspeed USB Capability descriptor shall be implemented by all
-	 * SuperSpeed devices.
-	 */
-	ss_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
-	bos->bNumDeviceCaps++;
-	le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SS_CAP_SIZE);
-	ss_cap->bLength = USB_DT_USB_SS_CAP_SIZE;
-	ss_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
-	ss_cap->bDevCapabilityType = USB_SS_CAP_TYPE;
-	ss_cap->bmAttributes = 0; /* LTM is not supported yet */
-	ss_cap->wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION |
-				USB_FULL_SPEED_OPERATION |
-				USB_HIGH_SPEED_OPERATION |
-				USB_5GBPS_OPERATION);
-	ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION;
-
-	/* Get Controller configuration */
-	if (cdev->gadget->ops->get_config_params)
-		cdev->gadget->ops->get_config_params(&dcd_config_params);
-	else {
-		dcd_config_params.bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT;
-		dcd_config_params.bU2DevExitLat =
-			cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
-	}
-	ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat;
-	ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat;
-
-	return le16_to_cpu(bos->wTotalLength);
-}
-
 static void device_qual(struct usb_composite_dev *cdev)
 {
 	struct usb_qualifier_descriptor	*qual = cdev->req->buf;
@@ -573,7 +361,7 @@
 	qual->bDeviceSubClass = cdev->desc.bDeviceSubClass;
 	qual->bDeviceProtocol = cdev->desc.bDeviceProtocol;
 	/* ASSUME same EP0 fifo size at both speeds */
-	qual->bMaxPacketSize0 = cdev->gadget->ep0->maxpacket;
+	qual->bMaxPacketSize0 = cdev->desc.bMaxPacketSize0;
 	qual->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER);
 	qual->bRESERVED = 0;
 }
@@ -604,46 +392,28 @@
 	unsigned		power = gadget_is_otg(gadget) ? 8 : 100;
 	int			tmp;
 
+	if (cdev->config)
+		reset_config(cdev);
+
 	if (number) {
 		list_for_each_entry(c, &cdev->configs, list) {
 			if (c->bConfigurationValue == number) {
-				/*
-				 * We disable the FDs of the previous
-				 * configuration only if the new configuration
-				 * is a valid one
-				 */
-				if (cdev->config)
-					reset_config(cdev);
 				result = 0;
 				break;
 			}
 		}
 		if (result < 0)
 			goto done;
-	} else { /* Zero configuration value - need to reset the config */
-		if (cdev->config)
-			reset_config(cdev);
+	} else
 		result = 0;
-	}
 
 	INFO(cdev, "%s speed config #%d: %s\n",
 		({ char *speed;
 		switch (gadget->speed) {
-		case USB_SPEED_LOW:
-			speed = "low";
-			break;
-		case USB_SPEED_FULL:
-			speed = "full";
-			break;
-		case USB_SPEED_HIGH:
-			speed = "high";
-			break;
-		case USB_SPEED_SUPER:
-			speed = "super";
-			break;
-		default:
-			speed = "?";
-			break;
+		case USB_SPEED_LOW:	speed = "low"; break;
+		case USB_SPEED_FULL:	speed = "full"; break;
+		case USB_SPEED_HIGH:	speed = "high"; break;
+		default:		speed = "?"; break;
 		} ; speed; }), number, c ? c->label : "unconfigured");
 
 	if (!c)
@@ -665,16 +435,10 @@
 		 * function's setup callback instead of the current
 		 * configuration's setup callback.
 		 */
-		switch (gadget->speed) {
-		case USB_SPEED_SUPER:
-			descriptors = f->ss_descriptors;
-			break;
-		case USB_SPEED_HIGH:
+		if (gadget->speed == USB_SPEED_HIGH)
 			descriptors = f->hs_descriptors;
-			break;
-		default:
+		else
 			descriptors = f->descriptors;
-		}
 
 		for (; *descriptors; ++descriptors) {
 			struct usb_endpoint_descriptor *ep;
@@ -769,9 +533,8 @@
 	} else {
 		unsigned	i;
 
-		DBG(cdev, "cfg %d/%p speeds:%s%s%s\n",
+		DBG(cdev, "cfg %d/%p speeds:%s%s\n",
 			config->bConfigurationValue, config,
-			config->superspeed ? " super" : "",
 			config->highspeed ? " high" : "",
 			config->fullspeed
 				? (gadget_is_dualspeed(cdev->gadget)
@@ -1089,7 +852,6 @@
 	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
 	struct usb_request		*req = cdev->req;
 	int				value = -EOPNOTSUPP;
-	int				status = 0;
 	u16				w_index = le16_to_cpu(ctrl->wIndex);
 	u8				intf = w_index & 0xFF;
 	u16				w_value = le16_to_cpu(ctrl->wValue);
@@ -1121,29 +883,18 @@
 		case USB_DT_DEVICE:
 			cdev->desc.bNumConfigurations =
 				count_configs(cdev, USB_DT_DEVICE);
-			cdev->desc.bMaxPacketSize0 =
-				cdev->gadget->ep0->maxpacket;
-			if (gadget_is_superspeed(gadget)) {
-				if (gadget->speed >= USB_SPEED_SUPER)
-					cdev->desc.bcdUSB = cpu_to_le16(0x0300);
-				else
-					cdev->desc.bcdUSB = cpu_to_le16(0x0210);
-			}
-
 			value = min(w_length, (u16) sizeof cdev->desc);
 			memcpy(req->buf, &cdev->desc, value);
 			break;
 		case USB_DT_DEVICE_QUALIFIER:
-			if (!gadget_is_dualspeed(gadget) ||
-			    gadget->speed >= USB_SPEED_SUPER)
+			if (!gadget_is_dualspeed(gadget))
 				break;
 			device_qual(cdev);
 			value = min_t(int, w_length,
 				sizeof(struct usb_qualifier_descriptor));
 			break;
 		case USB_DT_OTHER_SPEED_CONFIG:
-			if (!gadget_is_dualspeed(gadget) ||
-			    gadget->speed >= USB_SPEED_SUPER)
+			if (!gadget_is_dualspeed(gadget))
 				break;
 			/* FALLTHROUGH */
 		case USB_DT_CONFIG:
@@ -1157,12 +908,6 @@
 			if (value >= 0)
 				value = min(w_length, (u16) value);
 			break;
-		case USB_DT_BOS:
-			if (gadget_is_superspeed(gadget)) {
-				value = bos_desc(cdev);
-				value = min(w_length, (u16) value);
-			}
-			break;
 		}
 		break;
 
@@ -1230,61 +975,6 @@
 		*((u8 *)req->buf) = value;
 		value = min(w_length, (u16) 1);
 		break;
-
-	/*
-	 * USB 3.0 additions:
-	 * Function driver should handle get_status request. If such cb
-	 * wasn't supplied we respond with default value = 0
-	 * Note: function driver should supply such cb only for the first
-	 * interface of the function
-	 */
-	case USB_REQ_GET_STATUS:
-		if (!gadget_is_superspeed(gadget))
-			goto unknown;
-		if (ctrl->bRequestType != (USB_DIR_IN | USB_RECIP_INTERFACE))
-			goto unknown;
-		value = 2;	/* This is the length of the get_status reply */
-		put_unaligned_le16(0, req->buf);
-		if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
-			break;
-		f = cdev->config->interface[intf];
-		if (!f)
-			break;
-		status = f->get_status ? f->get_status(f) : 0;
-		if (status < 0)
-			break;
-		put_unaligned_le16(status & 0x0000ffff, req->buf);
-		break;
-	/*
-	 * Function drivers should handle SetFeature/ClearFeature
-	 * (FUNCTION_SUSPEND) request. function_suspend cb should be supplied
-	 * only for the first interface of the function
-	 */
-	case USB_REQ_CLEAR_FEATURE:
-	case USB_REQ_SET_FEATURE:
-		if (!gadget_is_superspeed(gadget))
-			goto unknown;
-		if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE))
-			goto unknown;
-		switch (w_value) {
-		case USB_INTRF_FUNC_SUSPEND:
-			if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
-				break;
-			f = cdev->config->interface[intf];
-			if (!f)
-				break;
-			value = 0;
-			if (f->func_suspend)
-				value = f->func_suspend(f, w_index >> 8);
-			if (value < 0) {
-				ERROR(cdev,
-				      "func_suspend() returned error %d\n",
-				      value);
-				value = 0;
-			}
-			break;
-		}
-		break;
 	default:
 unknown:
 		VDBG(cdev,
@@ -1476,6 +1166,7 @@
 		goto fail;
 
 	cdev->desc = *composite->dev;
+	cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 
 	/* standardized runtime overrides for device ID data */
 	if (idVendor)
@@ -1582,11 +1273,7 @@
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver composite_driver = {
-#ifdef CONFIG_USB_GADGET_SUPERSPEED
-	.speed		= USB_SPEED_SUPER,
-#else
 	.speed		= USB_SPEED_HIGH,
-#endif
 
 	.unbind		= composite_unbind,
 
@@ -1632,8 +1319,6 @@
 		driver->iProduct = driver->name;
 	composite_driver.function =  (char *) driver->name;
 	composite_driver.driver.name = driver->name;
-	composite_driver.speed = min((u8)composite_driver.speed,
-				     (u8)driver->max_speed);
 	composite = driver;
 	composite_gadget_bind = bind;
 
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 7b3ae76..09084fd 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -164,3 +164,29 @@
 
 	return ret;
 }
+
+/**
+ * usb_find_endpoint - find a copy of an endpoint descriptor
+ * @src: original vector of descriptors
+ * @copy: copy of @src
+ * @match: endpoint descriptor found in @src
+ *
+ * This returns the copy of the @match descriptor made for @copy.  Its
+ * intended use is to help remembering the endpoint descriptor to use
+ * when enabling a given endpoint.
+ */
+struct usb_endpoint_descriptor *
+usb_find_endpoint(
+	struct usb_descriptor_header **src,
+	struct usb_descriptor_header **copy,
+	struct usb_endpoint_descriptor *match
+)
+{
+	while (*src) {
+		if (*src == (void *) match)
+			return (void *)*copy;
+		src++;
+		copy++;
+	}
+	return NULL;
+}
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c
index 8beefdd..dbe92ee 100644
--- a/drivers/usb/gadget/dbgp.c
+++ b/drivers/usb/gadget/dbgp.c
@@ -173,9 +173,7 @@
 
 static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc)
 {
-	int err;
-	ep->desc = desc;
-	err = usb_ep_enable(ep);
+	int err = usb_ep_enable(ep, desc);
 	ep->driver_data = dbgp.gadget;
 	return err;
 }
@@ -270,8 +268,8 @@
 	dbgp.serial->in = dbgp.i_ep;
 	dbgp.serial->out = dbgp.o_ep;
 
-	dbgp.serial->in->desc = &i_desc;
-	dbgp.serial->out->desc = &o_desc;
+	dbgp.serial->in_desc = &i_desc;
+	dbgp.serial->out_desc = &o_desc;
 
 	if (gserial_setup(gadget, 1) < 0) {
 		stp = 3;
@@ -314,6 +312,7 @@
 
 	dbgp.req->length = DBGP_REQ_EP0_LEN;
 	gadget->ep0->driver_data = gadget;
+	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 
 #ifdef CONFIG_USB_G_DBGP_SERIAL
 	dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL);
@@ -364,7 +363,6 @@
 			dev_dbg(&dbgp.gadget->dev, "setup: desc device\n");
 			len = sizeof device_desc;
 			data = &device_desc;
-			device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 			break;
 		case USB_DT_DEBUG:
 			dev_dbg(&dbgp.gadget->dev, "setup: desc debug\n");
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index cbcb4c7..d3dcabc 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -425,18 +425,10 @@
 		(desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
 		({ char *val;
 		 switch (desc->bmAttributes & 0x03) {
-		 case USB_ENDPOINT_XFER_BULK:
-			 val = "bulk";
-			 break;
-		 case USB_ENDPOINT_XFER_ISOC:
-			 val = "iso";
-			 break;
-		 case USB_ENDPOINT_XFER_INT:
-			 val = "intr";
-			 break;
-		 default:
-			 val = "ctrl";
-			 break;
+		 case USB_ENDPOINT_XFER_BULK: val = "bulk"; break;
+		 case USB_ENDPOINT_XFER_ISOC: val = "iso"; break;
+		 case USB_ENDPOINT_XFER_INT: val = "intr"; break;
+		 default: val = "ctrl"; break;
 		 }; val; }),
 		max);
 
@@ -718,17 +710,11 @@
 	return 0;
 }
 
-static int dummy_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int dummy_udc_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops dummy_ops = {
 	.get_frame	= dummy_g_get_frame,
 	.wakeup		= dummy_wakeup,
 	.set_selfpowered = dummy_set_selfpowered,
 	.pullup		= dummy_pullup,
-	.start		= dummy_udc_start,
-	.stop		= dummy_udc_stop,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -761,7 +747,8 @@
  * for each driver that registers:  just add to a big root hub.
  */
 
-static int dummy_udc_start(struct usb_gadget_driver *driver,
+int
+usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct dummy	*dum = the_controller;
@@ -825,8 +812,10 @@
 	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int dummy_udc_stop(struct usb_gadget_driver *driver)
+int
+usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
 	struct dummy	*dum = the_controller;
 	unsigned long	flags;
@@ -856,6 +845,7 @@
 	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
 
 #undef is_enabled
 
@@ -902,20 +892,11 @@
 		return rc;
 	}
 
-	rc = usb_add_gadget_udc(&pdev->dev, &dum->gadget);
-	if (rc < 0)
-		goto err_udc;
-
 	rc = device_create_file (&dum->gadget.dev, &dev_attr_function);
 	if (rc < 0)
-		goto err_dev;
-	platform_set_drvdata(pdev, dum);
-	return rc;
-
-err_dev:
-	usb_del_gadget_udc(&dum->gadget);
-err_udc:
-	device_unregister(&dum->gadget.dev);
+		device_unregister (&dum->gadget.dev);
+	else
+		platform_set_drvdata(pdev, dum);
 	return rc;
 }
 
@@ -923,7 +904,6 @@
 {
 	struct dummy	*dum = platform_get_drvdata (pdev);
 
-	usb_del_gadget_udc(&dum->gadget);
 	platform_set_drvdata (pdev, NULL);
 	device_remove_file (&dum->gadget.dev, &dev_attr_function);
 	device_unregister (&dum->gadget.dev);
@@ -1806,34 +1786,18 @@
 		urb,
 		({ char *s;
 		 switch (urb->dev->speed) {
-		 case USB_SPEED_LOW:
-			s = "ls";
-			break;
-		 case USB_SPEED_FULL:
-			s = "fs";
-			break;
-		 case USB_SPEED_HIGH:
-			s = "hs";
-			break;
-		 default:
-			s = "?";
-			break;
+		 case USB_SPEED_LOW:	s = "ls"; break;
+		 case USB_SPEED_FULL:	s = "fs"; break;
+		 case USB_SPEED_HIGH:	s = "hs"; break;
+		 default:		s = "?"; break;
 		 }; s; }),
 		ep, ep ? (usb_pipein (urb->pipe) ? "in" : "out") : "",
 		({ char *s; \
 		 switch (usb_pipetype (urb->pipe)) { \
-		 case PIPE_CONTROL: \
-			s = ""; \
-			break; \
-		 case PIPE_BULK: \
-			s = "-bulk"; \
-			break; \
-		 case PIPE_INTERRUPT: \
-			s = "-int"; \
-			break; \
-		 default: \
-			s = "-iso"; \
-			break; \
+		 case PIPE_CONTROL:	s = ""; break; \
+		 case PIPE_BULK:	s = "-bulk"; break; \
+		 case PIPE_INTERRUPT:	s = "-int"; break; \
+		 default: 		s = "-iso"; break; \
 		}; s;}),
 		urb->actual_length, urb->transfer_buffer_length);
 }
@@ -1899,6 +1863,7 @@
 	dum = hcd_to_dummy (hcd);
 
 	device_remove_file (dummy_dev(dum), &dev_attr_urbs);
+	usb_gadget_unregister_driver (dum->driver);
 	dev_info (dummy_dev(dum), "stopped\n");
 }
 
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 2fcfb9b..9b7360f 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -63,16 +63,13 @@
 ep_matches (
 	struct usb_gadget		*gadget,
 	struct usb_ep			*ep,
-	struct usb_endpoint_descriptor	*desc,
-	struct usb_ss_ep_comp_descriptor *ep_comp
+	struct usb_endpoint_descriptor	*desc
 )
 {
 	u8		type;
 	const char	*tmp;
 	u16		max;
 
-	int		num_req_streams = 0;
-
 	/* endpoint already claimed? */
 	if (NULL != ep->driver_data)
 		return 0;
@@ -132,19 +129,6 @@
 	}
 
 	/*
-	 * Get the number of required streams from the EP companion
-	 * descriptor and see if the EP matches it
-	 */
-	if (usb_endpoint_xfer_bulk(desc)) {
-		if (ep_comp) {
-			num_req_streams = ep_comp->bmAttributes & 0x1f;
-			if (num_req_streams > ep->max_streams)
-				return 0;
-		}
-
-	}
-
-	/*
 	 * If the protocol driver hasn't yet decided on wMaxPacketSize
 	 * and wants to know the maximum possible, provide the info.
 	 */
@@ -158,13 +142,13 @@
 	max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
 	switch (type) {
 	case USB_ENDPOINT_XFER_INT:
-		/* INT:  limit 64 bytes full speed, 1024 high/super speed */
+		/* INT:  limit 64 bytes full speed, 1024 high speed */
 		if (!gadget->is_dualspeed && max > 64)
 			return 0;
 		/* FALLTHROUGH */
 
 	case USB_ENDPOINT_XFER_ISOC:
-		/* ISO:  limit 1023 bytes full speed, 1024 high/super speed */
+		/* ISO:  limit 1023 bytes full speed, 1024 high speed */
 		if (ep->maxpacket < max)
 			return 0;
 		if (!gadget->is_dualspeed && max > 1023)
@@ -199,7 +183,7 @@
 	}
 
 	/* report (variable) full speed bulk maxpacket */
-	if ((USB_ENDPOINT_XFER_BULK == type) && !ep_comp) {
+	if (USB_ENDPOINT_XFER_BULK == type) {
 		int size = ep->maxpacket;
 
 		/* min() doesn't work on bitfields with gcc-3.5 */
@@ -207,7 +191,6 @@
 			size = 64;
 		desc->wMaxPacketSize = cpu_to_le16(size);
 	}
-	ep->address = desc->bEndpointAddress;
 	return 1;
 }
 
@@ -224,120 +207,7 @@
 }
 
 /**
- * usb_ep_autoconfig_ss() - choose an endpoint matching the ep
- * descriptor and ep companion descriptor
- * @gadget: The device to which the endpoint must belong.
- * @desc: Endpoint descriptor, with endpoint direction and transfer mode
- *    initialized.  For periodic transfers, the maximum packet
- *    size must also be initialized.  This is modified on
- *    success.
- * @ep_comp: Endpoint companion descriptor, with the required
- *    number of streams. Will be modified when the chosen EP
- *    supports a different number of streams.
- *
- * This routine replaces the usb_ep_autoconfig when needed
- * superspeed enhancments. If such enhancemnets are required,
- * the FD should call usb_ep_autoconfig_ss directly and provide
- * the additional ep_comp parameter.
- *
- * By choosing an endpoint to use with the specified descriptor,
- * this routine simplifies writing gadget drivers that work with
- * multiple USB device controllers.  The endpoint would be
- * passed later to usb_ep_enable(), along with some descriptor.
- *
- * That second descriptor won't always be the same as the first one.
- * For example, isochronous endpoints can be autoconfigured for high
- * bandwidth, and then used in several lower bandwidth altsettings.
- * Also, high and full speed descriptors will be different.
- *
- * Be sure to examine and test the results of autoconfiguration
- * on your hardware.  This code may not make the best choices
- * about how to use the USB controller, and it can't know all
- * the restrictions that may apply. Some combinations of driver
- * and hardware won't be able to autoconfigure.
- *
- * On success, this returns an un-claimed usb_ep, and modifies the endpoint
- * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
- * is initialized as if the endpoint were used at full speed and
- * the bmAttribute field in the ep companion descriptor is
- * updated with the assigned number of streams if it is
- * different from the original value. To prevent the endpoint
- * from being returned by a later autoconfig call, claim it by
- * assigning ep->driver_data to some non-null value.
- *
- * On failure, this returns a null endpoint descriptor.
- */
-struct usb_ep *usb_ep_autoconfig_ss(
-	struct usb_gadget		*gadget,
-	struct usb_endpoint_descriptor	*desc,
-	struct usb_ss_ep_comp_descriptor *ep_comp
-)
-{
-	struct usb_ep	*ep;
-	u8		type;
-
-	type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-
-	/* First, apply chip-specific "best usage" knowledge.
-	 * This might make a good usb_gadget_ops hook ...
-	 */
-	if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) {
-		/* ep-e, ep-f are PIO with only 64 byte fifos */
-		ep = find_ep (gadget, "ep-e");
-		if (ep && ep_matches(gadget, ep, desc, ep_comp))
-			return ep;
-		ep = find_ep (gadget, "ep-f");
-		if (ep && ep_matches(gadget, ep, desc, ep_comp))
-			return ep;
-
-	} else if (gadget_is_goku (gadget)) {
-		if (USB_ENDPOINT_XFER_INT == type) {
-			/* single buffering is enough */
-			ep = find_ep(gadget, "ep3-bulk");
-			if (ep && ep_matches(gadget, ep, desc, ep_comp))
-				return ep;
-		} else if (USB_ENDPOINT_XFER_BULK == type
-				&& (USB_DIR_IN & desc->bEndpointAddress)) {
-			/* DMA may be available */
-			ep = find_ep(gadget, "ep2-bulk");
-			if (ep && ep_matches(gadget, ep, desc,
-					      ep_comp))
-				return ep;
-		}
-
-#ifdef CONFIG_BLACKFIN
-	} else if (gadget_is_musbhdrc(gadget)) {
-		if ((USB_ENDPOINT_XFER_BULK == type) ||
-		    (USB_ENDPOINT_XFER_ISOC == type)) {
-			if (USB_DIR_IN & desc->bEndpointAddress)
-				ep = find_ep (gadget, "ep5in");
-			else
-				ep = find_ep (gadget, "ep6out");
-		} else if (USB_ENDPOINT_XFER_INT == type) {
-			if (USB_DIR_IN & desc->bEndpointAddress)
-				ep = find_ep(gadget, "ep1in");
-			else
-				ep = find_ep(gadget, "ep2out");
-		} else
-			ep = NULL;
-		if (ep && ep_matches(gadget, ep, desc, ep_comp))
-			return ep;
-#endif
-	}
-
-	/* Second, look at endpoints until an unclaimed one looks usable */
-	list_for_each_entry (ep, &gadget->ep_list, ep_list) {
-		if (ep_matches(gadget, ep, desc, ep_comp))
-			return ep;
-	}
-
-	/* Fail */
-	return NULL;
-}
-
-/**
- * usb_ep_autoconfig() - choose an endpoint matching the
- * descriptor
+ * usb_ep_autoconfig - choose an endpoint matching the descriptor
  * @gadget: The device to which the endpoint must belong.
  * @desc: Endpoint descriptor, with endpoint direction and transfer mode
  *	initialized.  For periodic transfers, the maximum packet
@@ -366,14 +236,71 @@
  *
  * On failure, this returns a null endpoint descriptor.
  */
-struct usb_ep *usb_ep_autoconfig(
+struct usb_ep *usb_ep_autoconfig (
 	struct usb_gadget		*gadget,
 	struct usb_endpoint_descriptor	*desc
 )
 {
-	return usb_ep_autoconfig_ss(gadget, desc, NULL);
-}
+	struct usb_ep	*ep;
+	u8		type;
 
+	type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+	/* First, apply chip-specific "best usage" knowledge.
+	 * This might make a good usb_gadget_ops hook ...
+	 */
+	if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) {
+		/* ep-e, ep-f are PIO with only 64 byte fifos */
+		ep = find_ep (gadget, "ep-e");
+		if (ep && ep_matches (gadget, ep, desc))
+			return ep;
+		ep = find_ep (gadget, "ep-f");
+		if (ep && ep_matches (gadget, ep, desc))
+			return ep;
+
+	} else if (gadget_is_goku (gadget)) {
+		if (USB_ENDPOINT_XFER_INT == type) {
+			/* single buffering is enough */
+			ep = find_ep (gadget, "ep3-bulk");
+			if (ep && ep_matches (gadget, ep, desc))
+				return ep;
+		} else if (USB_ENDPOINT_XFER_BULK == type
+				&& (USB_DIR_IN & desc->bEndpointAddress)) {
+			/* DMA may be available */
+			ep = find_ep (gadget, "ep2-bulk");
+			if (ep && ep_matches (gadget, ep, desc))
+				return ep;
+		}
+
+#ifdef CONFIG_BLACKFIN
+	} else if (gadget_is_musbhdrc(gadget)) {
+		if ((USB_ENDPOINT_XFER_BULK == type) ||
+		    (USB_ENDPOINT_XFER_ISOC == type)) {
+			if (USB_DIR_IN & desc->bEndpointAddress)
+				ep = find_ep (gadget, "ep5in");
+			else
+				ep = find_ep (gadget, "ep6out");
+		} else if (USB_ENDPOINT_XFER_INT == type) {
+			if (USB_DIR_IN & desc->bEndpointAddress)
+				ep = find_ep(gadget, "ep1in");
+			else
+				ep = find_ep(gadget, "ep2out");
+		} else
+			ep = NULL;
+		if (ep && ep_matches (gadget, ep, desc))
+			return ep;
+#endif
+	}
+
+	/* Second, look at endpoints until an unclaimed one looks usable */
+	list_for_each_entry (ep, &gadget->ep_list, ep_list) {
+		if (ep_matches (gadget, ep, desc))
+			return ep;
+	}
+
+	/* Fail */
+	return NULL;
+}
 
 /**
  * usb_ep_autoconfig_reset - reset endpoint autoconfig state
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index ac41858..1690c9d 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -401,7 +401,6 @@
 	.name		= "g_ether",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(eth_unbind),
 };
 
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c
index 0187b69..05e65e5 100644
--- a/drivers/usb/gadget/f_accessory.c
+++ b/drivers/usb/gadget/f_accessory.c
@@ -686,33 +686,17 @@
 	int ret;
 
 	DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt);
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
-	if (ret) {
-		dev->ep_in->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-				dev->ep_in->name, ret);
-			return ret;
-	}
-	ret = usb_ep_enable(dev->ep_in);
-	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-			dev->ep_in->name, ret);
+	ret = usb_ep_enable(dev->ep_in,
+			ep_choose(cdev->gadget,
+				&acc_highspeed_in_desc,
+				&acc_fullspeed_in_desc));
+	if (ret)
 		return ret;
-	}
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
+	ret = usb_ep_enable(dev->ep_out,
+			ep_choose(cdev->gadget,
+				&acc_highspeed_out_desc,
+				&acc_fullspeed_out_desc));
 	if (ret) {
-		dev->ep_out->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->ep_out->name, ret);
-		usb_ep_disable(dev->ep_in);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->ep_out);
-	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-				dev->ep_out->name, ret);
 		usb_ep_disable(dev->ep_in);
 		return ret;
 	}
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index a30126f..69a36af 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -42,6 +42,12 @@
  * descriptors (roughly equivalent to CDC Unions) may sometimes help.
  */
 
+struct acm_ep_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+	struct usb_endpoint_descriptor	*notify;
+};
+
 struct f_acm {
 	struct gserial			port;
 	u8				ctrl_id, data_id;
@@ -56,7 +62,11 @@
 	 */
 	spinlock_t			lock;
 
+	struct acm_ep_descs		fs;
+	struct acm_ep_descs		hs;
+
 	struct usb_ep			*notify;
+	struct usb_endpoint_descriptor	*notify_desc;
 	struct usb_request		*notify_req;
 
 	struct usb_cdc_line_coding	port_line_coding;	/* 8-N-1 etc */
@@ -487,10 +497,10 @@
 		} else {
 			VDBG(cdev, "init acm ctrl interface %d\n", intf);
 		}
-		if (config_ep_by_speed(cdev->gadget, f, acm->notify))
-			return -EINVAL;
-
-		usb_ep_enable(acm->notify);
+		acm->notify_desc = ep_choose(cdev->gadget,
+				acm->hs.notify,
+				acm->fs.notify);
+		usb_ep_enable(acm->notify, acm->notify_desc);
 		acm->notify->driver_data = acm;
 
 	} else if (intf == acm->data_id) {
@@ -500,15 +510,10 @@
 		} else {
 			DBG(cdev, "activate acm ttyGS%d\n", acm->port_num);
 		}
-		if (config_ep_by_speed(cdev->gadget, f,
-				acm->port.in) ||
-			config_ep_by_speed(cdev->gadget, f,
-				acm->port.out)) {
-			acm->port.in->desc = NULL;
-			acm->port.out->desc = NULL;
-			return -EINVAL;
-		}
-
+		acm->port.in_desc = ep_choose(cdev->gadget,
+				acm->hs.in, acm->fs.in);
+		acm->port.out_desc = ep_choose(cdev->gadget,
+				acm->hs.out, acm->fs.out);
 		acm_port_connect(acm);
 
 	} else
@@ -724,11 +729,18 @@
 	acm->notify_req->complete = acm_cdc_notify_complete;
 	acm->notify_req->context = acm;
 
-	/* copy descriptors */
+	/* copy descriptors, and track endpoint copies */
 	f->descriptors = usb_copy_descriptors(acm_fs_function);
 	if (!f->descriptors)
 		goto fail;
 
+	acm->fs.in = usb_find_endpoint(acm_fs_function,
+			f->descriptors, &acm_fs_in_desc);
+	acm->fs.out = usb_find_endpoint(acm_fs_function,
+			f->descriptors, &acm_fs_out_desc);
+	acm->fs.notify = usb_find_endpoint(acm_fs_function,
+			f->descriptors, &acm_fs_notify_desc);
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -741,8 +753,15 @@
 		acm_hs_notify_desc.bEndpointAddress =
 				acm_fs_notify_desc.bEndpointAddress;
 
-		/* copy descriptors */
+		/* copy descriptors, and track endpoint copies */
 		f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
+
+		acm->hs.in = usb_find_endpoint(acm_hs_function,
+				f->hs_descriptors, &acm_hs_in_desc);
+		acm->hs.out = usb_find_endpoint(acm_hs_function,
+				f->hs_descriptors, &acm_hs_out_desc);
+		acm->hs.notify = usb_find_endpoint(acm_hs_function,
+				f->hs_descriptors, &acm_hs_notify_desc);
 	}
 
 	DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c
index 0cf6d48..cae0136 100644
--- a/drivers/usb/gadget/f_adb.c
+++ b/drivers/usb/gadget/f_adb.c
@@ -510,33 +510,17 @@
 	int ret;
 
 	DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt);
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
-	if (ret) {
-		dev->ep_in->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-				dev->ep_in->name, ret);
+	ret = usb_ep_enable(dev->ep_in,
+			ep_choose(cdev->gadget,
+				&adb_highspeed_in_desc,
+				&adb_fullspeed_in_desc));
+	if (ret)
 		return ret;
-	}
-	ret = usb_ep_enable(dev->ep_in);
+	ret = usb_ep_enable(dev->ep_out,
+			ep_choose(cdev->gadget,
+				&adb_highspeed_out_desc,
+				&adb_fullspeed_out_desc));
 	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-			dev->ep_in->name, ret);
-		return ret;
-	}
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
-	if (ret) {
-		dev->ep_out->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->ep_out->name, ret);
-		usb_ep_disable(dev->ep_in);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->ep_out);
-	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-				dev->ep_out->name, ret);
 		usb_ep_disable(dev->ep_in);
 		return ret;
 	}
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index 02a0270..8ee330a 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -279,6 +279,7 @@
 
 	/* endpoints handle full and/or high speeds */
 	struct usb_ep			*out_ep;
+	struct usb_endpoint_descriptor	*out_desc;
 
 	spinlock_t			lock;
 	struct f_audio_buf *copy_buf;
@@ -574,7 +575,7 @@
 
 	if (intf == 1) {
 		if (alt == 1) {
-			usb_ep_enable(out_ep);
+			usb_ep_enable(out_ep, audio->out_desc);
 			out_ep->driver_data = audio;
 			audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
 			if (IS_ERR(audio->copy_buf))
@@ -676,7 +677,6 @@
 	if (!ep)
 		goto fail;
 	audio->out_ep = ep;
-	audio->out_ep->desc = &as_out_ep_desc;
 	ep->driver_data = cdev;	/* claim */
 
 	status = -ENOMEM;
@@ -776,6 +776,7 @@
 	audio->card.func.set_alt = f_audio_set_alt;
 	audio->card.func.setup = f_audio_setup;
 	audio->card.func.disable = f_audio_disable;
+	audio->out_desc = &as_out_ep_desc;
 
 	control_selector_init(audio);
 
diff --git a/drivers/usb/gadget/f_ccid.c b/drivers/usb/gadget/f_ccid.c
index c8f144a..a11f439 100644
--- a/drivers/usb/gadget/f_ccid.c
+++ b/drivers/usb/gadget/f_ccid.c
@@ -33,6 +33,12 @@
 /* number of tx requests to allocate */
 #define TX_REQ_MAX 4
 
+struct ccid_descs {
+	struct usb_endpoint_descriptor *in;
+	struct usb_endpoint_descriptor *out;
+	struct usb_endpoint_descriptor *notify;
+};
+
 struct ccid_ctrl_dev {
 	atomic_t opened;
 	struct list_head tx_q;
@@ -58,10 +64,16 @@
 	int ifc_id;
 	spinlock_t lock;
 	atomic_t online;
+	/* usb descriptors */
+	struct ccid_descs fs;
+	struct ccid_descs hs;
 	/* usb eps*/
 	struct usb_ep *notify;
 	struct usb_ep *in;
 	struct usb_ep *out;
+	struct usb_endpoint_descriptor *in_desc;
+	struct usb_endpoint_descriptor *out_desc;
+	struct usb_endpoint_descriptor *notify_desc;
 	struct usb_request *notify_req;
 	struct ccid_ctrl_dev ctrl_dev;
 	struct ccid_bulk_dev bulk_dev;
@@ -424,14 +436,10 @@
 	}
 
 	/* choose the descriptors and enable endpoints */
-	ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->notify);
-	if (ret) {
-		ccid_dev->notify->desc = NULL;
-		pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n",
-				__func__, ccid_dev->notify->name, ret);
-		goto free_bulk_in;
-	}
-	ret = usb_ep_enable(ccid_dev->notify);
+	ccid_dev->notify_desc = ep_choose(cdev->gadget,
+				ccid_dev->hs.notify,
+				ccid_dev->fs.notify);
+	ret = usb_ep_enable(ccid_dev->notify, ccid_dev->notify_desc);
 	if (ret) {
 		pr_err("%s: usb ep#%s enable failed, err#%d\n",
 				__func__, ccid_dev->notify->name, ret);
@@ -439,28 +447,18 @@
 	}
 	ccid_dev->notify->driver_data = ccid_dev;
 
-	ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->in);
-	if (ret) {
-		ccid_dev->in->desc = NULL;
-		pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n",
-				__func__, ccid_dev->in->name, ret);
-		goto disable_ep_notify;
-	}
-	ret = usb_ep_enable(ccid_dev->in);
+	ccid_dev->in_desc = ep_choose(cdev->gadget,
+			ccid_dev->hs.in, ccid_dev->fs.in);
+	ret = usb_ep_enable(ccid_dev->in, ccid_dev->in_desc);
 	if (ret) {
 		pr_err("%s: usb ep#%s enable failed, err#%d\n",
 				__func__, ccid_dev->in->name, ret);
 		goto disable_ep_notify;
 	}
 
-	ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->out);
-	if (ret) {
-		ccid_dev->out->desc = NULL;
-		pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n",
-				__func__, ccid_dev->out->name, ret);
-		goto disable_ep_in;
-	}
-	ret = usb_ep_enable(ccid_dev->out);
+	ccid_dev->out_desc = ep_choose(cdev->gadget,
+			ccid_dev->hs.out, ccid_dev->fs.out);
+	ret = usb_ep_enable(ccid_dev->out, ccid_dev->out_desc);
 	if (ret) {
 		pr_err("%s: usb ep#%s enable failed, err#%d\n",
 				__func__, ccid_dev->out->name, ret);
@@ -540,6 +538,16 @@
 	if (!f->descriptors)
 		goto ep_auto_out_fail;
 
+	ccid_dev->fs.in = usb_find_endpoint(ccid_fs_descs,
+					f->descriptors,
+					&ccid_fs_in_desc);
+	ccid_dev->fs.out = usb_find_endpoint(ccid_fs_descs,
+					f->descriptors,
+					&ccid_fs_out_desc);
+	ccid_dev->fs.notify = usb_find_endpoint(ccid_fs_descs,
+					f->descriptors,
+					&ccid_fs_notify_desc);
+
 	if (gadget_is_dualspeed(cdev->gadget)) {
 		ccid_hs_in_desc.bEndpointAddress =
 				ccid_fs_in_desc.bEndpointAddress;
@@ -552,6 +560,13 @@
 		f->hs_descriptors = usb_copy_descriptors(ccid_hs_descs);
 		if (!f->hs_descriptors)
 			goto ep_auto_out_fail;
+
+		ccid_dev->hs.in = usb_find_endpoint(ccid_hs_descs,
+				f->hs_descriptors, &ccid_hs_in_desc);
+		ccid_dev->hs.out = usb_find_endpoint(ccid_hs_descs,
+				f->hs_descriptors, &ccid_hs_out_desc);
+		ccid_dev->hs.notify = usb_find_endpoint(ccid_hs_descs,
+				f->hs_descriptors, &ccid_hs_notify_desc);
 	}
 
 	pr_debug("%s: CCID %s Speed, IN:%s OUT:%s\n", __func__,
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index c4c7941..987ae65 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -108,6 +108,8 @@
 	struct usb_function function;
 	struct usb_ep *out;
 	struct usb_ep *in;
+	struct usb_endpoint_descriptor  *in_desc;
+	struct usb_endpoint_descriptor  *out_desc;
 	struct list_head read_pool;
 	struct list_head write_pool;
 	struct work_struct config_work;
@@ -512,22 +514,21 @@
 	unsigned long flags;
 	int rc = 0;
 
-	if (config_ep_by_speed(cdev->gadget, f, dev->in) ||
-	    config_ep_by_speed(cdev->gadget, f, dev->out)) {
-		dev->in->desc = NULL;
-		dev->out->desc = NULL;
-		return -EINVAL;
-	}
-
+	dev->in_desc = ep_choose(cdev->gadget,
+			(struct usb_endpoint_descriptor *)f->hs_descriptors[1],
+			(struct usb_endpoint_descriptor *)f->descriptors[1]);
+	dev->out_desc = ep_choose(cdev->gadget,
+			(struct usb_endpoint_descriptor *)f->hs_descriptors[2],
+			(struct usb_endpoint_descriptor *)f->descriptors[2]);
 	dev->in->driver_data = dev;
-	rc = usb_ep_enable(dev->in);
+	rc = usb_ep_enable(dev->in, dev->in_desc);
 	if (rc) {
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->in->name, rc);
 		return rc;
 	}
 	dev->out->driver_data = dev;
-	rc = usb_ep_enable(dev->out);
+	rc = usb_ep_enable(dev->out, dev->out_desc);
 	if (rc) {
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->out->name, rc);
@@ -629,7 +630,7 @@
 	/* claim the channel for this USB interface */
 	_ch->priv_usb = dev;
 
-	dev->update_pid_and_serial_num = update_pid;
+	dev->update_pid_and_serial_num = update_pid; 
 	dev->cdev = c->cdev;
 	dev->function.name = _ch->name;
 	dev->function.descriptors = fs_diag_desc;
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index ddedbc83..544257a 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -46,6 +46,11 @@
  * and also means that a get_alt() method is required.
  */
 
+struct ecm_ep_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+	struct usb_endpoint_descriptor	*notify;
+};
 
 enum ecm_notify_state {
 	ECM_NOTIFY_NONE,		/* don't notify */
@@ -59,7 +64,11 @@
 
 	char				ethaddr[14];
 
+	struct ecm_ep_descs		fs;
+	struct ecm_ep_descs		hs;
+
 	struct usb_ep			*notify;
+	struct usb_endpoint_descriptor	*notify_desc;
 	struct usb_request		*notify_req;
 	u8				notify_state;
 	bool				is_open;
@@ -455,13 +464,13 @@
 		if (ecm->notify->driver_data) {
 			VDBG(cdev, "reset ecm control %d\n", intf);
 			usb_ep_disable(ecm->notify);
-		}
-		if (!(ecm->notify->desc)) {
+		} else {
 			VDBG(cdev, "init ecm ctrl %d\n", intf);
-			if (config_ep_by_speed(cdev->gadget, f, ecm->notify))
-				goto fail;
+			ecm->notify_desc = ep_choose(cdev->gadget,
+					ecm->hs.notify,
+					ecm->fs.notify);
 		}
-		usb_ep_enable(ecm->notify);
+		usb_ep_enable(ecm->notify, ecm->notify_desc);
 		ecm->notify->driver_data = ecm;
 
 	/* Data interface has two altsettings, 0 and 1 */
@@ -474,17 +483,12 @@
 			gether_disconnect(&ecm->port);
 		}
 
-		if (!ecm->port.in_ep->desc ||
-		    !ecm->port.out_ep->desc) {
+		if (!ecm->port.in) {
 			DBG(cdev, "init ecm\n");
-			if (config_ep_by_speed(cdev->gadget, f,
-					       ecm->port.in_ep) ||
-			    config_ep_by_speed(cdev->gadget, f,
-					       ecm->port.out_ep)) {
-				ecm->port.in_ep->desc = NULL;
-				ecm->port.out_ep->desc = NULL;
-				goto fail;
-			}
+			ecm->port.in = ep_choose(cdev->gadget,
+					ecm->hs.in, ecm->fs.in);
+			ecm->port.out = ep_choose(cdev->gadget,
+					ecm->hs.out, ecm->fs.out);
 		}
 
 		/* CDC Ethernet only sends data in non-default altsettings.
@@ -545,7 +549,7 @@
 	if (ecm->notify->driver_data) {
 		usb_ep_disable(ecm->notify);
 		ecm->notify->driver_data = NULL;
-		ecm->notify->desc = NULL;
+		ecm->notify_desc = NULL;
 	}
 }
 
@@ -661,6 +665,13 @@
 	if (!f->descriptors)
 		goto fail;
 
+	ecm->fs.in = usb_find_endpoint(ecm_fs_function,
+			f->descriptors, &fs_ecm_in_desc);
+	ecm->fs.out = usb_find_endpoint(ecm_fs_function,
+			f->descriptors, &fs_ecm_out_desc);
+	ecm->fs.notify = usb_find_endpoint(ecm_fs_function,
+			f->descriptors, &fs_ecm_notify_desc);
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -677,6 +688,13 @@
 		f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
 		if (!f->hs_descriptors)
 			goto fail;
+
+		ecm->hs.in = usb_find_endpoint(ecm_hs_function,
+				f->hs_descriptors, &hs_ecm_in_desc);
+		ecm->hs.out = usb_find_endpoint(ecm_hs_function,
+				f->hs_descriptors, &hs_ecm_out_desc);
+		ecm->hs.notify = usb_find_endpoint(ecm_hs_function,
+				f->hs_descriptors, &hs_ecm_notify_desc);
 	}
 
 	/* NOTE:  all that is done without knowing or caring about
@@ -705,9 +723,9 @@
 	/* we might as well release our claims on endpoints */
 	if (ecm->notify)
 		ecm->notify->driver_data = NULL;
-	if (ecm->port.out_ep->desc)
+	if (ecm->port.out)
 		ecm->port.out_ep->driver_data = NULL;
-	if (ecm->port.in_ep->desc)
+	if (ecm->port.in)
 		ecm->port.in_ep->driver_data = NULL;
 
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index 3e41274..b3c3042 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -35,9 +35,17 @@
  * Ethernet link.
  */
 
+struct eem_ep_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+};
+
 struct f_eem {
 	struct gether			port;
 	u8				ctrl_id;
+
+	struct eem_ep_descs		fs;
+	struct eem_ep_descs		hs;
 };
 
 static inline struct f_eem *func_to_eem(struct usb_function *f)
@@ -168,16 +176,12 @@
 			gether_disconnect(&eem->port);
 		}
 
-		if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
+		if (!eem->port.in) {
 			DBG(cdev, "init eem\n");
-			if (config_ep_by_speed(cdev->gadget, f,
-					       eem->port.in_ep) ||
-			    config_ep_by_speed(cdev->gadget, f,
-					       eem->port.out_ep)) {
-				eem->port.in_ep->desc = NULL;
-				eem->port.out_ep->desc = NULL;
-				goto fail;
-			}
+			eem->port.in = ep_choose(cdev->gadget,
+					eem->hs.in, eem->fs.in);
+			eem->port.out = ep_choose(cdev->gadget,
+					eem->hs.out, eem->fs.out);
 		}
 
 		/* zlps should not occur because zero-length EEM packets
@@ -249,6 +253,11 @@
 	if (!f->descriptors)
 		goto fail;
 
+	eem->fs.in = usb_find_endpoint(eem_fs_function,
+			f->descriptors, &eem_fs_in_desc);
+	eem->fs.out = usb_find_endpoint(eem_fs_function,
+			f->descriptors, &eem_fs_out_desc);
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -263,6 +272,11 @@
 		f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
 		if (!f->hs_descriptors)
 			goto fail;
+
+		eem->hs.in = usb_find_endpoint(eem_hs_function,
+				f->hs_descriptors, &eem_hs_in_desc);
+		eem->hs.out = usb_find_endpoint(eem_hs_function,
+				f->hs_descriptors, &eem_hs_out_desc);
 	}
 
 	DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
@@ -275,9 +289,9 @@
 		usb_free_descriptors(f->descriptors);
 
 	/* we might as well release our claims on endpoints */
-	if (eem->port.out_ep->desc)
+	if (eem->port.out)
 		eem->port.out_ep->driver_data = NULL;
-	if (eem->port.in_ep->desc)
+	if (eem->port.in)
 		eem->port.in_ep->driver_data = NULL;
 
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index c161a9a..19fffcc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1544,8 +1544,7 @@
 		ds = ep->descs[ep->descs[1] ? 1 : 0];
 
 		ep->ep->driver_data = ep;
-		ep->ep->desc = ds;
-		ret = usb_ep_enable(ep->ep);
+		ret = usb_ep_enable(ep->ep, ds);
 		if (likely(!ret)) {
 			epfile->ep = ep;
 			epfile->in = usb_endpoint_dir_in(ds);
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 403a48b..598e7e2 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -59,6 +59,8 @@
 	struct cdev			cdev;
 	struct usb_function		func;
 	struct usb_ep			*in_ep;
+	struct usb_endpoint_descriptor	*fs_in_ep_desc;
+	struct usb_endpoint_descriptor	*hs_in_ep_desc;
 };
 
 static inline struct f_hidg *func_to_hidg(struct usb_function *f)
@@ -414,6 +416,7 @@
 {
 	struct usb_composite_dev		*cdev = f->config->cdev;
 	struct f_hidg				*hidg = func_to_hidg(f);
+	const struct usb_endpoint_descriptor	*ep_desc;
 	int status = 0;
 
 	VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt);
@@ -423,13 +426,9 @@
 		if (hidg->in_ep->driver_data != NULL)
 			usb_ep_disable(hidg->in_ep);
 
-		status = config_ep_by_speed(f->config->cdev->gadget, f,
-					    hidg->in_ep);
-		if (status) {
-			ERROR(cdev, "config_ep_by_speed FAILED!\n");
-			goto fail;
-		}
-		status = usb_ep_enable(hidg->in_ep);
+		ep_desc = ep_choose(f->config->cdev->gadget,
+				hidg->hs_in_ep_desc, hidg->fs_in_ep_desc);
+		status = usb_ep_enable(hidg->in_ep, ep_desc);
 		if (status < 0) {
 			ERROR(cdev, "Enable endpoint FAILED!\n");
 			goto fail;
@@ -499,12 +498,21 @@
 	if (!f->descriptors)
 		goto fail;
 
+	hidg->fs_in_ep_desc = usb_find_endpoint(hidg_fs_descriptors,
+						f->descriptors,
+						&hidg_fs_in_ep_desc);
+
 	if (gadget_is_dualspeed(c->cdev->gadget)) {
 		hidg_hs_in_ep_desc.bEndpointAddress =
 			hidg_fs_in_ep_desc.bEndpointAddress;
 		f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors);
 		if (!f->hs_descriptors)
 			goto fail;
+		hidg->hs_in_ep_desc = usb_find_endpoint(hidg_hs_descriptors,
+							f->hs_descriptors,
+							&hidg_hs_in_ep_desc);
+	} else {
+		hidg->hs_in_ep_desc = NULL;
 	}
 
 	mutex_init(&hidg->lock);
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 3756326..b37960f 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -250,27 +250,26 @@
 enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
 {
 	int					result = 0;
+	const struct usb_endpoint_descriptor	*src, *sink;
 	struct usb_ep				*ep;
 	struct usb_request			*req;
 	unsigned				i;
 
+	src = ep_choose(cdev->gadget,
+			&hs_loop_source_desc, &fs_loop_source_desc);
+	sink = ep_choose(cdev->gadget,
+			&hs_loop_sink_desc, &fs_loop_sink_desc);
+
 	/* one endpoint writes data back IN to the host */
 	ep = loop->in_ep;
-	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
-	if (result)
-		return result;
-	result = usb_ep_enable(ep);
+	result = usb_ep_enable(ep, src);
 	if (result < 0)
 		return result;
 	ep->driver_data = loop;
 
 	/* one endpoint just reads OUT packets */
 	ep = loop->out_ep;
-	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
-	if (result)
-		goto fail0;
-
-	result = usb_ep_enable(ep);
+	result = usb_ep_enable(ep, sink);
 	if (result < 0) {
 fail0:
 		ep = loop->in_ep;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 3d35c78..55d9a307 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -112,7 +112,8 @@
  * is not loaded (an empty string as "filename" in the fsg_config
  * structure causes error).  The CD-ROM emulation includes a single
  * data track and no audio tracks; hence there need be only one
- * backing file per LUN.
+ * backing file per LUN.  Note also that the CD-ROM block length is
+ * set to 512 rather than the more common value 2048.
  *
  *
  * MSF includes support for module parameters.  If gadget using it
@@ -748,6 +749,7 @@
 	u32			amount_left;
 	loff_t			file_offset, file_offset_tmp;
 	unsigned int		amount;
+	unsigned int		partial_page;
 	ssize_t			nread;
 #ifdef CONFIG_USB_MSC_PROFILING
 	ktime_t			start, diff;
@@ -776,7 +778,7 @@
 		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
 		return -EINVAL;
 	}
-	file_offset = ((loff_t) lba) << curlun->blkbits;
+	file_offset = ((loff_t) lba) << 9;
 
 	/* Carry out the file reads */
 	amount_left = common->data_size_from_cmnd;
@@ -789,10 +791,18 @@
 		 * Try to read the remaining amount.
 		 * But don't read more than the buffer size.
 		 * And don't try to read past the end of the file.
+		 * Finally, if we're not at a page boundary, don't read past
+		 *	the next page.
+		 * If this means reading 0 then we were asked to read past
+		 *	the end of file.
 		 */
 		amount = min(amount_left, FSG_BUFLEN);
 		amount = min((loff_t)amount,
 			     curlun->file_length - file_offset);
+		partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+		if (partial_page > 0)
+			amount = min(amount, (unsigned int)PAGE_CACHE_SIZE -
+					     partial_page);
 
 		/* Wait for the next buffer to become available */
 		bh = common->next_buffhd_to_fill;
@@ -809,8 +819,7 @@
 		if (amount == 0) {
 			curlun->sense_data =
 					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-			curlun->sense_data_info =
-					file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			bh->inreq->length = 0;
 			bh->state = BUF_STATE_FULL;
@@ -842,25 +851,18 @@
 		} else if (nread < amount) {
 			LDBG(curlun, "partial file read: %d/%u\n",
 			     (int)nread, amount);
-			nread = round_down(nread, curlun->blksize);
+			nread -= (nread & 511);	/* Round down to a block */
 		}
 		file_offset  += nread;
 		amount_left  -= nread;
 		common->residue -= nread;
-
-		/*
-		 * Except at the end of the transfer, nread will be
-		 * equal to the buffer size, which is divisible by the
-		 * bulk-in maxpacket size.
-		 */
 		bh->inreq->length = nread;
 		bh->state = BUF_STATE_FULL;
 
 		/* If an error occurred, report it and its position */
 		if (nread < amount) {
 			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
-			curlun->sense_data_info =
-					file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			break;
 		}
@@ -891,6 +893,7 @@
 	u32			amount_left_to_req, amount_left_to_write;
 	loff_t			usb_offset, file_offset, file_offset_tmp;
 	unsigned int		amount;
+	unsigned int		partial_page;
 	ssize_t			nwritten;
 	int			rc;
 
@@ -941,7 +944,7 @@
 
 	/* Carry out the file writes */
 	get_some_more = 1;
-	file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
+	file_offset = usb_offset = ((loff_t) lba) << 9;
 	amount_left_to_req = common->data_size_from_cmnd;
 	amount_left_to_write = common->data_size_from_cmnd;
 
@@ -953,21 +956,41 @@
 
 			/*
 			 * Figure out how much we want to get:
-			 * Try to get the remaining amount,
-			 * but not more than the buffer size.
+			 * Try to get the remaining amount.
+			 * But don't get more than the buffer size.
+			 * And don't try to go past the end of the file.
+			 * If we're not at a page boundary,
+			 *	don't go past the next page.
+			 * If this means getting 0, then we were asked
+			 *	to write past the end of file.
+			 * Finally, round down to a block boundary.
 			 */
 			amount = min(amount_left_to_req, FSG_BUFLEN);
+			amount = min((loff_t)amount,
+				     curlun->file_length - usb_offset);
+			partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+			if (partial_page > 0)
+				amount = min(amount,
+	(unsigned int)PAGE_CACHE_SIZE - partial_page);
 
-			/* Beyond the end of the backing file? */
-			if (usb_offset >= curlun->file_length) {
+			if (amount == 0) {
 				get_some_more = 0;
 				curlun->sense_data =
 					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-				curlun->sense_data_info =
-					usb_offset >> curlun->blkbits;
+				curlun->sense_data_info = usb_offset >> 9;
 				curlun->info_valid = 1;
 				continue;
 			}
+			amount -= amount & 511;
+			if (amount == 0) {
+
+				/*
+				 * Why were we were asked to transfer a
+				 * partial block?
+				 */
+				get_some_more = 0;
+				continue;
+			}
 
 			/* Get the next buffer */
 			usb_offset += amount;
@@ -977,11 +1000,12 @@
 				get_some_more = 0;
 
 			/*
-			 * Except at the end of the transfer, amount will be
-			 * equal to the buffer size, which is divisible by
-			 * the bulk-out maxpacket size.
+			 * amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size
 			 */
-			set_bulk_out_req_length(common, bh, amount);
+			bh->outreq->length = amount;
+			bh->bulk_out_intended_length = amount;
+			bh->outreq->short_not_ok = 1;
 			if (!start_out_transfer(common, bh))
 				/* Dunno what to do if common->fsg is NULL */
 				return -EIO;
@@ -1011,8 +1035,7 @@
 			/* Did something go wrong with the transfer? */
 			if (bh->outreq->status != 0) {
 				curlun->sense_data = SS_COMMUNICATION_FAILURE;
-				curlun->sense_data_info =
-					file_offset >> curlun->blkbits;
+				curlun->sense_data_info = file_offset >> 9;
 				curlun->info_valid = 1;
 				break;
 			}
@@ -1026,16 +1049,6 @@
 				amount = curlun->file_length - file_offset;
 			}
 
-			/* Don't accept excess data.  The spec doesn't say
-			 * what to do in this case.  We'll ignore the error.
-			 */
-			amount = min(amount, bh->bulk_out_intended_length);
-
-			/* Don't write a partial block */
-			amount = round_down(amount, curlun->blksize);
-			if (amount == 0)
-				goto empty_write;
-
 			/* Perform the write */
 			file_offset_tmp = file_offset;
 #ifdef CONFIG_USB_MSC_PROFILING
@@ -1062,7 +1075,8 @@
 			} else if (nwritten < amount) {
 				LDBG(curlun, "partial file write: %d/%u\n",
 				     (int)nwritten, amount);
-				nwritten = round_down(nwritten, curlun->blksize);
+				nwritten -= (nwritten & 511);
+				/* Round down to a block */
 			}
 			file_offset += nwritten;
 			amount_left_to_write -= nwritten;
@@ -1071,8 +1085,7 @@
 			/* If an error occurred, report it and its position */
 			if (nwritten < amount) {
 				curlun->sense_data = SS_WRITE_ERROR;
-				curlun->sense_data_info =
-					file_offset >> curlun->blkbits;
+				curlun->sense_data_info = file_offset >> 9;
 				curlun->info_valid = 1;
 #ifdef CONFIG_USB_CSW_HACK
 				write_error_after_csw_sent = 1;
@@ -1104,10 +1117,8 @@
 				}
 			}
 #endif
-
- empty_write:
 			/* Did the host decide to stop early? */
-			if (bh->outreq->actual < bh->bulk_out_intended_length) {
+			if (bh->outreq->actual != bh->outreq->length) {
 				common->short_packet_received = 1;
 				break;
 			}
@@ -1187,8 +1198,8 @@
 		return -EIO;		/* No default reply */
 
 	/* Prepare to carry out the file verify */
-	amount_left = verification_length << curlun->blkbits;
-	file_offset = ((loff_t) lba) << curlun->blkbits;
+	amount_left = verification_length << 9;
+	file_offset = ((loff_t) lba) << 9;
 
 	/* Write out all the dirty buffers before invalidating them */
 	fsg_lun_fsync_sub(curlun);
@@ -1206,6 +1217,8 @@
 		 * Try to read the remaining amount, but not more than
 		 * the buffer size.
 		 * And don't try to read past the end of the file.
+		 * If this means reading 0 then we were asked to read
+		 * past the end of file.
 		 */
 		amount = min(amount_left, FSG_BUFLEN);
 		amount = min((loff_t)amount,
@@ -1213,8 +1226,7 @@
 		if (amount == 0) {
 			curlun->sense_data =
 					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-			curlun->sense_data_info =
-				file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			break;
 		}
@@ -1236,12 +1248,11 @@
 		} else if (nread < amount) {
 			LDBG(curlun, "partial file verify: %d/%u\n",
 			     (int)nread, amount);
-			nread = round_down(nread, curlun->blksize);
+			nread -= nread & 511;	/* Round down to a sector */
 		}
 		if (nread == 0) {
 			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
-			curlun->sense_data_info =
-				file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			break;
 		}
@@ -1347,7 +1358,7 @@
 
 	put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
 						/* Max logical block */
-	put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
+	put_unaligned_be32(512, &buf[4]);	/* Block length */
 	return 8;
 }
 
@@ -1584,7 +1595,7 @@
 
 	put_unaligned_be32(curlun->num_sectors, &buf[0]);
 						/* Number of blocks */
-	put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
+	put_unaligned_be32(512, &buf[4]);	/* Block length */
 	buf[4] = 0x02;				/* Current capacity */
 	return 12;
 }
@@ -1664,7 +1675,7 @@
 			common->next_buffhd_to_drain = bh->next;
 
 			/* A short packet or an error ends everything */
-			if (bh->outreq->actual < bh->bulk_out_intended_length ||
+			if (bh->outreq->actual != bh->outreq->length ||
 			    bh->outreq->status != 0) {
 				raise_exception(common,
 						FSG_STATE_ABORT_BULK_OUT);
@@ -1680,11 +1691,12 @@
 			amount = min(common->usb_amount_left, FSG_BUFLEN);
 
 			/*
-			 * Except at the end of the transfer, amount will be
-			 * equal to the buffer size, which is divisible by
+			 * amount is always divisible by 512, hence by
 			 * the bulk-out maxpacket size.
 			 */
-			set_bulk_out_req_length(common, bh, amount);
+			bh->outreq->length = amount;
+			bh->bulk_out_intended_length = amount;
+			bh->outreq->short_not_ok = 1;
 			if (!start_out_transfer(common, bh))
 				/* Dunno what to do if common->fsg is NULL */
 				return -EIO;
@@ -2091,8 +2103,7 @@
 
 	case READ_6:
 		i = common->cmnd[4];
-		common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
-				common->curlun->blkbits;
+		common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
 		reply = check_command(common, 6, DATA_DIR_TO_HOST,
 				      (7<<1) | (1<<4), 1,
 				      "READ(6)");
@@ -2102,8 +2113,7 @@
 
 	case READ_10:
 		common->data_size_from_cmnd =
-				get_unaligned_be16(&common->cmnd[7]) <<
-						common->curlun->blkbits;
+				get_unaligned_be16(&common->cmnd[7]) << 9;
 		reply = check_command(common, 10, DATA_DIR_TO_HOST,
 				      (1<<1) | (0xf<<2) | (3<<7), 1,
 				      "READ(10)");
@@ -2113,8 +2123,7 @@
 
 	case READ_12:
 		common->data_size_from_cmnd =
-				get_unaligned_be32(&common->cmnd[6]) <<
-						common->curlun->blkbits;
+				get_unaligned_be32(&common->cmnd[6]) << 9;
 		reply = check_command(common, 12, DATA_DIR_TO_HOST,
 				      (1<<1) | (0xf<<2) | (0xf<<6), 1,
 				      "READ(12)");
@@ -2214,8 +2223,7 @@
 
 	case WRITE_6:
 		i = common->cmnd[4];
-		common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
-					common->curlun->blkbits;
+		common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
 		reply = check_command(common, 6, DATA_DIR_FROM_HOST,
 				      (7<<1) | (1<<4), 1,
 				      "WRITE(6)");
@@ -2225,8 +2233,7 @@
 
 	case WRITE_10:
 		common->data_size_from_cmnd =
-				get_unaligned_be16(&common->cmnd[7]) <<
-						common->curlun->blkbits;
+				get_unaligned_be16(&common->cmnd[7]) << 9;
 		reply = check_command(common, 10, DATA_DIR_FROM_HOST,
 				      (1<<1) | (0xf<<2) | (3<<7), 1,
 				      "WRITE(10)");
@@ -2236,8 +2243,7 @@
 
 	case WRITE_12:
 		common->data_size_from_cmnd =
-				get_unaligned_be32(&common->cmnd[6]) <<
-						common->curlun->blkbits;
+				get_unaligned_be32(&common->cmnd[6]) << 9;
 		reply = check_command(common, 12, DATA_DIR_FROM_HOST,
 				      (1<<1) | (0xf<<2) | (0xf<<6), 1,
 				      "WRITE(12)");
@@ -2372,6 +2378,7 @@
 
 	/* Queue a request to read a Bulk-only CBW */
 	set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN);
+	bh->outreq->short_not_ok = 1;
 	if (!start_out_transfer(common, bh))
 		/* Don't know what to do if common->fsg is NULL */
 		return -EIO;
@@ -2398,6 +2405,18 @@
 
 /*-------------------------------------------------------------------------*/
 
+static int enable_endpoint(struct fsg_common *common, struct usb_ep *ep,
+		const struct usb_endpoint_descriptor *d)
+{
+	int	rc;
+
+	ep->driver_data = common;
+	rc = usb_ep_enable(ep, d);
+	if (rc)
+		ERROR(common, "can't enable %s, result %d\n", ep->name, rc);
+	return rc;
+}
+
 static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
 		struct usb_request **preq)
 {
@@ -2447,6 +2466,7 @@
 	common->fsg = new_fsg;
 	fsg = common->fsg;
 
+
 	/* Allocate the requests */
 	for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
 		struct fsg_buffhd	*bh = &common->buffhds[i];
@@ -2476,37 +2496,31 @@
 {
 	struct fsg_dev *fsg = fsg_from_func(f);
 	struct fsg_common *common = fsg->common;
+	const struct usb_endpoint_descriptor *d;
 	int rc;
 
 	/* Enable the endpoints */
-	rc = config_ep_by_speed(common->gadget, &(fsg->function), fsg->bulk_in);
+	d = fsg_ep_desc(common->gadget,
+			&fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
+	rc = enable_endpoint(common, fsg->bulk_in, d);
 	if (rc)
 		return rc;
-	rc = usb_ep_enable(fsg->bulk_in);
-	if (rc)
-		return rc;
-	fsg->bulk_in->driver_data = common;
 	fsg->bulk_in_enabled = 1;
 
-	rc = config_ep_by_speed(common->gadget, &(fsg->function),
-				fsg->bulk_out);
-	if (rc)
-		goto reset_bulk_int;
-	rc = usb_ep_enable(fsg->bulk_out);
-	if (rc)
-		goto reset_bulk_int;
-	fsg->bulk_out->driver_data = common;
+	d = fsg_ep_desc(common->gadget,
+			&fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
+	rc = enable_endpoint(common, fsg->bulk_out, d);
+	if (rc) {
+		usb_ep_disable(fsg->bulk_in);
+		fsg->bulk_in_enabled = 0;
+		return rc;
+	}
 	fsg->bulk_out_enabled = 1;
-	common->bulk_out_maxpacket = le16_to_cpu(fsg->bulk_in->desc->wMaxPacketSize);
+	common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
 	clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
 	fsg->common->new_fsg = fsg;
 	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
 	return USB_GADGET_DELAYED_STATUS;
-
-reset_bulk_int:
-	usb_ep_disable(fsg->bulk_in);
-	fsg->bulk_in_enabled = 0;
-	return rc;
 }
 
 static void fsg_disable(struct usb_function *f)
@@ -3073,7 +3087,6 @@
 	fsg_common_put(common);
 	usb_free_descriptors(fsg->function.descriptors);
 	usb_free_descriptors(fsg->function.hs_descriptors);
-	usb_free_descriptors(fsg->function.ss_descriptors);
 	kfree(fsg);
 }
 
@@ -3124,28 +3137,6 @@
 		}
 	}
 
-	if (gadget_is_superspeed(gadget)) {
-		unsigned	max_burst;
-
-		/* Calculate bMaxBurst, we know packet size is 1024 */
-		max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
-
-		fsg_ss_bulk_in_desc.bEndpointAddress =
-			fsg_fs_bulk_in_desc.bEndpointAddress;
-		fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
-
-		fsg_ss_bulk_out_desc.bEndpointAddress =
-			fsg_fs_bulk_out_desc.bEndpointAddress;
-		fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
-
-		f->ss_descriptors = usb_copy_descriptors(fsg_ss_function);
-		if (unlikely(!f->ss_descriptors)) {
-			usb_free_descriptors(f->hs_descriptors);
-			usb_free_descriptors(f->descriptors);
-			return -ENOMEM;
-		}
-	}
-
 	return 0;
 
 autoconf_fail:
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 447e815..2829231 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -1132,38 +1132,21 @@
 	int ret;
 
 	DBG(cdev, "mtp_function_set_alt intf: %d alt: %d\n", intf, alt);
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
-	if (ret) {
-		dev->ep_in->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->ep_in->name, ret);
+	ret = usb_ep_enable(dev->ep_in,
+			ep_choose(cdev->gadget,
+				&mtp_highspeed_in_desc,
+				&mtp_fullspeed_in_desc));
+	if (ret)
 		return ret;
-	}
-	ret = usb_ep_enable(dev->ep_in);
+	ret = usb_ep_enable(dev->ep_out,
+			ep_choose(cdev->gadget,
+				&mtp_highspeed_out_desc,
+				&mtp_fullspeed_out_desc));
 	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-			dev->ep_in->name, ret);
-		return ret;
-	}
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
-	if (ret) {
-		dev->ep_out->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->ep_out->name, ret);
 		usb_ep_disable(dev->ep_in);
 		return ret;
 	}
-	ret = usb_ep_enable(dev->ep_out);
-	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-			dev->ep_out->name, ret);
-		usb_ep_disable(dev->ep_in);
-		return ret;
-	}
-	dev->ep_intr->desc = &mtp_intr_desc;
-	ret = usb_ep_enable(dev->ep_intr);
+	ret = usb_ep_enable(dev->ep_intr, &mtp_intr_desc);
 	if (ret) {
 		usb_ep_disable(dev->ep_out);
 		usb_ep_disable(dev->ep_in);
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index ae69ed7..86902a6 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -48,6 +48,12 @@
 #define NCM_NDP_HDR_CRC		0x01000000
 #define NCM_NDP_HDR_NOCRC	0x00000000
 
+struct ncm_ep_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+	struct usb_endpoint_descriptor	*notify;
+};
+
 enum ncm_notify_state {
 	NCM_NOTIFY_NONE,		/* don't notify */
 	NCM_NOTIFY_CONNECT,		/* issue CONNECT next */
@@ -60,7 +66,11 @@
 
 	char				ethaddr[14];
 
+	struct ncm_ep_descs		fs;
+	struct ncm_ep_descs		hs;
+
 	struct usb_ep			*notify;
+	struct usb_endpoint_descriptor	*notify_desc;
 	struct usb_request		*notify_req;
 	u8				notify_state;
 	bool				is_open;
@@ -792,14 +802,13 @@
 		if (ncm->notify->driver_data) {
 			DBG(cdev, "reset ncm control %d\n", intf);
 			usb_ep_disable(ncm->notify);
-		}
-
-		if (!(ncm->notify->desc)) {
+		} else {
 			DBG(cdev, "init ncm ctrl %d\n", intf);
-			if (config_ep_by_speed(cdev->gadget, f, ncm->notify))
-				goto fail;
+			ncm->notify_desc = ep_choose(cdev->gadget,
+					ncm->hs.notify,
+					ncm->fs.notify);
 		}
-		usb_ep_enable(ncm->notify);
+		usb_ep_enable(ncm->notify, ncm->notify_desc);
 		ncm->notify->driver_data = ncm;
 
 	/* Data interface has two altsettings, 0 and 1 */
@@ -820,17 +829,14 @@
 		if (alt == 1) {
 			struct net_device	*net;
 
-			if (!ncm->port.in_ep->desc ||
-			    !ncm->port.out_ep->desc) {
+			if (!ncm->port.in) {
 				DBG(cdev, "init ncm\n");
-				if (config_ep_by_speed(cdev->gadget, f,
-						       ncm->port.in_ep) ||
-				    config_ep_by_speed(cdev->gadget, f,
-						       ncm->port.out_ep)) {
-					ncm->port.in_ep->desc = NULL;
-					ncm->port.out_ep->desc = NULL;
-					goto fail;
-				}
+				ncm->port.in = ep_choose(cdev->gadget,
+							 ncm->hs.in,
+							 ncm->fs.in);
+				ncm->port.out = ep_choose(cdev->gadget,
+							  ncm->hs.out,
+							  ncm->fs.out);
 			}
 
 			/* TODO */
@@ -1105,7 +1111,7 @@
 	if (ncm->notify->driver_data) {
 		usb_ep_disable(ncm->notify);
 		ncm->notify->driver_data = NULL;
-		ncm->notify->desc = NULL;
+		ncm->notify_desc = NULL;
 	}
 }
 
@@ -1222,6 +1228,13 @@
 	if (!f->descriptors)
 		goto fail;
 
+	ncm->fs.in = usb_find_endpoint(ncm_fs_function,
+			f->descriptors, &fs_ncm_in_desc);
+	ncm->fs.out = usb_find_endpoint(ncm_fs_function,
+			f->descriptors, &fs_ncm_out_desc);
+	ncm->fs.notify = usb_find_endpoint(ncm_fs_function,
+			f->descriptors, &fs_ncm_notify_desc);
+
 	/*
 	 * support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -1239,6 +1252,13 @@
 		f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
 		if (!f->hs_descriptors)
 			goto fail;
+
+		ncm->hs.in = usb_find_endpoint(ncm_hs_function,
+				f->hs_descriptors, &hs_ncm_in_desc);
+		ncm->hs.out = usb_find_endpoint(ncm_hs_function,
+				f->hs_descriptors, &hs_ncm_out_desc);
+		ncm->hs.notify = usb_find_endpoint(ncm_hs_function,
+				f->hs_descriptors, &hs_ncm_notify_desc);
 	}
 
 	/*
@@ -1268,9 +1288,9 @@
 	/* we might as well release our claims on endpoints */
 	if (ncm->notify)
 		ncm->notify->driver_data = NULL;
-	if (ncm->port.out_ep->desc)
+	if (ncm->port.out)
 		ncm->port.out_ep->driver_data = NULL;
-	if (ncm->port.in_ep->desc)
+	if (ncm->port.in)
 		ncm->port.in_ep->driver_data = NULL;
 
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 394502a..8f8c643 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -39,12 +39,20 @@
  * ready to handle the commands.
  */
 
+struct obex_ep_descs {
+	struct usb_endpoint_descriptor	*obex_in;
+	struct usb_endpoint_descriptor	*obex_out;
+};
+
 struct f_obex {
 	struct gserial			port;
 	u8				ctrl_id;
 	u8				data_id;
 	u8				port_num;
 	u8				can_activate;
+
+	struct obex_ep_descs		fs;
+	struct obex_ep_descs		hs;
 };
 
 static inline struct f_obex *func_to_obex(struct usb_function *f)
@@ -219,16 +227,12 @@
 			gserial_disconnect(&obex->port);
 		}
 
-		if (!obex->port.in->desc || !obex->port.out->desc) {
+		if (!obex->port.in_desc) {
 			DBG(cdev, "init obex ttyGS%d\n", obex->port_num);
-			if (config_ep_by_speed(cdev->gadget, f,
-					       obex->port.in) ||
-			    config_ep_by_speed(cdev->gadget, f,
-					       obex->port.out)) {
-				obex->port.out->desc = NULL;
-				obex->port.in->desc = NULL;
-				goto fail;
-			}
+			obex->port.in_desc = ep_choose(cdev->gadget,
+					obex->hs.obex_in, obex->fs.obex_in);
+			obex->port.out_desc = ep_choose(cdev->gadget,
+					obex->hs.obex_out, obex->fs.obex_out);
 		}
 
 		if (alt == 1) {
@@ -342,6 +346,11 @@
 	/* copy descriptors, and track endpoint copies */
 	f->descriptors = usb_copy_descriptors(fs_function);
 
+	obex->fs.obex_in = usb_find_endpoint(fs_function,
+			f->descriptors, &obex_fs_ep_in_desc);
+	obex->fs.obex_out = usb_find_endpoint(fs_function,
+			f->descriptors, &obex_fs_ep_out_desc);
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -355,6 +364,11 @@
 
 		/* copy descriptors, and track endpoint copies */
 		f->hs_descriptors = usb_copy_descriptors(hs_function);
+
+		obex->hs.obex_in = usb_find_endpoint(hs_function,
+				f->hs_descriptors, &obex_hs_ep_in_desc);
+		obex->hs.obex_out = usb_find_endpoint(hs_function,
+				f->hs_descriptors, &obex_hs_ep_out_desc);
 	}
 
 	/* Avoid letting this gadget enumerate until the userspace
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index 0d6d260..5e14950 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -427,16 +427,17 @@
 		spin_lock(&port->lock);
 		__pn_reset(f);
 		if (alt == 1) {
+			struct usb_endpoint_descriptor *out, *in;
 			int i;
 
-			if (config_ep_by_speed(gadget, f, fp->in_ep) ||
-			    config_ep_by_speed(gadget, f, fp->out_ep)) {
-				fp->in_ep->desc = NULL;
-				fp->out_ep->desc = NULL;
-				return -EINVAL;
-			}
-			usb_ep_enable(fp->out_ep);
-			usb_ep_enable(fp->in_ep);
+			out = ep_choose(gadget,
+					&pn_hs_sink_desc,
+					&pn_fs_sink_desc);
+			in = ep_choose(gadget,
+					&pn_hs_source_desc,
+					&pn_fs_source_desc);
+			usb_ep_enable(fp->out_ep, out);
+			usb_ep_enable(fp->in_ep, in);
 
 			port->usb = fp;
 			fp->out_ep->driver_data = fp;
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index cc26c85..d846c4e 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -25,6 +25,11 @@
 #define RMNET_NOTIFY_INTERVAL	5
 #define RMNET_MAX_NOTIFY_SIZE	sizeof(struct usb_cdc_notification)
 
+struct rmnet_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+	struct usb_endpoint_descriptor	*notify;
+};
 
 #define ACM_CTRL_DTR	(1 << 0)
 
@@ -41,8 +46,13 @@
 
 	spinlock_t			lock;
 
+	/* usb descriptors */
+	struct rmnet_descs		fs;
+	struct rmnet_descs		hs;
+
 	/* usb eps*/
 	struct usb_ep			*notify;
+	struct usb_endpoint_descriptor	*notify_desc;
 	struct usb_request		*notify_req;
 
 	/* control info */
@@ -471,16 +481,10 @@
 		pr_debug("%s: reset port:%d\n", __func__, dev->port_num);
 		usb_ep_disable(dev->notify);
 	}
-
-	ret = config_ep_by_speed(cdev->gadget, f, dev->notify);
-	if (ret) {
-		dev->notify->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-					dev->notify->name, ret);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->notify);
-
+	dev->notify_desc = ep_choose(cdev->gadget,
+				dev->hs.notify,
+				dev->fs.notify);
+	ret = usb_ep_enable(dev->notify, dev->notify_desc);
 	if (ret) {
 		pr_err("%s: usb ep#%s enable failed, err#%d\n",
 				__func__, dev->notify->name, ret);
@@ -493,12 +497,10 @@
 		gport_rmnet_disconnect(dev);
 	}
 
-	if (config_ep_by_speed(cdev->gadget, f, dev->port.in) ||
-	    config_ep_by_speed(cdev->gadget, f, dev->port.out)) {
-			dev->port.in->desc = NULL;
-			dev->port.out->desc = NULL;
-			return -EINVAL;
-	}
+	dev->port.in_desc = ep_choose(cdev->gadget,
+			dev->hs.in, dev->fs.in);
+	dev->port.out_desc = ep_choose(cdev->gadget,
+			dev->hs.out, dev->fs.out);
 
 	ret = gport_rmnet_connect(dev);
 
@@ -852,6 +854,16 @@
 	if (!f->descriptors)
 		goto fail;
 
+	dev->fs.in = usb_find_endpoint(rmnet_fs_function,
+					f->descriptors,
+					&rmnet_fs_in_desc);
+	dev->fs.out = usb_find_endpoint(rmnet_fs_function,
+					f->descriptors,
+					&rmnet_fs_out_desc);
+	dev->fs.notify = usb_find_endpoint(rmnet_fs_function,
+					f->descriptors,
+					&rmnet_fs_notify_desc);
+
 	if (gadget_is_dualspeed(cdev->gadget)) {
 		rmnet_hs_in_desc.bEndpointAddress =
 				rmnet_fs_in_desc.bEndpointAddress;
@@ -865,6 +877,13 @@
 
 		if (!f->hs_descriptors)
 			goto fail;
+
+		dev->hs.in = usb_find_endpoint(rmnet_hs_function,
+				f->hs_descriptors, &rmnet_hs_in_desc);
+		dev->hs.out = usb_find_endpoint(rmnet_hs_function,
+				f->hs_descriptors, &rmnet_hs_out_desc);
+		dev->hs.notify = usb_find_endpoint(rmnet_hs_function,
+				f->hs_descriptors, &rmnet_hs_notify_desc);
 	}
 
 	pr_info("%s: RmNet(%d) %s Speed, IN:%s OUT:%s\n",
diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c
index 8019356..f63d939 100644
--- a/drivers/usb/gadget/f_rmnet_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_sdio.c
@@ -1255,58 +1255,17 @@
 	struct usb_composite_dev *cdev = dev->cdev;
 	int ret = 0;
 
-	/* Enable epin */
 	dev->epin->driver_data = dev;
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epin);
-	if (ret) {
-		dev->epin->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->epin->name, ret);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epin);
-	if (ret) {
-		ERROR(cdev, "can't enable %s, result %d\n",
-			dev->epin->name, ret);
-		return ret;
-	}
-
-	/* Enable epout */
+	usb_ep_enable(dev->epin, ep_choose(cdev->gadget,
+				&rmnet_sdio_hs_in_desc,
+				&rmnet_sdio_fs_in_desc));
 	dev->epout->driver_data = dev;
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epout);
-	if (ret) {
-		dev->epout->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->epout->name, ret);
-		usb_ep_disable(dev->epin);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epout);
-	if (ret) {
-		ERROR(cdev, "can't enable %s, result %d\n",
-			dev->epout->name, ret);
-		usb_ep_disable(dev->epin);
-		return ret;
-	}
-
-	/* Enable epnotify */
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify);
-	if (ret) {
-		dev->epnotify->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->epnotify->name, ret);
-		usb_ep_disable(dev->epin);
-		usb_ep_disable(dev->epout);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epnotify);
-	if (ret) {
-		ERROR(cdev, "can't enable %s, result %d\n",
-			dev->epnotify->name, ret);
-		usb_ep_disable(dev->epin);
-		usb_ep_disable(dev->epout);
-		return ret;
-	}
+	usb_ep_enable(dev->epout, ep_choose(cdev->gadget,
+				&rmnet_sdio_hs_out_desc,
+				&rmnet_sdio_fs_out_desc));
+	usb_ep_enable(dev->epnotify, ep_choose(cdev->gadget,
+				&rmnet_sdio_hs_notify_desc,
+				&rmnet_sdio_fs_notify_desc));
 
 	/* allocate notification */
 	dev->notify_req = rmnet_sdio_alloc_req(dev->epnotify,
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index b71f646..2049dc0 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -956,32 +956,17 @@
 	struct usb_composite_dev *cdev = dev->cdev;
 	int ret = 0;
 
-	/* Enable epin endpoint */
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epin);
-	if (ret) {
-		dev->epin->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n",
-			dev->epin->name, ret);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epin);
+	ret = usb_ep_enable(dev->epin, ep_choose(cdev->gadget,
+				&rmnet_smd_hs_in_desc,
+				&rmnet_smd_fs_in_desc));
 	if (ret) {
 		ERROR(cdev, "can't enable %s, result %d\n",
 					dev->epin->name, ret);
 		return ret;
 	}
-
-	/* Enable epout endpoint */
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epout);
-	if (ret) {
-		dev->epout->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n",
-					dev->epout->name, ret);
-		usb_ep_disable(dev->epin);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epout);
-
+	ret = usb_ep_enable(dev->epout, ep_choose(cdev->gadget,
+				&rmnet_smd_hs_out_desc,
+				&rmnet_smd_fs_out_desc));
 	if (ret) {
 		ERROR(cdev, "can't enable %s, result %d\n",
 					dev->epout->name, ret);
@@ -989,17 +974,9 @@
 		return ret;
 	}
 
-	/* Enable epnotify endpoint */
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify);
-	if (ret) {
-		dev->epnotify->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n",
-			dev->epnotify->name, ret);
-		usb_ep_disable(dev->epin);
-		usb_ep_disable(dev->epout);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epnotify);
+	ret = usb_ep_enable(dev->epnotify, ep_choose(cdev->gadget,
+				&rmnet_smd_hs_notify_desc,
+				&rmnet_smd_fs_notify_desc));
 	if (ret) {
 		ERROR(cdev, "can't enable %s, result %d\n",
 					dev->epnotify->name, ret);
diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c
index 175afe3..e39125d 100644
--- a/drivers/usb/gadget/f_rmnet_smd_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c
@@ -1354,7 +1354,6 @@
 								function);
 	struct rmnet_mux_sdio_dev *sdio_dev = &dev->sdio_dev;
 	struct usb_composite_dev *cdev = dev->cdev;
-	int ret = 0;
 
 	/* allocate notification */
 	dev->notify_req = rmnet_mux_alloc_req(dev->epnotify,
@@ -1366,59 +1365,18 @@
 	dev->notify_req->complete = rmnet_mux_notify_complete;
 	dev->notify_req->context = dev;
 	dev->notify_req->length = RMNET_MUX_SDIO_MAX_NFY_SZE;
+	usb_ep_enable(dev->epnotify, ep_choose(cdev->gadget,
+				&rmnet_mux_hs_notify_desc,
+				&rmnet_mux_fs_notify_desc));
 
-	/* Enable epin */
 	dev->epin->driver_data = dev;
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epin);
-	if (ret) {
-			dev->epin->desc = NULL;
-			ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-				dev->epin->name, ret);
-			return ret;
-	}
-	ret = usb_ep_enable(dev->epin);
-	if (ret) {
-		ERROR(cdev, "can't enable %s, result %d\n",
-		dev->epin->name, ret);
-		return ret;
-	}
-
-	/* Enable epout */
+	usb_ep_enable(dev->epin, ep_choose(cdev->gadget,
+				&rmnet_mux_hs_in_desc,
+				&rmnet_mux_fs_in_desc));
 	dev->epout->driver_data = dev;
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epout);
-	if (ret) {
-		dev->epout->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-				dev->epout->name, ret);
-		usb_ep_disable(dev->epin);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epout);
-	if (ret) {
-		ERROR(cdev, "can't enable %s, result %d\n",
-			dev->epout->name, ret);
-		usb_ep_disable(dev->epin);
-		return ret;
-	}
-
-	/* Enable epnotify */
-	ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify);
-	if (ret) {
-		dev->epnotify->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-			dev->epnotify->name, ret);
-		usb_ep_disable(dev->epin);
-		usb_ep_disable(dev->epout);
-		return ret;
-	}
-	ret = usb_ep_enable(dev->epnotify);
-	if (ret) {
-		ERROR(cdev, "can't enable %s, result %d\n",
-			dev->epnotify->name, ret);
-		usb_ep_disable(dev->epin);
-		usb_ep_disable(dev->epout);
-		return ret;
-	}
+	usb_ep_enable(dev->epout, ep_choose(cdev->gadget,
+				&rmnet_mux_hs_out_desc,
+				&rmnet_mux_fs_out_desc));
 
 	dev->dpkts_tolaptop = 0;
 	dev->cpkts_tolaptop = 0;
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 4a74dcf..d03b11b 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -76,6 +76,12 @@
  *   - MS-Windows drivers sometimes emit undocumented requests.
  */
 
+struct rndis_ep_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+	struct usb_endpoint_descriptor	*notify;
+};
+
 struct f_rndis {
 	struct gether			port;
 	u8				ctrl_id, data_id;
@@ -84,7 +90,12 @@
 	const char			*manufacturer;
 	int				config;
 
+
+	struct rndis_ep_descs		fs;
+	struct rndis_ep_descs		hs;
+
 	struct usb_ep			*notify;
+	struct usb_endpoint_descriptor	*notify_desc;
 	struct usb_request		*notify_req;
 	atomic_t			notify_count;
 };
@@ -475,13 +486,13 @@
 		if (rndis->notify->driver_data) {
 			VDBG(cdev, "reset rndis control %d\n", intf);
 			usb_ep_disable(rndis->notify);
-		}
-		if (!rndis->notify->desc) {
+		} else {
 			VDBG(cdev, "init rndis ctrl %d\n", intf);
-			if (config_ep_by_speed(cdev->gadget, f, rndis->notify))
-				goto fail;
 		}
-		usb_ep_enable(rndis->notify);
+		rndis->notify_desc = ep_choose(cdev->gadget,
+				rndis->hs.notify,
+				rndis->fs.notify);
+		usb_ep_enable(rndis->notify, rndis->notify_desc);
 		rndis->notify->driver_data = rndis;
 
 	} else if (intf == rndis->data_id) {
@@ -492,17 +503,13 @@
 			gether_disconnect(&rndis->port);
 		}
 
-		if (!rndis->port.in_ep->desc || !rndis->port.out_ep->desc) {
+		if (!rndis->port.in) {
 			DBG(cdev, "init rndis\n");
-			if (config_ep_by_speed(cdev->gadget, f,
-					       rndis->port.in_ep) ||
-			    config_ep_by_speed(cdev->gadget, f,
-					       rndis->port.out_ep)) {
-				rndis->port.in_ep->desc = NULL;
-				rndis->port.out_ep->desc = NULL;
-				goto fail;
-			}
 		}
+		rndis->port.in = ep_choose(cdev->gadget,
+				rndis->hs.in, rndis->fs.in);
+		rndis->port.out = ep_choose(cdev->gadget,
+				rndis->hs.out, rndis->fs.out);
 
 		/* Avoid ZLPs; they can be troublesome. */
 		rndis->port.is_zlp_ok = false;
@@ -657,6 +664,13 @@
 	if (!f->descriptors)
 		goto fail;
 
+	rndis->fs.in = usb_find_endpoint(eth_fs_function,
+			f->descriptors, &fs_in_desc);
+	rndis->fs.out = usb_find_endpoint(eth_fs_function,
+			f->descriptors, &fs_out_desc);
+	rndis->fs.notify = usb_find_endpoint(eth_fs_function,
+			f->descriptors, &fs_notify_desc);
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -674,6 +688,13 @@
 
 		if (!f->hs_descriptors)
 			goto fail;
+
+		rndis->hs.in = usb_find_endpoint(eth_hs_function,
+				f->hs_descriptors, &hs_in_desc);
+		rndis->hs.out = usb_find_endpoint(eth_hs_function,
+				f->hs_descriptors, &hs_out_desc);
+		rndis->hs.notify = usb_find_endpoint(eth_hs_function,
+				f->hs_descriptors, &hs_notify_desc);
 	}
 
 	rndis->port.open = rndis_open;
@@ -716,9 +737,9 @@
 	/* we might as well release our claims on endpoints */
 	if (rndis->notify)
 		rndis->notify->driver_data = NULL;
-	if (rndis->port.out_ep->desc)
+	if (rndis->port.out)
 		rndis->port.out_ep->driver_data = NULL;
-	if (rndis->port.in_ep->desc)
+	if (rndis->port.in)
 		rndis->port.in_ep->driver_data = NULL;
 
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index ebd1580..de8c8ed 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -29,12 +29,21 @@
  */
 #define GSERIAL_NO_PORTS 2
 
+struct gser_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+#ifdef CONFIG_MODEM_SUPPORT
+	struct usb_endpoint_descriptor	*notify;
+#endif
+};
 
 struct f_gser {
 	struct gserial			port;
 	u8				data_id;
 	u8				port_num;
 
+	struct gser_descs		fs;
+	struct gser_descs		hs;
 	u8				online;
 	enum transport_type		transport;
 
@@ -42,6 +51,7 @@
 	u8				pending;
 	spinlock_t			lock;
 	struct usb_ep			*notify;
+	struct usb_endpoint_descriptor	*notify_desc;
 	struct usb_request		*notify_req;
 
 	struct usb_cdc_line_coding	port_line_coding;
@@ -468,16 +478,10 @@
 		DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
 		usb_ep_disable(gser->notify);
 	}
-
-	if (!gser->notify->desc) {
-		if (config_ep_by_speed(cdev->gadget, f, gser->notify)) {
-			gser->notify->desc = NULL;
-			return -EINVAL;
-		}
-	}
-
-	rc = usb_ep_enable(gser->notify);
-
+	gser->notify_desc = ep_choose(cdev->gadget,
+			gser->hs.notify,
+			gser->fs.notify);
+	rc = usb_ep_enable(gser->notify, gser->notify_desc);
 	if (rc) {
 		ERROR(cdev, "can't enable %s, result %d\n",
 					gser->notify->name, rc);
@@ -489,16 +493,14 @@
 	if (gser->port.in->driver_data) {
 		DBG(cdev, "reset generic data ttyGS%d\n", gser->port_num);
 		gport_disconnect(gser);
+	} else {
+		DBG(cdev, "activate generic data ttyGS%d\n", gser->port_num);
 	}
-	if (!gser->port.in->desc || !gser->port.out->desc) {
-		DBG(cdev, "activate generic ttyGS%d\n", gser->port_num);
-		if (config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
-		    config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
-			gser->port.in->desc = NULL;
-			gser->port.out->desc = NULL;
-			return -EINVAL;
-		}
-	}
+	gser->port.in_desc = ep_choose(cdev->gadget,
+			gser->hs.in, gser->fs.in);
+	gser->port.out_desc = ep_choose(cdev->gadget,
+			gser->hs.out, gser->fs.out);
+
 	gport_connect(gser);
 
 	gser->online = 1;
@@ -742,6 +744,16 @@
 	if (!f->descriptors)
 		goto fail;
 
+	gser->fs.in = usb_find_endpoint(gser_fs_function,
+			f->descriptors, &gser_fs_in_desc);
+	gser->fs.out = usb_find_endpoint(gser_fs_function,
+			f->descriptors, &gser_fs_out_desc);
+#ifdef CONFIG_MODEM_SUPPORT
+	gser->fs.notify = usb_find_endpoint(gser_fs_function,
+			f->descriptors, &gser_fs_notify_desc);
+#endif
+
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -762,6 +774,14 @@
 		if (!f->hs_descriptors)
 			goto fail;
 
+		gser->hs.in = usb_find_endpoint(gser_hs_function,
+				f->hs_descriptors, &gser_hs_in_desc);
+		gser->hs.out = usb_find_endpoint(gser_hs_function,
+				f->hs_descriptors, &gser_hs_out_desc);
+#ifdef CONFIG_MODEM_SUPPORT
+		gser->hs.notify = usb_find_endpoint(gser_hs_function,
+				f->hs_descriptors, &gser_hs_notify_desc);
+#endif
 	}
 
 	DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n",
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index caf2f95..e403a53 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -343,14 +343,15 @@
 enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
 {
 	int					result = 0;
+	const struct usb_endpoint_descriptor	*src, *sink;
 	struct usb_ep				*ep;
 
+	src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
+	sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+
 	/* one endpoint writes (sources) zeroes IN (to the host) */
 	ep = ss->in_ep;
-	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
-	if (result)
-		return result;
-	result = usb_ep_enable(ep);
+	result = usb_ep_enable(ep, src);
 	if (result < 0)
 		return result;
 	ep->driver_data = ss;
@@ -366,10 +367,7 @@
 
 	/* one endpoint reads (sinks) anything OUT (from the host) */
 	ep = ss->out_ep;
-	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
-	if (result)
-		goto fail;
-	result = usb_ep_enable(ep);
+	result = usb_ep_enable(ep, sink);
 	if (result < 0)
 		goto fail;
 	ep->driver_data = ss;
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 93bf676..8675ca4 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -57,10 +57,18 @@
  * caring about specific product and vendor IDs.
  */
 
+struct geth_descs {
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+};
+
 struct f_gether {
 	struct gether			port;
 
 	char				ethaddr[14];
+
+	struct geth_descs		fs;
+	struct geth_descs		hs;
 };
 
 static inline struct f_gether *func_to_geth(struct usb_function *f)
@@ -235,12 +243,10 @@
 	}
 
 	DBG(cdev, "init + activate cdc subset\n");
-	if (config_ep_by_speed(cdev->gadget, f, geth->port.in_ep) ||
-	    config_ep_by_speed(cdev->gadget, f, geth->port.out_ep)) {
-		geth->port.in_ep->desc = NULL;
-		geth->port.out_ep->desc = NULL;
-		return -EINVAL;
-	}
+	geth->port.in = ep_choose(cdev->gadget,
+			geth->hs.in, geth->fs.in);
+	geth->port.out = ep_choose(cdev->gadget,
+			geth->hs.out, geth->fs.out);
 
 	net = gether_connect(&geth->port);
 	return IS_ERR(net) ? PTR_ERR(net) : 0;
@@ -291,6 +297,12 @@
 	/* copy descriptors, and track endpoint copies */
 	f->descriptors = usb_copy_descriptors(fs_eth_function);
 
+	geth->fs.in = usb_find_endpoint(fs_eth_function,
+			f->descriptors, &fs_subset_in_desc);
+	geth->fs.out = usb_find_endpoint(fs_eth_function,
+			f->descriptors, &fs_subset_out_desc);
+
+
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
 	 * both speeds
@@ -303,6 +315,11 @@
 
 		/* copy descriptors, and track endpoint copies */
 		f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
+
+		geth->hs.in = usb_find_endpoint(hs_eth_function,
+				f->hs_descriptors, &hs_subset_in_desc);
+		geth->hs.out = usb_find_endpoint(hs_eth_function,
+				f->hs_descriptors, &hs_subset_out_desc);
 	}
 
 	/* NOTE:  all that is done without knowing or caring about
@@ -317,9 +334,9 @@
 
 fail:
 	/* we might as well release our claims on endpoints */
-	if (geth->port.out_ep->desc)
+	if (geth->port.out)
 		geth->port.out_ep->driver_data = NULL;
-	if (geth->port.in_ep->desc)
+	if (geth->port.in)
 		geth->port.in_ep->driver_data = NULL;
 
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index df74d03..be446b7 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -262,10 +262,8 @@
 		if (uvc->state != UVC_STATE_CONNECTED)
 			return 0;
 
-		if (uvc->video.ep) {
-			uvc->video.ep->desc = &uvc_streaming_ep;
-			usb_ep_enable(uvc->video.ep);
-		}
+		if (uvc->video.ep)
+			usb_ep_enable(uvc->video.ep, &uvc_streaming_ep);
 
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		v4l2_event.type = UVC_EVENT_STREAMON;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index b17ecd8..0360f56 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -69,7 +69,8 @@
  * each LUN would be settable independently as a disk drive or a CD-ROM
  * drive, but currently all LUNs have to be the same type.  The CD-ROM
  * emulation includes a single data track and no audio tracks; hence there
- * need be only one backing file per LUN.
+ * need be only one backing file per LUN.  Note also that the CD-ROM block
+ * length is set to 512 rather than the more common value 2048.
  *
  * Requirements are modest; only a bulk-in and a bulk-out endpoint are
  * needed (an interrupt-out endpoint is also needed for CBI).  The memory
@@ -532,18 +533,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* Maxpacket and other transfer characteristics vary by speed. */
-static struct usb_endpoint_descriptor *
-fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
-		struct usb_endpoint_descriptor *hs)
-{
-	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
-		return hs;
-	return fs;
-}
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * DESCRIPTORS ... most are static, but strings and (full) configuration
  * descriptors are built on demand.  Also the (static) config and interface
@@ -597,19 +586,7 @@
 	.bNumConfigurations =	1,
 };
 
-static int populate_bos(struct fsg_dev *fsg, u8 *buf)
-{
-	memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE);
-	buf += USB_DT_BOS_SIZE;
 
-	memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE);
-	buf += USB_DT_USB_EXT_CAP_SIZE;
-
-	memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE);
-
-	return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE
-		+ USB_DT_USB_EXT_CAP_SIZE;
-}
 
 /*
  * Config descriptors must agree with the code that sets configurations
@@ -952,28 +929,20 @@
 
 		case USB_DT_DEVICE:
 			VDBG(fsg, "get device descriptor\n");
-			device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
 			value = sizeof device_desc;
 			memcpy(req->buf, &device_desc, value);
 			break;
 		case USB_DT_DEVICE_QUALIFIER:
 			VDBG(fsg, "get device qualifier\n");
-			if (!gadget_is_dualspeed(fsg->gadget) ||
-					fsg->gadget->speed == USB_SPEED_SUPER)
+			if (!gadget_is_dualspeed(fsg->gadget))
 				break;
-			/*
-			 * Assume ep0 uses the same maxpacket value for both
-			 * speeds
-			 */
-			dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
 			value = sizeof dev_qualifier;
 			memcpy(req->buf, &dev_qualifier, value);
 			break;
 
 		case USB_DT_OTHER_SPEED_CONFIG:
 			VDBG(fsg, "get other-speed config descriptor\n");
-			if (!gadget_is_dualspeed(fsg->gadget) ||
-					fsg->gadget->speed == USB_SPEED_SUPER)
+			if (!gadget_is_dualspeed(fsg->gadget))
 				break;
 			goto get_config;
 		case USB_DT_CONFIG:
@@ -992,15 +961,7 @@
 			value = usb_gadget_get_string(&fsg_stringtab,
 					w_value & 0xff, req->buf);
 			break;
-
-		case USB_DT_BOS:
-			VDBG(fsg, "get bos descriptor\n");
-
-			if (gadget_is_superspeed(fsg->gadget))
-				value = populate_bos(fsg, req->buf);
-			break;
 		}
-
 		break;
 
 	/* One config, two speeds */
@@ -1169,6 +1130,7 @@
 	u32			amount_left;
 	loff_t			file_offset, file_offset_tmp;
 	unsigned int		amount;
+	unsigned int		partial_page;
 	ssize_t			nread;
 
 	/* Get the starting Logical Block Address and check that it's
@@ -1190,7 +1152,7 @@
 		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
 		return -EINVAL;
 	}
-	file_offset = ((loff_t) lba) << curlun->blkbits;
+	file_offset = ((loff_t) lba) << 9;
 
 	/* Carry out the file reads */
 	amount_left = fsg->data_size_from_cmnd;
@@ -1203,10 +1165,17 @@
 		 * Try to read the remaining amount.
 		 * But don't read more than the buffer size.
 		 * And don't try to read past the end of the file.
-		 */
+		 * Finally, if we're not at a page boundary, don't read past
+		 *	the next page.
+		 * If this means reading 0 then we were asked to read past
+		 *	the end of file. */
 		amount = min((unsigned int) amount_left, mod_data.buflen);
 		amount = min((loff_t) amount,
 				curlun->file_length - file_offset);
+		partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+		if (partial_page > 0)
+			amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
+					partial_page);
 
 		/* Wait for the next buffer to become available */
 		bh = fsg->next_buffhd_to_fill;
@@ -1221,7 +1190,7 @@
 		if (amount == 0) {
 			curlun->sense_data =
 					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-			curlun->sense_data_info = file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			bh->inreq->length = 0;
 			bh->state = BUF_STATE_FULL;
@@ -1246,23 +1215,18 @@
 		} else if (nread < amount) {
 			LDBG(curlun, "partial file read: %d/%u\n",
 					(int) nread, amount);
-			nread = round_down(nread, curlun->blksize);
+			nread -= (nread & 511);	// Round down to a block
 		}
 		file_offset  += nread;
 		amount_left  -= nread;
 		fsg->residue -= nread;
-
-		/* Except at the end of the transfer, nread will be
-		 * equal to the buffer size, which is divisible by the
-		 * bulk-in maxpacket size.
-		 */
 		bh->inreq->length = nread;
 		bh->state = BUF_STATE_FULL;
 
 		/* If an error occurred, report it and its position */
 		if (nread < amount) {
 			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
-			curlun->sense_data_info = file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			break;
 		}
@@ -1292,6 +1256,7 @@
 	u32			amount_left_to_req, amount_left_to_write;
 	loff_t			usb_offset, file_offset, file_offset_tmp;
 	unsigned int		amount;
+	unsigned int		partial_page;
 	ssize_t			nwritten;
 	int			rc;
 
@@ -1332,7 +1297,7 @@
 
 	/* Carry out the file writes */
 	get_some_more = 1;
-	file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
+	file_offset = usb_offset = ((loff_t) lba) << 9;
 	amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd;
 
 	while (amount_left_to_write > 0) {
@@ -1342,20 +1307,38 @@
 		if (bh->state == BUF_STATE_EMPTY && get_some_more) {
 
 			/* Figure out how much we want to get:
-			 * Try to get the remaining amount,
-			 * but not more than the buffer size.
-			 */
+			 * Try to get the remaining amount.
+			 * But don't get more than the buffer size.
+			 * And don't try to go past the end of the file.
+			 * If we're not at a page boundary,
+			 *	don't go past the next page.
+			 * If this means getting 0, then we were asked
+			 *	to write past the end of file.
+			 * Finally, round down to a block boundary. */
 			amount = min(amount_left_to_req, mod_data.buflen);
+			amount = min((loff_t) amount, curlun->file_length -
+					usb_offset);
+			partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+			if (partial_page > 0)
+				amount = min(amount,
+	(unsigned int) PAGE_CACHE_SIZE - partial_page);
 
-			/* Beyond the end of the backing file? */
-			if (usb_offset >= curlun->file_length) {
+			if (amount == 0) {
 				get_some_more = 0;
 				curlun->sense_data =
 					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-				curlun->sense_data_info = usb_offset >> curlun->blkbits;
+				curlun->sense_data_info = usb_offset >> 9;
 				curlun->info_valid = 1;
 				continue;
 			}
+			amount -= (amount & 511);
+			if (amount == 0) {
+
+				/* Why were we were asked to transfer a
+				 * partial block? */
+				get_some_more = 0;
+				continue;
+			}
 
 			/* Get the next buffer */
 			usb_offset += amount;
@@ -1364,11 +1347,11 @@
 			if (amount_left_to_req == 0)
 				get_some_more = 0;
 
-			/* Except at the end of the transfer, amount will be
-			 * equal to the buffer size, which is divisible by
-			 * the bulk-out maxpacket size.
-			 */
-			set_bulk_out_req_length(fsg, bh, amount);
+			/* amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size */
+			bh->outreq->length = bh->bulk_out_intended_length =
+					amount;
+			bh->outreq->short_not_ok = 1;
 			start_transfer(fsg, fsg->bulk_out, bh->outreq,
 					&bh->outreq_busy, &bh->state);
 			fsg->next_buffhd_to_fill = bh->next;
@@ -1387,7 +1370,7 @@
 			/* Did something go wrong with the transfer? */
 			if (bh->outreq->status != 0) {
 				curlun->sense_data = SS_COMMUNICATION_FAILURE;
-				curlun->sense_data_info = file_offset >> curlun->blkbits;
+				curlun->sense_data_info = file_offset >> 9;
 				curlun->info_valid = 1;
 				break;
 			}
@@ -1401,16 +1384,6 @@
 				amount = curlun->file_length - file_offset;
 			}
 
-			/* Don't accept excess data.  The spec doesn't say
-			 * what to do in this case.  We'll ignore the error.
-			 */
-			amount = min(amount, bh->bulk_out_intended_length);
-
-			/* Don't write a partial block */
-			amount = round_down(amount, curlun->blksize);
-			if (amount == 0)
-				goto empty_write;
-
 			/* Perform the write */
 			file_offset_tmp = file_offset;
 			nwritten = vfs_write(curlun->filp,
@@ -1429,7 +1402,8 @@
 			} else if (nwritten < amount) {
 				LDBG(curlun, "partial file write: %d/%u\n",
 						(int) nwritten, amount);
-				nwritten = round_down(nwritten, curlun->blksize);
+				nwritten -= (nwritten & 511);
+						// Round down to a block
 			}
 			file_offset += nwritten;
 			amount_left_to_write -= nwritten;
@@ -1438,14 +1412,13 @@
 			/* If an error occurred, report it and its position */
 			if (nwritten < amount) {
 				curlun->sense_data = SS_WRITE_ERROR;
-				curlun->sense_data_info = file_offset >> curlun->blkbits;
+				curlun->sense_data_info = file_offset >> 9;
 				curlun->info_valid = 1;
 				break;
 			}
 
- empty_write:
 			/* Did the host decide to stop early? */
-			if (bh->outreq->actual < bh->bulk_out_intended_length) {
+			if (bh->outreq->actual != bh->outreq->length) {
 				fsg->short_packet_received = 1;
 				break;
 			}
@@ -1521,8 +1494,8 @@
 		return -EIO;		// No default reply
 
 	/* Prepare to carry out the file verify */
-	amount_left = verification_length << curlun->blkbits;
-	file_offset = ((loff_t) lba) << curlun->blkbits;
+	amount_left = verification_length << 9;
+	file_offset = ((loff_t) lba) << 9;
 
 	/* Write out all the dirty buffers before invalidating them */
 	fsg_lun_fsync_sub(curlun);
@@ -1540,14 +1513,15 @@
 		 * Try to read the remaining amount, but not more than
 		 * the buffer size.
 		 * And don't try to read past the end of the file.
-		 */
+		 * If this means reading 0 then we were asked to read
+		 * past the end of file. */
 		amount = min((unsigned int) amount_left, mod_data.buflen);
 		amount = min((loff_t) amount,
 				curlun->file_length - file_offset);
 		if (amount == 0) {
 			curlun->sense_data =
 					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-			curlun->sense_data_info = file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			break;
 		}
@@ -1570,11 +1544,11 @@
 		} else if (nread < amount) {
 			LDBG(curlun, "partial file verify: %d/%u\n",
 					(int) nread, amount);
-			nread = round_down(nread, curlun->blksize);
+			nread -= (nread & 511);	// Round down to a sector
 		}
 		if (nread == 0) {
 			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
-			curlun->sense_data_info = file_offset >> curlun->blkbits;
+			curlun->sense_data_info = file_offset >> 9;
 			curlun->info_valid = 1;
 			break;
 		}
@@ -1688,7 +1662,7 @@
 
 	put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
 						/* Max logical block */
-	put_unaligned_be32(curlun->blksize, &buf[4]);	/* Block length */
+	put_unaligned_be32(512, &buf[4]);	/* Block length */
 	return 8;
 }
 
@@ -1910,7 +1884,7 @@
 
 	put_unaligned_be32(curlun->num_sectors, &buf[0]);
 						/* Number of blocks */
-	put_unaligned_be32(curlun->blksize, &buf[4]);	/* Block length */
+	put_unaligned_be32(512, &buf[4]);	/* Block length */
 	buf[4] = 0x02;				/* Current capacity */
 	return 12;
 }
@@ -1989,7 +1963,7 @@
 			fsg->next_buffhd_to_drain = bh->next;
 
 			/* A short packet or an error ends everything */
-			if (bh->outreq->actual < bh->bulk_out_intended_length ||
+			if (bh->outreq->actual != bh->outreq->length ||
 					bh->outreq->status != 0) {
 				raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
 				return -EINTR;
@@ -2003,11 +1977,11 @@
 			amount = min(fsg->usb_amount_left,
 					(u32) mod_data.buflen);
 
-			/* Except at the end of the transfer, amount will be
-			 * equal to the buffer size, which is divisible by
-			 * the bulk-out maxpacket size.
-			 */
-			set_bulk_out_req_length(fsg, bh, amount);
+			/* amount is always divisible by 512, hence by
+			 * the bulk-out maxpacket size */
+			bh->outreq->length = bh->bulk_out_intended_length =
+					amount;
+			bh->outreq->short_not_ok = 1;
 			start_transfer(fsg, fsg->bulk_out, bh->outreq,
 					&bh->outreq_busy, &bh->state);
 			fsg->next_buffhd_to_fill = bh->next;
@@ -2435,7 +2409,7 @@
 
 	case READ_6:
 		i = fsg->cmnd[4];
-		fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
+		fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
 		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
 				(7<<1) | (1<<4), 1,
 				"READ(6)")) == 0)
@@ -2444,7 +2418,7 @@
 
 	case READ_10:
 		fsg->data_size_from_cmnd =
-				get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
+				get_unaligned_be16(&fsg->cmnd[7]) << 9;
 		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
 				(1<<1) | (0xf<<2) | (3<<7), 1,
 				"READ(10)")) == 0)
@@ -2453,7 +2427,7 @@
 
 	case READ_12:
 		fsg->data_size_from_cmnd =
-				get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
+				get_unaligned_be32(&fsg->cmnd[6]) << 9;
 		if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
 				(1<<1) | (0xf<<2) | (0xf<<6), 1,
 				"READ(12)")) == 0)
@@ -2539,7 +2513,7 @@
 
 	case WRITE_6:
 		i = fsg->cmnd[4];
-		fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
+		fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
 		if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
 				(7<<1) | (1<<4), 1,
 				"WRITE(6)")) == 0)
@@ -2548,7 +2522,7 @@
 
 	case WRITE_10:
 		fsg->data_size_from_cmnd =
-				get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
+				get_unaligned_be16(&fsg->cmnd[7]) << 9;
 		if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
 				(1<<1) | (0xf<<2) | (3<<7), 1,
 				"WRITE(10)")) == 0)
@@ -2557,7 +2531,7 @@
 
 	case WRITE_12:
 		fsg->data_size_from_cmnd =
-				get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
+				get_unaligned_be32(&fsg->cmnd[6]) << 9;
 		if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
 				(1<<1) | (0xf<<2) | (0xf<<6), 1,
 				"WRITE(12)")) == 0)
@@ -2686,6 +2660,7 @@
 
 		/* Queue a request to read a Bulk-only CBW */
 		set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
+		bh->outreq->short_not_ok = 1;
 		start_transfer(fsg, fsg->bulk_out, bh->outreq,
 				&bh->outreq_busy, &bh->state);
 
@@ -2738,8 +2713,7 @@
 	int	rc;
 
 	ep->driver_data = fsg;
-	ep->desc = d;
-	rc = usb_ep_enable(ep);
+	rc = usb_ep_enable(ep, d);
 	if (rc)
 		ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc);
 	return rc;
@@ -2810,15 +2784,13 @@
 
 	/* Enable the endpoints */
 	d = fsg_ep_desc(fsg->gadget,
-			&fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc,
-			&fsg_ss_bulk_in_desc);
+			&fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
 	if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
 		goto reset;
 	fsg->bulk_in_enabled = 1;
 
 	d = fsg_ep_desc(fsg->gadget,
-			&fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc,
-			&fsg_ss_bulk_out_desc);
+			&fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
 	if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
 		goto reset;
 	fsg->bulk_out_enabled = 1;
@@ -2827,8 +2799,7 @@
 
 	if (transport_is_cbi()) {
 		d = fsg_ep_desc(fsg->gadget,
-				&fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc,
-				&fsg_ss_intr_in_desc);
+				&fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc);
 		if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
 			goto reset;
 		fsg->intr_in_enabled = 1;
@@ -3445,6 +3416,7 @@
 	}
 
 	/* Fix up the descriptors */
+	device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
 	device_desc.idVendor = cpu_to_le16(mod_data.vendor);
 	device_desc.idProduct = cpu_to_le16(mod_data.product);
 	device_desc.bcdDevice = cpu_to_le16(mod_data.release);
@@ -3458,6 +3430,9 @@
 	if (gadget_is_dualspeed(gadget)) {
 		fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
 
+		/* Assume ep0 uses the same maxpacket value for both speeds */
+		dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
+
 		/* Assume endpoint addresses are the same for both speeds */
 		fsg_hs_bulk_in_desc.bEndpointAddress =
 			fsg_fs_bulk_in_desc.bEndpointAddress;
@@ -3467,24 +3442,6 @@
 			fsg_fs_intr_in_desc.bEndpointAddress;
 	}
 
-	if (gadget_is_superspeed(gadget)) {
-		unsigned		max_burst;
-
-		fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-
-		/* Calculate bMaxBurst, we know packet size is 1024 */
-		max_burst = min_t(unsigned, mod_data.buflen / 1024, 15);
-
-		/* Assume endpoint addresses are the same for both speeds */
-		fsg_ss_bulk_in_desc.bEndpointAddress =
-			fsg_fs_bulk_in_desc.bEndpointAddress;
-		fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
-
-		fsg_ss_bulk_out_desc.bEndpointAddress =
-			fsg_fs_bulk_out_desc.bEndpointAddress;
-		fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
-	}
-
 	if (gadget_is_otg(gadget))
 		fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
 
@@ -3599,7 +3556,11 @@
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver		fsg_driver = {
-	.speed		= USB_SPEED_SUPER,
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+	.speed		= USB_SPEED_HIGH,
+#else
+	.speed		= USB_SPEED_FULL,
+#endif
 	.function	= (char *) fsg_string_product,
 	.unbind		= fsg_unbind,
 	.disconnect	= fsg_disconnect,
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index 3bf872e..3a68e09 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -1927,10 +1927,6 @@
 	return -ENOTSUPP;
 }
 
-static int fsl_qe_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int fsl_qe_stop(struct usb_gadget_driver *driver);
-
 /* defined in usb_gadget.h */
 static struct usb_gadget_ops qe_gadget_ops = {
 	.get_frame = qe_get_frame,
@@ -1939,8 +1935,6 @@
 	.vbus_session = qe_vbus_session,
 	.vbus_draw = qe_vbus_draw,
 	.pullup = qe_pullup,
-	.start = fsl_qe_start,
-	.stop = fsl_qe_stop,
 };
 
 /*-------------------------------------------------------------------------
@@ -2326,7 +2320,7 @@
 /*-------------------------------------------------------------------------
 	Gadget driver probe and unregister.
  --------------------------------------------------------------------------*/
-static int fsl_qe_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	int retval;
@@ -2375,8 +2369,9 @@
 		udc_controller->gadget.name, driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int fsl_qe_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct qe_ep *loop_ep;
 	unsigned long flags;
@@ -2416,6 +2411,7 @@
 			driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /* udc structure's alloc and setup, include ep-param alloc */
 static struct qe_udc __devinit *qe_udc_config(struct platform_device *ofdev)
@@ -2666,17 +2662,11 @@
 	if (ret)
 		goto err6;
 
-	ret = usb_add_gadget_udc(&ofdev->dev, &udc_controller->gadget);
-	if (ret)
-		goto err7;
-
 	dev_info(udc_controller->dev,
 			"%s USB controller initialized as device\n",
 			(udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
 	return 0;
 
-err7:
-	device_unregister(&udc_controller->gadget.dev);
 err6:
 	free_irq(udc_controller->usb_irq, udc_controller);
 err5:
@@ -2731,8 +2721,6 @@
 	if (!udc_controller)
 		return -ENODEV;
 
-	usb_del_gadget_udc(&udc_controller->gadget);
-
 	udc_controller->done = &done;
 	tasklet_disable(&udc_controller->rx_tasklet);
 
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 4763cc3..4e48331 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1244,9 +1244,6 @@
 	return 0;
 }
 
-static int fsl_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int fsl_stop(struct usb_gadget_driver *driver);
 /* defined in gadget.h */
 static struct usb_gadget_ops fsl_gadget_ops = {
 	.get_frame = fsl_get_frame,
@@ -1255,8 +1252,6 @@
 	.vbus_session = fsl_vbus_session,
 	.vbus_draw = fsl_vbus_draw,
 	.pullup = fsl_pullup,
-	.start = fsl_start,
-	.stop = fsl_stop,
 };
 
 /* Set protocol stall on ep0, protocol stall will automatically be cleared
@@ -1932,7 +1927,7 @@
  * Hook to gadget drivers
  * Called by initialization code of gadget drivers
 *----------------------------------------------------------------*/
-static int fsl_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	int retval = -ENODEV;
@@ -2000,9 +1995,10 @@
 		       retval);
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /* Disconnect from gadget driver */
-static int fsl_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct fsl_ep *loop_ep;
 	unsigned long flags;
@@ -2045,6 +2041,7 @@
 	       driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------
 		PROC File System Support
@@ -2593,16 +2590,9 @@
 		ret = -ENOMEM;
 		goto err_unregister;
 	}
-
-	ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget);
-	if (ret)
-		goto err_del_udc;
-
 	create_proc_file();
 	return 0;
 
-err_del_udc:
-	dma_pool_destroy(udc_controller->td_pool);
 err_unregister:
 	device_unregister(&udc_controller->gadget.dev);
 err_free_irq:
@@ -2634,8 +2624,6 @@
 
 	if (!udc_controller)
 		return -ENODEV;
-
-	usb_del_gadget_udc(&udc_controller->gadget);
 	udc_controller->done = &done;
 
 	fsl_udc_clk_release();
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c
index 9cf53c6..763d462 100644
--- a/drivers/usb/gadget/fusb300_udc.c
+++ b/drivers/usb/gadget/fusb300_udc.c
@@ -1500,7 +1500,7 @@
 /*------------------------------------------------------------------------*/
 static struct fusb300 *the_controller;
 
-static int fusb300_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct fusb300 *fusb300 = the_controller;
@@ -1544,8 +1544,9 @@
 
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int fusb300_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct fusb300 *fusb300 = the_controller;
 
@@ -1561,6 +1562,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 /*--------------------------------------------------------------------------*/
 
 static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active)
@@ -1570,15 +1572,12 @@
 
 static struct usb_gadget_ops fusb300_gadget_ops = {
 	.pullup		= fusb300_udc_pullup,
-	.start		= fusb300_udc_start,
-	.stop		= fusb300_udc_stop,
 };
 
 static int __exit fusb300_remove(struct platform_device *pdev)
 {
 	struct fusb300 *fusb300 = dev_get_drvdata(&pdev->dev);
 
-	usb_del_gadget_udc(&fusb300->gadget);
 	iounmap(fusb300->reg);
 	free_irq(platform_get_irq(pdev, 0), fusb300);
 
@@ -1703,15 +1702,9 @@
 		goto clean_up3;
 
 	init_controller(fusb300);
-	ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget);
-	if (ret)
-		goto err_add_udc;
-
 	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
 
 	return 0;
-err_add_udc:
-	fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req);
 
 clean_up3:
 	free_irq(ires->start, fusb300);
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 704c280..ebf6970 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -162,7 +162,6 @@
 	.name		= DRIVER_NAME,
 	.dev		= &gfs_dev_desc,
 	.strings	= gfs_dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= gfs_unbind,
 	.iProduct	= DRIVER_DESC,
 };
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 7a9d57d..da312d4 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -120,12 +120,6 @@
 #define gadget_is_ci13xxx_pci(g)	0
 #endif
 
-#ifdef CONFIG_USB_GADGET_DWC3
-#define gadget_is_dwc3(g)		(!strcmp("dwc3-gadget", (g)->name))
-#else
-#define gadget_is_dwc3(g)	0
-#endif
-
 #ifdef CONFIG_USB_GADGET_MSM_72K
 #define	gadget_is_msm72k(g)	!strcmp("msm72k_udc", (g)->name)
 #else
@@ -246,8 +240,6 @@
 		return 0x31;
 	else if (gadget_is_ci13xxx_msm_hsic(gadget))
 		return 0x32;
-	else if (gadget_is_dwc3(gadget))
-		return 0x33;
 
 	return -ENOENT;
 }
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 8b9220e..47b86b9 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -537,16 +537,14 @@
 	struct usb_ep *ep;
 	unsigned i;
 
-	dev->in_ep->desc = &bulk_in_desc;
-	err = usb_ep_enable(dev->in_ep);
+	err = usb_ep_enable(dev->in_ep, &bulk_in_desc);
 	if (err) {
 		ERROR(dev, "can't start %s: %d\n", dev->in_ep->name, err);
 		goto fail;
 	}
 	dev->in_ep->driver_data = dev;
 
-	dev->out_ep->desc = &bulk_out_desc;
-	err = usb_ep_enable(dev->out_ep);
+	err = usb_ep_enable(dev->out_ep, &bulk_out_desc);
 	if (err) {
 		ERROR(dev, "can't start %s: %d\n", dev->out_ep->name, err);
 		goto fail;
@@ -695,7 +693,6 @@
 		switch (w_value >> 8) {
 
 		case USB_DT_DEVICE:
-			device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 			value = min(w_length, (u16) sizeof(device_desc));
 			memcpy(req->buf, &device_desc, value);
 			break;
@@ -1250,6 +1247,8 @@
 
 	dev->req->complete = gmidi_setup_complete;
 
+	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+
 	gadget->ep0->driver_data = dev;
 
 	INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 7f87805..bf6e11c 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -996,14 +996,8 @@
 	return -EOPNOTSUPP;
 }
 
-static int goku_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int goku_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops goku_ops = {
 	.get_frame	= goku_get_frame,
-	.start		= goku_start,
-	.stop		= goku_stop,
 	// no remote wakeup
 	// not selfpowered
 };
@@ -1350,7 +1344,7 @@
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-static int goku_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct goku_udc	*dev = the_controller;
@@ -1388,6 +1382,7 @@
 	DBG(dev, "registered gadget driver '%s'\n", driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
@@ -1413,7 +1408,7 @@
 		udc_enable(dev);
 }
 
-static int goku_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct goku_udc	*dev = the_controller;
 	unsigned long	flags;
@@ -1434,6 +1429,8 @@
 	DBG(dev, "unregistered driver '%s'\n", driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -1733,8 +1730,6 @@
 
 	DBG(dev, "%s\n", __func__);
 
-	usb_del_gadget_udc(&dev->gadget);
-
 	BUG_ON(dev->driver);
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
@@ -1859,10 +1854,6 @@
 		goto err;
 	}
 	dev->registered = 1;
-	retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
-	if (retval)
-		goto err;
-
 	return 0;
 
 err:
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 9fb5750..2523e54 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -255,7 +255,6 @@
 	.name		= "g_hid",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(hid_unbind),
 };
 
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index 692fd9b..ade4006 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1237,14 +1237,9 @@
  *******************************************************************************
  */
 
-static int imx_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int imx_udc_stop(struct usb_gadget_driver *driver);
 static const struct usb_gadget_ops imx_udc_ops = {
 	.get_frame	 = imx_udc_get_frame,
 	.wakeup		 = imx_udc_wakeup,
-	.start		= imx_udc_start,
-	.stop		= imx_udc_stop,
 };
 
 static struct imx_udc_struct controller = {
@@ -1329,7 +1324,7 @@
  * USB gadget driver functions
  *******************************************************************************
  */
-static int imx_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct imx_udc_struct *imx_usb = &controller;
@@ -1373,8 +1368,9 @@
 	imx_usb->gadget.dev.driver = NULL;
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int imx_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct imx_udc_struct *imx_usb = &controller;
 
@@ -1398,6 +1394,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*******************************************************************************
  * Module functions
@@ -1507,14 +1504,8 @@
 	imx_usb->timer.function = handle_config;
 	imx_usb->timer.data = (unsigned long)imx_usb;
 
-	ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget);
-	if (ret)
-		goto fail4;
-
 	return 0;
-fail4:
-	for (i = 0; i < IMX_USB_NB_EP + 1; i++)
-		free_irq(imx_usb->usbd_int[i], imx_usb);
+
 fail3:
 	clk_put(clk);
 	clk_disable(clk);
@@ -1534,7 +1525,6 @@
 	struct imxusb_platform_data *pdata = pdev->dev.platform_data;
 	int i;
 
-	usb_del_gadget_udc(&imx_usb->gadget);
 	imx_udc_disable(imx_usb);
 	del_timer(&imx_usb->timer);
 
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 1b24099..a56876a 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -832,16 +832,14 @@
 	switch (data->dev->gadget->speed) {
 	case USB_SPEED_LOW:
 	case USB_SPEED_FULL:
-		ep->desc = &data->desc;
-		value = usb_ep_enable(ep);
+		value = usb_ep_enable (ep, &data->desc);
 		if (value == 0)
 			data->state = STATE_EP_ENABLED;
 		break;
 #ifdef	CONFIG_USB_GADGET_DUALSPEED
 	case USB_SPEED_HIGH:
 		/* fails if caller didn't provide that descriptor... */
-		ep->desc = &data->hs_desc;
-		value = usb_ep_enable(ep);
+		value = usb_ep_enable (ep, &data->hs_desc);
 		if (value == 0)
 			data->state = STATE_EP_ENABLED;
 		break;
@@ -1347,7 +1345,7 @@
 	qual.bDeviceProtocol = desc->bDeviceProtocol;
 
 	/* assumes ep0 uses the same value for both speeds ... */
-	qual.bMaxPacketSize0 = dev->gadget->ep0->maxpacket;
+	qual.bMaxPacketSize0 = desc->bMaxPacketSize0;
 
 	qual.bNumConfigurations = 1;
 	qual.bRESERVED = 0;
@@ -1404,6 +1402,7 @@
 		}
 
 		dev->state = STATE_DEV_CONNECTED;
+		dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
 
 		INFO (dev, "connected\n");
 		event = next_event (dev, GADGETFS_CONNECT);
@@ -1431,7 +1430,6 @@
 
 		case USB_DT_DEVICE:
 			value = min (w_length, (u16) sizeof *dev->dev);
-			dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket;
 			req->buf = dev->dev;
 			break;
 #ifdef	CONFIG_USB_GADGET_DUALSPEED
@@ -1712,6 +1710,7 @@
 	set_gadget_data (gadget, dev);
 	dev->gadget = gadget;
 	gadget->ep0->driver_data = dev;
+	dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
 
 	/* preallocate control response and buffer */
 	dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index d8403ae..9cee88a 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -1321,9 +1321,7 @@
 	return 0;
 }
 
-static int langwell_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int langwell_stop(struct usb_gadget_driver *driver);
+
 /* device controller usb_gadget_ops structure */
 static const struct usb_gadget_ops langwell_ops = {
 
@@ -1344,9 +1342,6 @@
 
 	/* D+ pullup, software-controlled connect/disconnect to USB host */
 	.pullup		= langwell_pullup,
-
-	.start		= langwell_start,
-	.stop		= langwell_stop,
 };
 
 
@@ -1857,7 +1852,7 @@
  * the driver might get unbound.
  */
 
-static int langwell_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct langwell_udc	*dev = the_controller;
@@ -1919,9 +1914,11 @@
 	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
+
 
 /* unregister gadget driver */
-static int langwell_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct langwell_udc	*dev = the_controller;
 	unsigned long		flags;
@@ -1968,6 +1965,8 @@
 	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -3374,10 +3373,6 @@
 	if (retval)
 		goto error;
 
-	retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
-	if (retval)
-		goto error;
-
 	retval = device_create_file(&pdev->dev, &dev_attr_langwell_udc);
 	if (retval)
 		goto error;
@@ -3408,7 +3403,6 @@
 
 	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
-	usb_del_gadget_udc(&dev->gadget);
 	/* disable interrupt and set controller to stop state */
 	langwell_udc_stop(dev);
 
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 11d3782..084aa08 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -1454,7 +1454,7 @@
 /*-------------------------------------------------------------------------*/
 static struct m66592 *the_controller;
 
-static int m66592_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct m66592 *m66592 = the_controller;
@@ -1506,8 +1506,9 @@
 
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int m66592_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct m66592 *m66592 = the_controller;
 	unsigned long flags;
@@ -1532,6 +1533,7 @@
 	m66592->driver = NULL;
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------*/
 static int m66592_get_frame(struct usb_gadget *_gadget)
@@ -1542,16 +1544,12 @@
 
 static struct usb_gadget_ops m66592_gadget_ops = {
 	.get_frame		= m66592_get_frame,
-	.start			= m66592_start,
-	.stop			= m66592_stop,
 };
 
 static int __exit m66592_remove(struct platform_device *pdev)
 {
 	struct m66592		*m66592 = dev_get_drvdata(&pdev->dev);
 
-	usb_del_gadget_udc(&m66592->gadget);
-
 	del_timer_sync(&m66592->timer);
 	iounmap(m66592->reg);
 	free_irq(platform_get_irq(pdev, 0), m66592);
@@ -1693,16 +1691,9 @@
 
 	init_controller(m66592);
 
-	ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget);
-	if (ret)
-		goto err_add_udc;
-
 	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
 	return 0;
 
-err_add_udc:
-	m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
-
 clean_up3:
 #ifdef CONFIG_HAVE_CLK
 	if (m66592->pdata->on_chip) {
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 1b2d135..0182242 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -169,7 +169,6 @@
 	.name		= "g_mass_storage",
 	.dev		= &msg_device_desc,
 	.iProduct	= DRIVER_DESC,
-	.max_speed	= USB_SPEED_SUPER,
 	.needs_serial	= 1,
 };
 
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 42c48a5..ea62262 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -1453,10 +1453,7 @@
 
 static int usb_free(struct usb_info *ui, int ret)
 {
-	if (ret)
-		dev_dbg(&ui->pdev->dev, "usb_free(%d)\n", ret);
-
-	usb_del_gadget_udc(&ui->gadget);
+	dev_dbg(&ui->pdev->dev, "usb_free(%d)\n", ret);
 
 	if (ui->xceiv)
 		otg_put_transceiver(ui->xceiv);
@@ -2388,11 +2385,6 @@
 
 }
 
-static int msm72k_gadget_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int msm72k_gadget_stop(struct usb_gadget_driver *driver);
-
-
 static const struct usb_gadget_ops msm72k_ops = {
 	.get_frame	= msm72k_get_frame,
 	.vbus_session	= msm72k_udc_vbus_session,
@@ -2400,8 +2392,6 @@
 	.pullup		= msm72k_pullup,
 	.wakeup		= msm72k_wakeup,
 	.set_selfpowered = msm72k_set_selfpowered,
-	.start		= msm72k_gadget_start,
-	.stop		= msm72k_gadget_stop,
 };
 
 static void usb_do_remote_wakeup(struct work_struct *w)
@@ -2595,10 +2585,6 @@
 	ui->gadget.is_otg = 1;
 #endif
 
-	retval = usb_add_gadget_udc(&pdev->dev, &ui->gadget);
-	if (retval)
-		return usb_free(ui, retval);
-
 	ui->sdev.name = DRIVER_NAME;
 	ui->sdev.print_name = print_switch_name;
 	ui->sdev.print_state = print_switch_state;
@@ -2643,7 +2629,7 @@
 	return 0;
 }
 
-static int msm72k_gadget_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 			    int (*bind)(struct usb_gadget *))
 {
 	struct usb_info *ui = the_usb_info;
@@ -2729,8 +2715,9 @@
 	ui->gadget.dev.driver = NULL;
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int msm72k_gadget_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct usb_info *dev = the_usb_info;
 
@@ -2767,6 +2754,7 @@
 		"unregistered gadget driver '%s'\n", driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 
 static int msm72k_udc_runtime_suspend(struct device *dev)
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 8c7b747..d9feced 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -351,7 +351,6 @@
 	.name		= "g_multi",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(multi_unbind),
 	.iProduct	= DRIVER_DESC,
 	.needs_serial	= 1,
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index 6adf38c..b1a8146 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -1128,9 +1128,6 @@
 	return 0;
 }
 
-static int mv_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int mv_udc_stop(struct usb_gadget_driver *driver);
 /* device controller usb_gadget_ops structure */
 static const struct usb_gadget_ops mv_ops = {
 
@@ -1142,8 +1139,6 @@
 
 	/* D+ pullup, software-controlled connect/disconnect to USB host */
 	.pullup		= mv_udc_pullup,
-	.start		= mv_udc_start,
-	.stop		= mv_udc_stop,
 };
 
 static void mv_udc_testmode(struct mv_udc *udc, u16 index, bool enter)
@@ -1235,7 +1230,7 @@
 	}
 }
 
-static int mv_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct mv_udc *udc = the_controller;
@@ -1275,8 +1270,9 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int mv_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct mv_udc *udc = the_controller;
 	unsigned long flags;
@@ -1300,6 +1296,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static int
 udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty)
@@ -1883,9 +1880,8 @@
 static int mv_udc_remove(struct platform_device *dev)
 {
 	struct mv_udc *udc = the_controller;
-	DECLARE_COMPLETION(done);
 
-	usb_del_gadget_udc(&udc->gadget);
+	DECLARE_COMPLETION(done);
 
 	udc->done = &done;
 
@@ -2078,12 +2074,11 @@
 
 	the_controller = udc;
 
-	retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
-	if (!retval)
-		return retval;
+	goto out;
 error:
 	if (udc)
 		mv_udc_remove(udc->dev);
+out:
 	return retval;
 }
 
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
index 62ee508..99c179a 100644
--- a/drivers/usb/gadget/ncm.c
+++ b/drivers/usb/gadget/ncm.c
@@ -228,7 +228,6 @@
 	.name		= "g_ncm",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(gncm_unbind),
 };
 
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 1e6ea6f..476d88e 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -1410,17 +1410,11 @@
 	return 0;
 }
 
-static int net2280_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int net2280_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops net2280_ops = {
 	.get_frame	= net2280_get_frame,
 	.wakeup		= net2280_wakeup,
 	.set_selfpowered = net2280_set_selfpowered,
 	.pullup		= net2280_pullup,
-	.start		= net2280_start,
-	.stop		= net2280_stop,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -1936,7 +1930,7 @@
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-static int net2280_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct net2280		*dev = the_controller;
@@ -2000,6 +1994,7 @@
 	dev->driver = NULL;
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
@@ -2027,7 +2022,7 @@
 	usb_reinit (dev);
 }
 
-static int net2280_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
 	struct net2280	*dev = the_controller;
 	unsigned long	flags;
@@ -2054,6 +2049,8 @@
 	DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -2735,8 +2732,6 @@
 {
 	struct net2280		*dev = pci_get_drvdata (pdev);
 
-	usb_del_gadget_udc(&dev->gadget);
-
 	BUG_ON(dev->driver);
 
 	/* then clean up the resources we allocated during probe() */
@@ -2921,9 +2916,6 @@
 	retval = device_create_file (&pdev->dev, &dev_attr_registers);
 	if (retval) goto done;
 
-	retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
-	if (retval)
-		goto done;
 	return 0;
 
 done:
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index c7fb772..55ca63a 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -241,7 +241,6 @@
 	.name		= "g_nokia",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= __exit_p(nokia_unbind),
 };
 
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 740c7da..82fd249 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -1375,10 +1375,6 @@
 	return 0;
 }
 
-static int omap_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int omap_udc_stop(struct usb_gadget_driver *driver);
-
 static struct usb_gadget_ops omap_gadget_ops = {
 	.get_frame		= omap_get_frame,
 	.wakeup			= omap_wakeup,
@@ -1386,8 +1382,6 @@
 	.vbus_session		= omap_vbus_session,
 	.vbus_draw		= omap_vbus_draw,
 	.pullup			= omap_pullup,
-	.start			= omap_udc_start,
-	.stop			= omap_udc_stop,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -2108,7 +2102,7 @@
 		);
 }
 
-static int omap_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	int		status = -ENODEV;
@@ -2192,8 +2186,9 @@
 		omap_udc_enable_clock(0);
 	return status;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int omap_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
 	unsigned long	flags;
 	int		status = -ENODEV;
@@ -2227,6 +2222,8 @@
 	DBG("unregistered driver '%s'\n", driver->driver.name);
 	return status;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -2994,16 +2991,9 @@
 
 	create_proc_file();
 	status = device_add(&udc->gadget.dev);
-	if (status)
-		goto cleanup4;
-
-	status = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
 	if (!status)
 		return status;
 	/* If fail, fall through */
-cleanup4:
-	remove_proc_file();
-
 #ifdef	USE_ISO
 cleanup3:
 	free_irq(pdev->resource[2].start, udc);
@@ -3039,8 +3029,6 @@
 
 	if (!udc)
 		return -ENODEV;
-
-	usb_del_gadget_udc(&udc->gadget);
 	if (udc->driver)
 		return -EBUSY;
 
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c
index f96615a..68dbcc3 100644
--- a/drivers/usb/gadget/pch_udc.c
+++ b/drivers/usb/gadget/pch_udc.c
@@ -1176,9 +1176,6 @@
 	return -EOPNOTSUPP;
 }
 
-static int pch_udc_start(struct usb_gadget_driver *driver,
-	int (*bind)(struct usb_gadget *));
-static int pch_udc_stop(struct usb_gadget_driver *driver);
 static const struct usb_gadget_ops pch_udc_ops = {
 	.get_frame = pch_udc_pcd_get_frame,
 	.wakeup = pch_udc_pcd_wakeup,
@@ -1186,8 +1183,6 @@
 	.pullup = pch_udc_pcd_pullup,
 	.vbus_session = pch_udc_pcd_vbus_session,
 	.vbus_draw = pch_udc_pcd_vbus_draw,
-	.start	= pch_udc_start,
-	.stop	= pch_udc_stop,
 };
 
 /**
@@ -2695,7 +2690,7 @@
 	return 0;
 }
 
-static int pch_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 	int (*bind)(struct usb_gadget *))
 {
 	struct pch_udc_dev	*dev = pch_udc;
@@ -2738,8 +2733,9 @@
 	dev->connected = 1;
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int pch_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct pch_udc_dev	*dev = pch_udc;
 
@@ -2765,6 +2761,7 @@
 	pch_udc_set_disconnect(dev);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static void pch_udc_shutdown(struct pci_dev *pdev)
 {
@@ -2781,8 +2778,6 @@
 {
 	struct pch_udc_dev	*dev = pci_get_drvdata(pdev);
 
-	usb_del_gadget_udc(&dev->gadget);
-
 	/* gadget driver must not be registered */
 	if (dev->driver)
 		dev_err(&pdev->dev,
@@ -2958,9 +2953,6 @@
 
 	/* Put the device in disconnected state till a driver is bound */
 	pch_udc_set_disconnect(dev);
-	retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
-	if (retval)
-		goto finished;
 	return 0;
 
 finished:
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index d5df8dd..271ef94 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -89,7 +89,8 @@
 	u8			config;
 	s8			interface;
 	struct usb_ep		*in_ep, *out_ep;
-
+	const struct usb_endpoint_descriptor
+				*in, *out;
 	struct list_head	rx_reqs;	/* List of free RX structs */
 	struct list_head	rx_reqs_active;	/* List of Active RX xfers */
 	struct list_head	rx_buffers;	/* List of completed xfers */
@@ -894,20 +895,19 @@
 {
 	int			result = 0;
 
-	dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
+	dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
 	dev->in_ep->driver_data = dev;
 
-	dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc,
-				    &fs_ep_out_desc);
+	dev->out = ep_desc(dev->gadget, &hs_ep_out_desc, &fs_ep_out_desc);
 	dev->out_ep->driver_data = dev;
 
-	result = usb_ep_enable(dev->in_ep);
+	result = usb_ep_enable(dev->in_ep, dev->in);
 	if (result != 0) {
 		DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
 		goto done;
 	}
 
-	result = usb_ep_enable(dev->out_ep);
+	result = usb_ep_enable(dev->out_ep, dev->out);
 	if (result != 0) {
 		DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
 		goto done;
@@ -918,8 +918,8 @@
 	if (result != 0) {
 		(void) usb_ep_disable(dev->in_ep);
 		(void) usb_ep_disable(dev->out_ep);
-		dev->in_ep->desc = NULL;
-		dev->out_ep->desc = NULL;
+		dev->in = NULL;
+		dev->out = NULL;
 	}
 
 	/* caller is responsible for cleanup on error */
@@ -933,14 +933,12 @@
 
 	DBG(dev, "%s\n", __func__);
 
-	if (dev->in_ep->desc)
+	if (dev->in)
 		usb_ep_disable(dev->in_ep);
 
-	if (dev->out_ep->desc)
+	if (dev->out)
 		usb_ep_disable(dev->out_ep);
 
-	dev->in_ep->desc = NULL;
-	dev->out_ep->desc = NULL;
 	dev->interface = -1;
 }
 
@@ -1106,9 +1104,9 @@
 		list_add(&req->list, &dev->tx_reqs);
 	}
 
-	if (usb_ep_enable(dev->in_ep))
+	if (usb_ep_enable(dev->in_ep, dev->in))
 		DBG(dev, "Failed to enable USB in_ep\n");
-	if (usb_ep_enable(dev->out_ep))
+	if (usb_ep_enable(dev->out_ep, dev->out))
 		DBG(dev, "Failed to enable USB out_ep\n");
 
 	wake_up_interruptible(&dev->rx_wait);
@@ -1148,8 +1146,6 @@
 			switch (wValue >> 8) {
 
 			case USB_DT_DEVICE:
-				device_desc.bMaxPacketSize0 =
-					gadget->ep0->maxpacket;
 				value = min(wLength, (u16) sizeof device_desc);
 				memcpy(req->buf, &device_desc, value);
 				break;
@@ -1157,12 +1153,6 @@
 			case USB_DT_DEVICE_QUALIFIER:
 				if (!gadget->is_dualspeed)
 					break;
-				/*
-				 * assumes ep0 uses the same value for both
-				 * speeds
-				 */
-				dev_qualifier.bMaxPacketSize0 =
-					gadget->ep0->maxpacket;
 				value = min(wLength,
 						(u16) sizeof dev_qualifier);
 				memcpy(req->buf, &dev_qualifier, value);
@@ -1458,11 +1448,15 @@
 	out_ep->driver_data = out_ep;	/* claim */
 
 #ifdef	CONFIG_USB_GADGET_DUALSPEED
-	/* assumes that all endpoints are dual-speed */
+	/* assumes ep0 uses the same value for both speeds ... */
+	dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
+
+	/* and that all endpoints are dual-speed */
 	hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
 	hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
 #endif	/* DUALSPEED */
 
+	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 	usb_gadget_set_selfpowered(gadget);
 
 	if (gadget->is_otg) {
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index e4e59b4..7745454 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -1011,18 +1011,12 @@
 	return -EOPNOTSUPP;
 }
 
-static int pxa25x_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int pxa25x_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops pxa25x_udc_ops = {
 	.get_frame	= pxa25x_udc_get_frame,
 	.wakeup		= pxa25x_udc_wakeup,
 	.vbus_session	= pxa25x_udc_vbus_session,
 	.pullup		= pxa25x_udc_pullup,
 	.vbus_draw	= pxa25x_udc_vbus_draw,
-	.start		= pxa25x_start,
-	.stop		= pxa25x_stop,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -1269,7 +1263,7 @@
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-static int pxa25x_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct pxa25x_udc	*dev = the_controller;
@@ -1328,6 +1322,7 @@
 bind_fail:
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
@@ -1356,7 +1351,7 @@
 	udc_reinit(dev);
 }
 
-static int pxa25x_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct pxa25x_udc	*dev = the_controller;
 
@@ -1384,6 +1379,8 @@
 	dump_state(dev);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -2234,11 +2231,8 @@
 #endif
 	create_debug_files(dev);
 
-	retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
-	if (!retval)
-		return retval;
+	return 0;
 
-	remove_debug_files(dev);
 #ifdef	CONFIG_ARCH_LUBBOCK
 lubbock_fail0:
 	free_irq(LUBBOCK_USB_DISC_IRQ, dev);
@@ -2267,7 +2261,6 @@
 {
 	struct pxa25x_udc *dev = platform_get_drvdata(pdev);
 
-	usb_del_gadget_udc(&dev->gadget);
 	if (dev->driver)
 		return -EBUSY;
 
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 85b68c7..5760769 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1680,18 +1680,12 @@
 	return -EOPNOTSUPP;
 }
 
-static int pxa27x_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int pxa27x_udc_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops pxa_udc_ops = {
 	.get_frame	= pxa_udc_get_frame,
 	.wakeup		= pxa_udc_wakeup,
 	.pullup		= pxa_udc_pullup,
 	.vbus_session	= pxa_udc_vbus_session,
 	.vbus_draw	= pxa_udc_vbus_draw,
-	.start		= pxa27x_udc_start,
-	.stop		= pxa27x_udc_stop,
 };
 
 /**
@@ -1797,7 +1791,7 @@
 }
 
 /**
- * pxa27x_start - Register gadget driver
+ * usb_gadget_probe_driver - Register gadget driver
  * @driver: gadget driver
  * @bind: bind function
  *
@@ -1811,7 +1805,7 @@
  *
  * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
  */
-static int pxa27x_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct pxa_udc *udc = the_controller;
@@ -1866,6 +1860,8 @@
 	udc->gadget.dev.driver = NULL;
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
+
 
 /**
  * stop_activity - Stops udc endpoints
@@ -1892,12 +1888,12 @@
 }
 
 /**
- * pxa27x_udc_stop - Unregister the gadget driver
+ * usb_gadget_unregister_driver - Unregister the gadget driver
  * @driver: gadget driver
  *
  * Returns 0 if no error, -ENODEV, -EINVAL otherwise
  */
-static int pxa27x_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct pxa_udc *udc = the_controller;
 
@@ -1921,6 +1917,7 @@
 		return otg_set_peripheral(udc->transceiver, NULL);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /**
  * handle_ep0_ctrl_req - handle control endpoint control request
@@ -2519,14 +2516,9 @@
 			driver_name, IRQ_USB, retval);
 		goto err_irq;
 	}
-	retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
-	if (retval)
-		goto err_add_udc;
 
 	pxa_init_debugfs(udc);
 	return 0;
-err_add_udc:
-	free_irq(udc->irq, udc);
 err_irq:
 	iounmap(udc->regs);
 err_map:
@@ -2545,7 +2537,6 @@
 	struct pxa_udc *udc = platform_get_drvdata(_dev);
 	int gpio = udc->mach->gpio_pullup;
 
-	usb_del_gadget_udc(&udc->gadget);
 	usb_gadget_unregister_driver(udc->driver);
 	free_irq(udc->irq, udc);
 	pxa_cleanup_debugfs(udc);
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 51b655f..6dcc1f6 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -1410,7 +1410,7 @@
 /*-------------------------------------------------------------------------*/
 static struct r8a66597 *the_controller;
 
-static int r8a66597_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct r8a66597 *r8a66597 = the_controller;
@@ -1462,8 +1462,9 @@
 
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int r8a66597_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct r8a66597 *r8a66597 = the_controller;
 	unsigned long flags;
@@ -1487,6 +1488,7 @@
 	r8a66597->driver = NULL;
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*-------------------------------------------------------------------------*/
 static int r8a66597_get_frame(struct usb_gadget *_gadget)
@@ -1497,15 +1499,12 @@
 
 static struct usb_gadget_ops r8a66597_gadget_ops = {
 	.get_frame		= r8a66597_get_frame,
-	.start			= r8a66597_start,
-	.stop			= r8a66597_stop,
 };
 
 static int __exit r8a66597_remove(struct platform_device *pdev)
 {
 	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
 
-	usb_del_gadget_udc(&r8a66597->gadget);
 	del_timer_sync(&r8a66597->timer);
 	iounmap(r8a66597->reg);
 	free_irq(platform_get_irq(pdev, 0), r8a66597);
@@ -1648,15 +1647,9 @@
 
 	init_controller(r8a66597);
 
-	ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget);
-	if (ret)
-		goto err_add_udc;
-
 	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
 	return 0;
 
-err_add_udc:
-	r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
 clean_up3:
 	free_irq(irq, r8a66597);
 clean_up2:
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 8bdee67..0dfee28 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -2574,7 +2574,7 @@
 	return 0;
 }
 
-static int s3c_hsotg_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct s3c_hsotg *hsotg = our_hsotg;
@@ -2745,8 +2745,9 @@
 	hsotg->gadget.dev.driver = NULL;
 	return ret;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int s3c_hsotg_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct s3c_hsotg *hsotg = our_hsotg;
 	int ep;
@@ -2774,6 +2775,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget)
 {
@@ -2782,8 +2784,6 @@
 
 static struct usb_gadget_ops s3c_hsotg_gadget_ops = {
 	.get_frame	= s3c_hsotg_gadget_getframe,
-	.start		= s3c_hsotg_start,
-	.stop		= s3c_hsotg_stop,
 };
 
 /**
@@ -3403,10 +3403,6 @@
 	for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++)
 		s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum);
 
-	ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
-	if (ret)
-		goto err_add_udc;
-
 	s3c_hsotg_create_debug(hsotg);
 
 	s3c_hsotg_dump(hsotg);
@@ -3414,11 +3410,6 @@
 	our_hsotg = hsotg;
 	return 0;
 
-err_add_udc:
-	s3c_hsotg_gate(pdev, false);
-	clk_disable(hsotg->clk);
-	clk_put(hsotg->clk);
-
 err_regs:
 	iounmap(hsotg->regs);
 
@@ -3436,8 +3427,6 @@
 {
 	struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
 
-	usb_del_gadget_udc(&hsotg->gadget);
-
 	s3c_hsotg_delete_debug(hsotg);
 
 	usb_gadget_unregister_driver(hsotg->driver);
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c
index dc9f428..d5e3e1e 100644
--- a/drivers/usb/gadget/s3c-hsudc.c
+++ b/drivers/usb/gadget/s3c-hsudc.c
@@ -1133,7 +1133,7 @@
 	return IRQ_HANDLED;
 }
 
-static int s3c_hsudc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct s3c_hsudc *hsudc = the_controller;
@@ -1181,8 +1181,9 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int s3c_hsudc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct s3c_hsudc *hsudc = the_controller;
 	unsigned long flags;
@@ -1209,6 +1210,7 @@
 			driver->driver.name);
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc)
 {
@@ -1222,8 +1224,6 @@
 
 static struct usb_gadget_ops s3c_hsudc_gadget_ops = {
 	.get_frame	= s3c_hsudc_gadget_getframe,
-	.start		= s3c_hsudc_start,
-	.stop		= s3c_hsudc_stop,
 };
 
 static int s3c_hsudc_probe(struct platform_device *pdev)
@@ -1311,15 +1311,7 @@
 
 	disable_irq(hsudc->irq);
 	local_irq_enable();
-
-	ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget);
-	if (ret)
-		goto err_add_udc;
-
 	return 0;
-err_add_udc:
-	clk_disable(hsudc->uclk);
-	clk_put(hsudc->uclk);
 err_clk:
 	free_irq(hsudc->irq, hsudc);
 err_irq:
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index 1c19cd3..100f263 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1552,10 +1552,6 @@
 	return -ENOTSUPP;
 }
 
-static int s3c2410_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int s3c2410_udc_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops s3c2410_ops = {
 	.get_frame		= s3c2410_udc_get_frame,
 	.wakeup			= s3c2410_udc_wakeup,
@@ -1563,8 +1559,6 @@
 	.pullup			= s3c2410_udc_pullup,
 	.vbus_session		= s3c2410_udc_vbus_session,
 	.vbus_draw		= s3c2410_vbus_draw,
-	.start			= s3c2410_udc_start,
-	.stop			= s3c2410_udc_stop,
 };
 
 static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd)
@@ -1678,7 +1672,10 @@
 	s3c2410_udc_command(S3C2410_UDC_P_ENABLE);
 }
 
-static int s3c2410_udc_start(struct usb_gadget_driver *driver,
+/*
+ *	usb_gadget_probe_driver
+ */
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct s3c2410_udc *udc = the_controller;
@@ -1733,8 +1730,12 @@
 	udc->gadget.dev.driver = NULL;
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int s3c2410_udc_stop(struct usb_gadget_driver *driver)
+/*
+ *	usb_gadget_unregister_driver
+ */
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct s3c2410_udc *udc = the_controller;
 
@@ -1954,10 +1955,6 @@
 			goto err_vbus_irq;
 	}
 
-	retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
-	if (retval)
-		goto err_add_udc;
-
 	if (s3c2410_udc_debugfs_root) {
 		udc->regs_info = debugfs_create_file("registers", S_IRUGO,
 				s3c2410_udc_debugfs_root,
@@ -1970,10 +1967,6 @@
 
 	return 0;
 
-err_add_udc:
-	if (udc_info && !udc_info->udc_command &&
-			gpio_is_valid(udc_info->pullup_pin))
-		gpio_free(udc_info->pullup_pin);
 err_vbus_irq:
 	if (udc_info && udc_info->vbus_pin > 0)
 		free_irq(gpio_to_irq(udc_info->vbus_pin), udc);
@@ -1999,8 +1992,6 @@
 	unsigned int irq;
 
 	dev_dbg(&pdev->dev, "%s()\n", __func__);
-
-	usb_del_gadget_udc(&udc->gadget);
 	if (udc->driver)
 		return -EBUSY;
 
@@ -2114,6 +2105,8 @@
 	debugfs_remove(s3c2410_udc_debugfs_root);
 }
 
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 module_init(udc_init);
 module_exit(udc_exit);
 
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index ed1b816..1ac57a9 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -242,7 +242,6 @@
 	.name		= "g_serial",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 };
 
 static int __init init(void)
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 43a54f1..1505967 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -247,8 +247,6 @@
 	u32		sense_data_info;
 	u32		unit_attention_data;
 
-	unsigned int	blkbits;	/* Bits of logical block size of bound block device */
-	unsigned int	blksize;	/* logical block size of bound block device */
 	struct device	dev;
 #ifdef CONFIG_USB_MSC_PROFILING
 	spinlock_t	lock;
@@ -511,128 +509,12 @@
 	NULL,
 };
 
-static struct usb_endpoint_descriptor
-fsg_ss_bulk_in_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
-	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	.wMaxPacketSize =	cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
-	.bLength =		sizeof(fsg_ss_bulk_in_comp_desc),
-	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
-
-	/*.bMaxBurst =		DYNAMIC, */
-};
-
-static struct usb_endpoint_descriptor
-fsg_ss_bulk_out_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
-	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	.wMaxPacketSize =	cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
-	.bLength =		sizeof(fsg_ss_bulk_in_comp_desc),
-	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
-
-	/*.bMaxBurst =		DYNAMIC, */
-};
-
-#ifndef FSG_NO_INTR_EP
-
-static struct usb_endpoint_descriptor
-fsg_ss_intr_in_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-
-	/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
-	.bmAttributes =		USB_ENDPOINT_XFER_INT,
-	.wMaxPacketSize =	cpu_to_le16(2),
-	.bInterval =		9,	/* 2**(9-1) = 256 uframes -> 32 ms */
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = {
-	.bLength =		sizeof(fsg_ss_bulk_in_comp_desc),
-	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
-
-	.wBytesPerInterval =	cpu_to_le16(2),
-};
-
-#ifndef FSG_NO_OTG
-#  define FSG_SS_FUNCTION_PRE_EP_ENTRIES	2
-#else
-#  define FSG_SS_FUNCTION_PRE_EP_ENTRIES	1
-#endif
-
-#endif
-
-static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = {
-	.bLength =		USB_DT_USB_EXT_CAP_SIZE,
-	.bDescriptorType =	USB_DT_DEVICE_CAPABILITY,
-	.bDevCapabilityType =	USB_CAP_TYPE_EXT,
-
-	.bmAttributes =		cpu_to_le32(USB_LPM_SUPPORT),
-};
-
-static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = {
-	.bLength =		USB_DT_USB_SS_CAP_SIZE,
-	.bDescriptorType =	USB_DT_DEVICE_CAPABILITY,
-	.bDevCapabilityType =	USB_SS_CAP_TYPE,
-
-	/* .bmAttributes = LTM is not supported yet */
-
-	.wSpeedSupported =	cpu_to_le16(USB_LOW_SPEED_OPERATION
-		| USB_FULL_SPEED_OPERATION
-		| USB_HIGH_SPEED_OPERATION
-		| USB_5GBPS_OPERATION),
-	.bFunctionalitySupport = USB_LOW_SPEED_OPERATION,
-	.bU1devExitLat =	USB_DEFAULT_U1_DEV_EXIT_LAT,
-	.bU2DevExitLat =	USB_DEFAULT_U2_DEV_EXIT_LAT,
-};
-
-static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = {
-	.bLength =		USB_DT_BOS_SIZE,
-	.bDescriptorType =	USB_DT_BOS,
-
-	.wTotalLength =		USB_DT_BOS_SIZE
-				+ USB_DT_USB_EXT_CAP_SIZE
-				+ USB_DT_USB_SS_CAP_SIZE,
-
-	.bNumDeviceCaps =	2,
-};
-
-static struct usb_descriptor_header *fsg_ss_function[] = {
-#ifndef FSG_NO_OTG
-	(struct usb_descriptor_header *) &fsg_otg_desc,
-#endif
-	(struct usb_descriptor_header *) &fsg_intf_desc,
-	(struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
-	(struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
-	(struct usb_descriptor_header *) &fsg_ss_bulk_out_desc,
-	(struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
-#ifndef FSG_NO_INTR_EP
-	(struct usb_descriptor_header *) &fsg_ss_intr_in_desc,
-	(struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc,
-#endif
-	NULL,
-};
-
 /* Maxpacket and other transfer characteristics vary by speed. */
-static __maybe_unused struct usb_endpoint_descriptor *
+static struct usb_endpoint_descriptor *
 fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
-		struct usb_endpoint_descriptor *hs,
-		struct usb_endpoint_descriptor *ss)
+		struct usb_endpoint_descriptor *hs)
 {
-	if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
-		return ss;
-	else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
 		return hs;
 	return fs;
 }
@@ -714,24 +596,13 @@
 		rc = (int) size;
 		goto out;
 	}
-
-	if (curlun->cdrom) {
-		curlun->blksize = 2048;
-		curlun->blkbits = 11;
-	} else if (inode->i_bdev) {
-		curlun->blksize = bdev_logical_block_size(inode->i_bdev);
-		curlun->blkbits = blksize_bits(curlun->blksize);
-	} else {
-		curlun->blksize = 512;
-		curlun->blkbits = 9;
-	}
-
-	num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */
+	num_sectors = size >> 9;	/* File size in 512-byte blocks */
 	min_sectors = 1;
 	if (curlun->cdrom) {
-		min_sectors = 300;	/* Smallest track is 300 frames */
-		if (num_sectors >= 256*60*75) {
-			num_sectors = 256*60*75 - 1;
+		num_sectors &= ~3;	/* Reduce to a multiple of 2048 */
+		min_sectors = 300*4;	/* Smallest track is 300 frames */
+		if (num_sectors >= 256*60*75*4) {
+			num_sectors = (256*60*75 - 1) * 4;
 			LINFO(curlun, "file too big: %s\n", filename);
 			LINFO(curlun, "using only first %d blocks\n",
 					(int) num_sectors);
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 36270d4..6299cdd 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -704,7 +704,7 @@
 	int ret;
 	unsigned long flags;
 
-	ret = usb_ep_enable(port->gr->in);
+	ret = usb_ep_enable(port->gr->in, port->gr->in_desc);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
 				__func__, port->gr->in);
@@ -712,7 +712,7 @@
 	}
 	port->gr->in->driver_data = port;
 
-	ret = usb_ep_enable(port->gr->out);
+	ret = usb_ep_enable(port->gr->out, port->gr->out_desc);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
 				__func__, port->gr->out);
@@ -1125,7 +1125,7 @@
 	d = &port->data_ch;
 
 	if (trans == USB_GADGET_XPORT_BAM) {
-		ret = usb_ep_enable(gr->in);
+		ret = usb_ep_enable(gr->in, gr->in_desc);
 		if (ret) {
 			pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
 					__func__, gr->in);
@@ -1133,7 +1133,7 @@
 		}
 		gr->in->driver_data = port;
 
-		ret = usb_ep_enable(gr->out);
+		ret = usb_ep_enable(gr->out, gr->out_desc);
 		if (ret) {
 			pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
 					__func__, gr->out);
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index a12953b..7b77a1d 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -741,6 +741,8 @@
 	struct gdata_port		*port;
 	struct gserial			*gser;
 	struct grmnet			*gr;
+	struct usb_endpoint_descriptor	*in_desc;
+	struct usb_endpoint_descriptor	*out_desc;
 	unsigned long			flags;
 	int				ret = 0;
 
@@ -766,6 +768,8 @@
 		port->rx_q_size = ghsic_data_serial_rx_q_size;
 		gser->in->driver_data = port;
 		gser->out->driver_data = port;
+		in_desc = gser->in_desc;
+		out_desc = gser->out_desc;
 	} else {
 		gr = gptr;
 		port->in = gr->in;
@@ -774,16 +778,18 @@
 		port->rx_q_size = ghsic_data_rmnet_rx_q_size;
 		gr->in->driver_data = port;
 		gr->out->driver_data = port;
+		in_desc = gr->in_desc;
+		out_desc = gr->out_desc;
 	}
 
-	ret = usb_ep_enable(port->in);
+	ret = usb_ep_enable(port->in, in_desc);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
 				__func__, port->in);
 		goto fail;
 	}
 
-	ret = usb_ep_enable(port->out);
+	ret = usb_ep_enable(port->out, out_desc);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
 				__func__, port->out);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 39c53da..b5a30fe 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -693,8 +693,8 @@
 		usb_ep_disable(link->out_ep);
 		if (netif_carrier_ok(net)) {
 			DBG(dev, "host still using in/out endpoints\n");
-			usb_ep_enable(link->in_ep);
-			usb_ep_enable(link->out_ep);
+			usb_ep_enable(link->in_ep, link->in);
+			usb_ep_enable(link->out_ep, link->out);
 		}
 	}
 	spin_unlock_irqrestore(&dev->lock, flags);
@@ -891,7 +891,7 @@
 		return ERR_PTR(-EINVAL);
 
 	link->in_ep->driver_data = dev;
-	result = usb_ep_enable(link->in_ep);
+	result = usb_ep_enable(link->in_ep, link->in);
 	if (result != 0) {
 		DBG(dev, "enable %s --> %d\n",
 			link->in_ep->name, result);
@@ -899,7 +899,7 @@
 	}
 
 	link->out_ep->driver_data = dev;
-	result = usb_ep_enable(link->out_ep);
+	result = usb_ep_enable(link->out_ep, link->out);
 	if (result != 0) {
 		DBG(dev, "enable %s --> %d\n",
 			link->out_ep->name, result);
@@ -988,7 +988,7 @@
 	}
 	spin_unlock(&dev->req_lock);
 	link->in_ep->driver_data = NULL;
-	link->in_ep->desc = NULL;
+	link->in = NULL;
 
 	usb_ep_disable(link->out_ep);
 	spin_lock(&dev->req_lock);
@@ -1003,7 +1003,7 @@
 	}
 	spin_unlock(&dev->req_lock);
 	link->out_ep->driver_data = NULL;
-	link->out_ep->desc = NULL;
+	link->out = NULL;
 
 	/* finish forgetting about this USB link episode */
 	dev->header_len = 0;
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
index 4677241..64b65f9 100644
--- a/drivers/usb/gadget/u_ether.h
+++ b/drivers/usb/gadget/u_ether.h
@@ -52,6 +52,10 @@
 	struct usb_ep			*in_ep;
 	struct usb_ep			*out_ep;
 
+	/* descriptors match device speed at gether_connect() time */
+	struct usb_endpoint_descriptor	*in;
+	struct usb_endpoint_descriptor	*out;
+
 	bool				is_zlp_ok;
 
 	u16				cdc_filter;
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index 386101c..fd1e124 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -29,6 +29,8 @@
 
 	struct usb_ep			*in;
 	struct usb_ep			*out;
+	struct usb_endpoint_descriptor	*in_desc;
+	struct usb_endpoint_descriptor	*out_desc;
 
 	/* to usb host, aka laptop, windows pc etc. Will
 	 * be filled by usb driver of rmnet functionality
diff --git a/drivers/usb/gadget/u_sdio.c b/drivers/usb/gadget/u_sdio.c
index 14dc73a..9bd4370 100644
--- a/drivers/usb/gadget/u_sdio.c
+++ b/drivers/usb/gadget/u_sdio.c
@@ -931,7 +931,7 @@
 	gser->notify_modem = gsdio_ctrl_notify_modem;
 	spin_unlock_irqrestore(&port->port_lock, flags);
 
-	ret = usb_ep_enable(gser->in);
+	ret = usb_ep_enable(gser->in, gser->in_desc);
 	if (ret) {
 		pr_err("%s: failed to enable in ep w/ err:%d\n",
 					__func__, ret);
@@ -940,7 +940,7 @@
 	}
 	gser->in->driver_data = port;
 
-	ret = usb_ep_enable(gser->out);
+	ret = usb_ep_enable(gser->out, gser->out_desc);
 	if (ret) {
 		pr_err("%s: failed to enable in ep w/ err:%d\n",
 					__func__, ret);
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 10a255d..ca5f11b 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1524,12 +1524,12 @@
 	port = ports[port_num].port;
 
 	/* activate the endpoints */
-	status = usb_ep_enable(gser->in);
+	status = usb_ep_enable(gser->in, gser->in_desc);
 	if (status < 0)
 		return status;
 	gser->in->driver_data = port;
 
-	status = usb_ep_enable(gser->out);
+	status = usb_ep_enable(gser->out, gser->out_desc);
 	if (status < 0)
 		goto fail_out;
 	gser->out->driver_data = port;
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
index dadc507..c937006 100644
--- a/drivers/usb/gadget/u_serial.h
+++ b/drivers/usb/gadget/u_serial.h
@@ -35,6 +35,8 @@
 
 	struct usb_ep			*in;
 	struct usb_ep			*out;
+	struct usb_endpoint_descriptor	*in_desc;
+	struct usb_endpoint_descriptor	*out_desc;
 
 	/* REVISIT avoid this CDC-ACM support harder ... */
 	struct usb_cdc_line_coding port_line_coding;	/* 9600-8-N-1 etc */
diff --git a/drivers/usb/gadget/u_smd.c b/drivers/usb/gadget/u_smd.c
index 0e9ad48..95adf5d 100644
--- a/drivers/usb/gadget/u_smd.c
+++ b/drivers/usb/gadget/u_smd.c
@@ -660,7 +660,7 @@
 	port->nbytes_tolaptop = 0;
 	spin_unlock_irqrestore(&port->port_lock, flags);
 
-	ret = usb_ep_enable(gser->in);
+	ret = usb_ep_enable(gser->in, gser->in_desc);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
 				__func__, gser->in);
@@ -669,7 +669,7 @@
 	}
 	gser->in->driver_data = port;
 
-	ret = usb_ep_enable(gser->out);
+	ret = usb_ep_enable(gser->out, gser->out_desc);
 	if (ret) {
 		pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
 				__func__, gser->out);
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
deleted file mode 100644
index 2f77e46..0000000
--- a/drivers/usb/gadget/udc-core.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- * udc.c - Core UDC Framework
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Felipe Balbi <balbi@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2  of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/err.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-/**
- * struct usb_udc - describes one usb device controller
- * @driver - the gadget driver pointer. For use by the class code
- * @dev - the child device to the actual controller
- * @gadget - the gadget. For use by the class code
- * @list - for use by the udc class driver
- *
- * This represents the internal data structure which is used by the UDC-class
- * to hold information about udc driver and gadget together.
- */
-struct usb_udc {
-	struct usb_gadget_driver	*driver;
-	struct usb_gadget		*gadget;
-	struct device			dev;
-	struct list_head		list;
-};
-
-static struct class *udc_class;
-static struct device_type udc_device_type;
-static LIST_HEAD(udc_list);
-static DEFINE_MUTEX(udc_lock);
-
-/* ------------------------------------------------------------------------- */
-
-/**
- * usb_gadget_start - tells usb device controller to start up
- * @gadget: The gadget we want to get started
- * @driver: The driver we want to bind to @gadget
- * @bind: The bind function for @driver
- *
- * This call is issued by the UDC Class driver when it's about
- * to register a gadget driver to the device controller, before
- * calling gadget driver's bind() method.
- *
- * It allows the controller to be powered off until strictly
- * necessary to have it powered on.
- *
- * Returns zero on success, else negative errno.
- */
-static inline int usb_gadget_start(struct usb_gadget *gadget,
-		struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
-{
-	return gadget->ops->start(driver, bind);
-}
-
-/**
- * usb_gadget_udc_start - tells usb device controller to start up
- * @gadget: The gadget we want to get started
- * @driver: The driver we want to bind to @gadget
- *
- * This call is issued by the UDC Class driver when it's about
- * to register a gadget driver to the device controller, before
- * calling gadget driver's bind() method.
- *
- * It allows the controller to be powered off until strictly
- * necessary to have it powered on.
- *
- * Returns zero on success, else negative errno.
- */
-static inline int usb_gadget_udc_start(struct usb_gadget *gadget,
-		struct usb_gadget_driver *driver)
-{
-	return gadget->ops->udc_start(gadget, driver);
-}
-
-/**
- * usb_gadget_stop - tells usb device controller we don't need it anymore
- * @gadget: The device we want to stop activity
- * @driver: The driver to unbind from @gadget
- *
- * This call is issued by the UDC Class driver after calling
- * gadget driver's unbind() method.
- *
- * The details are implementation specific, but it can go as
- * far as powering off UDC completely and disable its data
- * line pullups.
- */
-static inline void usb_gadget_stop(struct usb_gadget *gadget,
-		struct usb_gadget_driver *driver)
-{
-	gadget->ops->stop(driver);
-}
-
-/**
- * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
- * @gadget: The device we want to stop activity
- * @driver: The driver to unbind from @gadget
- *
- * This call is issued by the UDC Class driver after calling
- * gadget driver's unbind() method.
- *
- * The details are implementation specific, but it can go as
- * far as powering off UDC completely and disable its data
- * line pullups.
- */
-static inline void usb_gadget_udc_stop(struct usb_gadget *gadget,
-		struct usb_gadget_driver *driver)
-{
-	gadget->ops->udc_stop(gadget, driver);
-}
-
-/**
- * usb_udc_release - release the usb_udc struct
- * @dev: the dev member within usb_udc
- *
- * This is called by driver's core in order to free memory once the last
- * reference is released.
- */
-static void usb_udc_release(struct device *dev)
-{
-	struct usb_udc *udc;
-
-	udc = container_of(dev, struct usb_udc, dev);
-	dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
-	kfree(udc);
-}
-
-/**
- * usb_add_gadget_udc - adds a new gadget to the udc class driver list
- * @parent: the parent device to this udc. Usually the controller
- * driver's device.
- * @gadget: the gadget to be added to the list
- *
- * Returns zero on success, negative errno otherwise.
- */
-int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
-{
-	struct usb_udc		*udc;
-	int			ret = -ENOMEM;
-
-	udc = kzalloc(sizeof(*udc), GFP_KERNEL);
-	if (!udc)
-		goto err1;
-
-	device_initialize(&udc->dev);
-	udc->dev.release = usb_udc_release;
-	udc->dev.class = udc_class;
-	udc->dev.parent = parent;
-	ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj));
-	if (ret)
-		goto err2;
-
-	udc->gadget = gadget;
-
-	mutex_lock(&udc_lock);
-	list_add_tail(&udc->list, &udc_list);
-
-	ret = device_add(&udc->dev);
-	if (ret)
-		goto err3;
-
-	mutex_unlock(&udc_lock);
-
-	return 0;
-err3:
-	list_del(&udc->list);
-	mutex_unlock(&udc_lock);
-
-err2:
-	put_device(&udc->dev);
-
-err1:
-	return ret;
-}
-EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
-
-static int udc_is_newstyle(struct usb_udc *udc)
-{
-	if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop)
-		return 1;
-	return 0;
-}
-
-
-static void usb_gadget_remove_driver(struct usb_udc *udc)
-{
-	dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
-			udc->gadget->name);
-
-	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
-
-	if (udc_is_newstyle(udc)) {
-		udc->driver->disconnect(udc->gadget);
-		udc->driver->unbind(udc->gadget);
-		usb_gadget_udc_stop(udc->gadget, udc->driver);
-		usb_gadget_disconnect(udc->gadget);
-	} else {
-		usb_gadget_stop(udc->gadget, udc->driver);
-	}
-
-	udc->driver = NULL;
-	udc->dev.driver = NULL;
-}
-
-/**
- * usb_del_gadget_udc - deletes @udc from udc_list
- * @gadget: the gadget to be removed.
- *
- * This, will call usb_gadget_unregister_driver() if
- * the @udc is still busy.
- */
-void usb_del_gadget_udc(struct usb_gadget *gadget)
-{
-	struct usb_udc		*udc = NULL;
-
-	mutex_lock(&udc_lock);
-	list_for_each_entry(udc, &udc_list, list)
-		if (udc->gadget == gadget)
-			goto found;
-
-	dev_err(gadget->dev.parent, "gadget not registered.\n");
-	mutex_unlock(&udc_lock);
-
-	return;
-
-found:
-	dev_vdbg(gadget->dev.parent, "unregistering gadget\n");
-
-	list_del(&udc->list);
-	mutex_unlock(&udc_lock);
-
-	if (udc->driver)
-		usb_gadget_remove_driver(udc);
-
-	kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
-	device_unregister(&udc->dev);
-}
-EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
-
-/* ------------------------------------------------------------------------- */
-
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
-{
-	struct usb_udc		*udc = NULL;
-	int			ret;
-
-	if (!driver || !bind || !driver->setup)
-		return -EINVAL;
-
-	mutex_lock(&udc_lock);
-	list_for_each_entry(udc, &udc_list, list) {
-		/* For now we take the first one */
-		if (!udc->driver)
-			goto found;
-	}
-
-	pr_debug("couldn't find an available UDC\n");
-	mutex_unlock(&udc_lock);
-	return -ENODEV;
-
-found:
-	dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
-			driver->function);
-
-	udc->driver = driver;
-	udc->dev.driver = &driver->driver;
-
-	if (udc_is_newstyle(udc)) {
-		ret = bind(udc->gadget);
-		if (ret)
-			goto err1;
-		ret = usb_gadget_udc_start(udc->gadget, driver);
-		if (ret) {
-			driver->unbind(udc->gadget);
-			goto err1;
-		}
-		usb_gadget_connect(udc->gadget);
-	} else {
-
-		ret = usb_gadget_start(udc->gadget, driver, bind);
-		if (ret)
-			goto err1;
-
-	}
-
-	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
-	mutex_unlock(&udc_lock);
-	return 0;
-
-err1:
-	dev_err(&udc->dev, "failed to start %s: %d\n",
-			udc->driver->function, ret);
-	udc->driver = NULL;
-	udc->dev.driver = NULL;
-	mutex_unlock(&udc_lock);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
-
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
-{
-	struct usb_udc		*udc = NULL;
-	int			ret = -ENODEV;
-
-	if (!driver || !driver->unbind)
-		return -EINVAL;
-
-	mutex_lock(&udc_lock);
-	list_for_each_entry(udc, &udc_list, list)
-		if (udc->driver == driver) {
-			usb_gadget_remove_driver(udc);
-			ret = 0;
-			break;
-		}
-
-	mutex_unlock(&udc_lock);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
-
-/* ------------------------------------------------------------------------- */
-
-static ssize_t usb_udc_srp_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t n)
-{
-	struct usb_udc		*udc = dev_get_drvdata(dev);
-
-	if (sysfs_streq(buf, "1"))
-		usb_gadget_wakeup(udc->gadget);
-
-	return n;
-}
-static DEVICE_ATTR(srp, S_IWUSR, NULL, usb_udc_srp_store);
-
-static ssize_t usb_udc_softconn_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t n)
-{
-	struct usb_udc		*udc = dev_get_drvdata(dev);
-
-	if (sysfs_streq(buf, "connect")) {
-		usb_gadget_connect(udc->gadget);
-	} else if (sysfs_streq(buf, "disconnect")) {
-		usb_gadget_disconnect(udc->gadget);
-	} else {
-		dev_err(dev, "unsupported command '%s'\n", buf);
-		return -EINVAL;
-	}
-
-	return n;
-}
-static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store);
-
-static ssize_t usb_udc_speed_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct usb_udc		*udc = dev_get_drvdata(dev);
-	struct usb_gadget	*gadget = udc->gadget;
-
-	switch (gadget->speed) {
-	case USB_SPEED_LOW:
-		return snprintf(buf, PAGE_SIZE, "low-speed\n");
-	case USB_SPEED_FULL:
-		return snprintf(buf, PAGE_SIZE, "full-speed\n");
-	case USB_SPEED_HIGH:
-		return snprintf(buf, PAGE_SIZE, "high-speed\n");
-	case USB_SPEED_WIRELESS:
-		return snprintf(buf, PAGE_SIZE, "wireless\n");
-	case USB_SPEED_SUPER:
-		return snprintf(buf, PAGE_SIZE, "super-speed\n");
-	case USB_SPEED_UNKNOWN:	/* FALLTHROUGH */
-	default:
-		return snprintf(buf, PAGE_SIZE, "UNKNOWN\n");
-	}
-}
-static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
-
-#define USB_UDC_ATTR(name)					\
-ssize_t usb_udc_##name##_show(struct device *dev,		\
-		struct device_attribute *attr, char *buf)	\
-{								\
-	struct usb_udc		*udc = dev_get_drvdata(dev);	\
-	struct usb_gadget	*gadget = udc->gadget;		\
-								\
-	return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name);	\
-}								\
-static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL)
-
-static USB_UDC_ATTR(is_dualspeed);
-static USB_UDC_ATTR(is_otg);
-static USB_UDC_ATTR(is_a_peripheral);
-static USB_UDC_ATTR(b_hnp_enable);
-static USB_UDC_ATTR(a_hnp_support);
-static USB_UDC_ATTR(a_alt_hnp_support);
-
-static struct attribute *usb_udc_attrs[] = {
-	&dev_attr_srp.attr,
-	&dev_attr_soft_connect.attr,
-	&dev_attr_speed.attr,
-
-	&dev_attr_is_dualspeed.attr,
-	&dev_attr_is_otg.attr,
-	&dev_attr_is_a_peripheral.attr,
-	&dev_attr_b_hnp_enable.attr,
-	&dev_attr_a_hnp_support.attr,
-	&dev_attr_a_alt_hnp_support.attr,
-	NULL,
-};
-
-static const struct attribute_group usb_udc_attr_group = {
-	.attrs = usb_udc_attrs,
-};
-
-static const struct attribute_group *usb_udc_attr_groups[] = {
-	&usb_udc_attr_group,
-	NULL,
-};
-
-static int usb_udc_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);
-	int			ret;
-
-	ret = add_uevent_var(env, "USB_UDC_NAME=%s", udc->gadget->name);
-	if (ret) {
-		dev_err(dev, "failed to add uevent USB_UDC_NAME\n");
-		return ret;
-	}
-
-	if (udc->driver) {
-		ret = add_uevent_var(env, "USB_UDC_DRIVER=%s",
-				udc->driver->function);
-		if (ret) {
-			dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int __init usb_udc_init(void)
-{
-	udc_class = class_create(THIS_MODULE, "udc");
-	if (IS_ERR(udc_class)) {
-		pr_err("failed to create udc class --> %ld\n",
-				PTR_ERR(udc_class));
-		return PTR_ERR(udc_class);
-	}
-
-	udc_class->dev_uevent = usb_udc_uevent;
-	udc_device_type.groups = usb_udc_attr_groups;
-
-	return 0;
-}
-subsys_initcall(usb_udc_init);
-
-static void __exit usb_udc_exit(void)
-{
-	class_destroy(udc_class);
-}
-module_exit(usb_udc_exit);
-
-MODULE_DESCRIPTION("UDC Framework");
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index df6882d..a5a0fdb 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -373,7 +373,6 @@
 	.name		= "g_webcam",
 	.dev		= &webcam_device_descriptor,
 	.strings	= webcam_device_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= webcam_unbind,
 };
 
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index af7e7c3..6d16db9 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -340,7 +340,6 @@
 	.name		= "zero",
 	.dev		= &device_desc,
 	.strings	= dev_strings,
-	.max_speed	= USB_SPEED_HIGH,
 	.unbind		= zero_unbind,
 	.suspend	= zero_suspend,
 	.resume		= zero_resume,
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 784910a..548338c 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1715,10 +1715,6 @@
 	return 0;
 }
 
-static int musb_gadget_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int musb_gadget_stop(struct usb_gadget_driver *driver);
-
 static const struct usb_gadget_ops musb_gadget_operations = {
 	.get_frame		= musb_gadget_get_frame,
 	.wakeup			= musb_gadget_wakeup,
@@ -1726,8 +1722,6 @@
 	/* .vbus_session		= musb_gadget_vbus_session, */
 	.vbus_draw		= musb_gadget_vbus_draw,
 	.pullup			= musb_gadget_pullup,
-	.start			= musb_gadget_start,
-	.stop			= musb_gadget_stop,
 };
 
 /* ----------------------------------------------------------------------- */
@@ -1852,16 +1846,7 @@
 	if (status != 0) {
 		put_device(&musb->g.dev);
 		the_gadget = NULL;
-		return status;
 	}
-	status = usb_add_gadget_udc(musb->controller, &musb->g);
-	if (status)
-		goto err;
-
-	return 0;
-err:
-	device_unregister(&musb->g.dev);
-	the_gadget = NULL;
 	return status;
 }
 
@@ -1870,7 +1855,6 @@
 	if (musb != the_gadget)
 		return;
 
-	usb_del_gadget_udc(&musb->g);
 	device_unregister(&musb->g.dev);
 	the_gadget = NULL;
 }
@@ -1887,7 +1871,7 @@
  * @param bind the driver's bind function
  * @return <0 if error, 0 if everything is fine
  */
-static int musb_gadget_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 		int (*bind)(struct usb_gadget *))
 {
 	struct musb		*musb = the_gadget;
@@ -1989,6 +1973,7 @@
 err0:
 	return retval;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
 {
@@ -2038,7 +2023,7 @@
  *
  * @param driver the gadget driver to unregister
  */
-static int musb_gadget_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct musb	*musb = the_gadget;
 	unsigned long	flags;
@@ -2097,6 +2082,8 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
 
 /* ----------------------------------------------------------------------- */
 
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 486d129..547486c 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -1179,7 +1179,7 @@
  *
  */
 struct usbhsg_gpriv *the_controller;
-static int usbhsg_gadget_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 			    int (*bind)(struct usb_gadget *))
 {
 	struct usbhsg_gpriv *gpriv = the_controller;
@@ -1229,8 +1229,9 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
-static int usbhsg_gadget_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
 	struct usbhsg_gpriv *gpriv = the_controller;
 	struct usbhs_priv *priv;
@@ -1259,6 +1260,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
 
 /*
  *		usb gadget ops
@@ -1273,8 +1275,6 @@
 
 static struct usb_gadget_ops usbhsg_gadget_ops = {
 	.get_frame		= usbhsg_get_frame,
-	.start			= usbhsg_gadget_start,
-	.stop			= usbhsg_gadget_stop,
 };
 
 static int usbhsg_start(struct usbhs_priv *priv)
@@ -1294,7 +1294,6 @@
 	struct device *dev = usbhs_priv_to_dev(priv);
 	int pipe_size = usbhs_get_dparam(priv, pipe_size);
 	int i;
-	int ret;
 
 	gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL);
 	if (!gpriv) {
@@ -1305,7 +1304,6 @@
 	uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL);
 	if (!uep) {
 		dev_err(dev, "Could not allocate ep\n");
-		ret = -ENOMEM;
 		goto usbhs_mod_gadget_probe_err_gpriv;
 	}
 
@@ -1368,28 +1366,20 @@
 
 	the_controller = gpriv;
 
-	ret = usb_add_gadget_udc(dev, &gpriv->gadget);
-	if (ret)
-		goto err_add_udc;
-
-
 	dev_info(dev, "gadget probed\n");
 
 	return 0;
-err_add_udc:
-	kfree(gpriv->uep);
 
 usbhs_mod_gadget_probe_err_gpriv:
 	kfree(gpriv);
 
-	return ret;
+	return -ENOMEM;
 }
 
 void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
 {
 	struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
 
-	usb_del_gadget_udc(&gpriv->gadget);
 	kfree(gpriv->uep);
 	kfree(gpriv);
 }