Merge branch 'v3.5-for-usb' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into usb-next
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index 7c22a532..6ae9fec 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -135,6 +135,17 @@
 		for the device and attempt to bind to it.  For example:
 		# echo "8086 10f5" > /sys/bus/usb/drivers/foo/new_id
 
+		Reading from this file will list all dynamically added
+		device IDs in the same format, with one entry per
+		line. For example:
+		# cat /sys/bus/usb/drivers/foo/new_id
+		8086 10f5
+		dead beef 06
+		f00d cafe
+
+		The list will be truncated at PAGE_SIZE bytes due to
+		sysfs restrictions.
+
 What:		/sys/bus/usb-serial/drivers/.../new_id
 Date:		October 2011
 Contact:	linux-usb@vger.kernel.org
@@ -157,6 +168,10 @@
 		match the driver to the device.  For example:
 		# echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id
 
+		Reading from this file will list the dynamically added
+		device IDs, exactly like reading from the entry
+		"/sys/bus/usb/drivers/.../new_id"
+
 What:		/sys/bus/usb/device/.../avoid_reset_quirk
 Date:		December 2009
 Contact:	Oliver Neukum <oliver@neukum.org>
diff --git a/Documentation/devicetree/bindings/usb/isp1301.txt b/Documentation/devicetree/bindings/usb/isp1301.txt
new file mode 100644
index 0000000..5405d99
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/isp1301.txt
@@ -0,0 +1,25 @@
+* NXP ISP1301 USB transceiver
+
+Required properties:
+- compatible: must be "nxp,isp1301"
+- reg: I2C address of the ISP1301 device
+
+Optional properties of devices using ISP1301:
+- transceiver: phandle of isp1301 - this helps the ISP1301 driver to find the
+               ISP1301 instance associated with the respective USB driver
+
+Example:
+
+	isp1301: usb-transceiver@2c {
+		compatible = "nxp,isp1301";
+		reg = <0x2c>;
+	};
+
+	usbd@31020000 {
+		compatible = "nxp,lpc3220-udc";
+		reg = <0x31020000 0x300>;
+		interrupt-parent = <&mic>;
+		interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+		transceiver = <&isp1301>;
+		status = "okay";
+	};
diff --git a/Documentation/devicetree/bindings/usb/lpc32xx-udc.txt b/Documentation/devicetree/bindings/usb/lpc32xx-udc.txt
new file mode 100644
index 0000000..29f12a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/lpc32xx-udc.txt
@@ -0,0 +1,28 @@
+* NXP LPC32xx SoC USB Device Controller (UDC)
+
+Required properties:
+- compatible: Must be "nxp,lpc3220-udc"
+- reg: Physical base address of the controller and length of memory mapped
+  region.
+- interrupts: The USB interrupts:
+              * USB Device Low Priority Interrupt
+              * USB Device High Priority Interrupt
+              * USB Device DMA Interrupt
+              * External USB Transceiver Interrupt (OTG ATX)
+- transceiver: phandle of the associated ISP1301 device - this is necessary for
+               the UDC controller for connecting to the USB physical layer
+
+Example:
+
+	isp1301: usb-transceiver@2c {
+		compatible = "nxp,isp1301";
+		reg = <0x2c>;
+	};
+
+	usbd@31020000 {
+		compatible = "nxp,lpc3220-udc";
+		reg = <0x31020000 0x300>;
+		interrupt-parent = <&mic>;
+		interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+		transceiver = <&isp1301>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/ohci-nxp.txt b/Documentation/devicetree/bindings/usb/ohci-nxp.txt
new file mode 100644
index 0000000..71e28c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ohci-nxp.txt
@@ -0,0 +1,24 @@
+* OHCI controller, NXP ohci-nxp variant
+
+Required properties:
+- compatible: must be "nxp,ohci-nxp"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: The OHCI interrupt
+- transceiver: phandle of the associated ISP1301 device - this is necessary for
+               the UDC controller for connecting to the USB physical layer
+
+Example (LPC32xx):
+
+	isp1301: usb-transceiver@2c {
+		compatible = "nxp,isp1301";
+		reg = <0x2c>;
+	};
+
+	ohci@31020000 {
+		compatible = "nxp,ohci-nxp";
+		reg = <0x31020000 0x300>;
+		interrupt-parent = <&mic>;
+		interrupts = <0x3b 0>;
+		transceiver = <&isp1301>;
+	};
diff --git a/Documentation/devicetree/bindings/usb/spear-usb.txt b/Documentation/devicetree/bindings/usb/spear-usb.txt
new file mode 100644
index 0000000..f8a464a
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/spear-usb.txt
@@ -0,0 +1,39 @@
+ST SPEAr SoC USB controllers:
+-----------------------------
+
+EHCI:
+-----
+
+Required properties:
+- compatible: "st,spear600-ehci"
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the EHCI interrupt
+
+Example:
+
+	ehci@e1800000 {
+		compatible = "st,spear600-ehci", "usb-ehci";
+		reg = <0xe1800000 0x1000>;
+		interrupt-parent = <&vic1>;
+		interrupts = <27>;
+	};
+
+
+OHCI:
+-----
+
+Required properties:
+- compatible: "st,spear600-ohci"
+- interrupt-parent: Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- interrupts: Should contain the OHCI interrupt
+
+Example:
+
+	ohci@e1900000 {
+		compatible = "st,spear600-ohci", "usb-ohci";
+		reg = <0xe1800000 0x1000>;
+		interrupt-parent = <&vic1>;
+		interrupts = <26>;
+	};
diff --git a/Documentation/usb/functionfs.txt b/Documentation/usb/functionfs.txt
new file mode 100644
index 0000000..eaaaea0
--- /dev/null
+++ b/Documentation/usb/functionfs.txt
@@ -0,0 +1,67 @@
+*How FunctionFS works*
+
+From kernel point of view it is just a composite function with some
+unique behaviour.  It may be added to an USB configuration only after
+the user space driver has registered by writing descriptors and
+strings (the user space program has to provide the same information
+that kernel level composite functions provide when they are added to
+the configuration).
+
+This in particular means that the composite initialisation functions
+may not be in init section (ie. may not use the __init tag).
+
+From user space point of view it is a file system which when
+mounted provides an "ep0" file.  User space driver need to
+write descriptors and strings to that file.  It does not need
+to worry about endpoints, interfaces or strings numbers but
+simply provide descriptors such as if the function was the
+only one (endpoints and strings numbers starting from one and
+interface numbers starting from zero).  The FunctionFS changes
+them as needed also handling situation when numbers differ in
+different configurations.
+
+When descriptors and strings are written "ep#" files appear
+(one for each declared endpoint) which handle communication on
+a single endpoint.  Again, FunctionFS takes care of the real
+numbers and changing of the configuration (which means that
+"ep1" file may be really mapped to (say) endpoint 3 (and when
+configuration changes to (say) endpoint 2)).  "ep0" is used
+for receiving events and handling setup requests.
+
+When all files are closed the function disables itself.
+
+What I also want to mention is that the FunctionFS is designed in such
+a way that it is possible to mount it several times so in the end
+a gadget could use several FunctionFS functions. The idea is that
+each FunctionFS instance is identified by the device name used
+when mounting.
+
+One can imagine a gadget that has an Ethernet, MTP and HID interfaces
+where the last two are implemented via FunctionFS.  On user space
+level it would look like this:
+
+$ insmod g_ffs.ko idVendor=<ID> iSerialNumber=<string> functions=mtp,hid
+$ mkdir /dev/ffs-mtp && mount -t functionfs mtp /dev/ffs-mtp
+$ ( cd /dev/ffs-mtp && mtp-daemon ) &
+$ mkdir /dev/ffs-hid && mount -t functionfs hid /dev/ffs-hid
+$ ( cd /dev/ffs-hid && hid-daemon ) &
+
+On kernel level the gadget checks ffs_data->dev_name to identify
+whether it's FunctionFS designed for MTP ("mtp") or HID ("hid").
+
+If no "functions" module parameters is supplied, the driver accepts
+just one function with any name.
+
+When "functions" module parameter is supplied, only functions
+with listed names are accepted. In particular, if the "functions"
+parameter's value is just a one-element list, then the behaviour
+is similar to when there is no "functions" at all; however,
+only a function with the specified name is accepted.
+
+The gadget is registered only after all the declared function
+filesystems have been mounted and USB descriptors of all functions
+have been written to their ep0's.
+
+Conversely, the gadget is unregistered after the first USB function
+closes its endpoints.
+
diff --git a/MAINTAINERS b/MAINTAINERS
index b362709..8741f75 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1809,6 +1809,12 @@
 S:	Maintained
 F:	Documentation/zh_CN/
 
+CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER
+M:	Alexander Shishkin <alexander.shishkin@linux.intel.com>
+L:	linux-usb@vger.kernel.org
+S:	Maintained
+F:	drivers/usb/chipidea/
+
 CISCO VIC ETHERNET NIC DRIVER
 M:	Christian Benvenuti <benve@cisco.com>
 M:	Roopa Prabhu <roprabhu@cisco.com>
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index f74c3b7..a60269d 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -25,6 +25,7 @@
 #include <linux/mmc/host.h>
 #include <linux/fb.h>
 #include <linux/pwm_backlight.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <video/platform_lcd.h>
 #include <media/m5mols.h>
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 620f053..9be8a07 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -23,6 +23,7 @@
 #include <linux/i2c-gpio.h>
 #include <linux/i2c/mcs.h>
 #include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index e20bf58..b9f4d25 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -31,6 +31,7 @@
 #include <linux/spi/spi.h>
 
 #include <linux/i2c/pca953x.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <video/platform_lcd.h>
 
@@ -61,7 +62,6 @@
 #include <plat/sdhci.h>
 #include <plat/gpio-cfg.h>
 #include <plat/s3c64xx-spi.h>
-#include <plat/udc-hs.h>
 
 #include <plat/keypad.h>
 #include <plat/clock.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index ce745e1..ceeb1de4 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -18,6 +18,7 @@
 #include <linux/serial_core.h>
 #include <linux/spi/spi_gpio.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
@@ -33,7 +34,6 @@
 #include <plat/gpio-cfg.h>
 #include <plat/hwmon.h>
 #include <plat/regs-serial.h>
-#include <plat/udc-hs.h>
 #include <plat/usb-control.h>
 #include <plat/sdhci.h>
 #include <plat/ts.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d55bc96..4bc5c74 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -30,6 +30,7 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/pwm_backlight.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #ifdef CONFIG_SMDK6410_WM1190_EV1
 #include <linux/mfd/wm8350/core.h>
@@ -72,7 +73,6 @@
 #include <plat/keypad.h>
 #include <plat/backlight.h>
 #include <plat/regs-fb-v4.h>
-#include <plat/udc-hs.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 5fac4e4..f20a97c 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -27,6 +27,7 @@
 #include <linux/gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/interrupt.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 8b928f9..b728905 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -30,6 +30,7 @@
 #include <linux/mmc/host.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/s3c-hsudc.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <asm/irq.h>
 #include <asm/pmu.h>
@@ -57,7 +58,6 @@
 #include <plat/sdhci.h>
 #include <plat/ts.h>
 #include <plat/udc.h>
-#include <plat/udc-hs.h>
 #include <plat/usb-control.h>
 #include <plat/usb-phy.h>
 #include <plat/regs-iic.h>
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
deleted file mode 100644
index dc90f5e..0000000
--- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C - USB2.0 Highspeed/OtG device block registers
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_H
-#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
-
-#define S3C_HSOTG_REG(x) (x)
-
-#define S3C_GOTGCTL				S3C_HSOTG_REG(0x000)
-#define S3C_GOTGCTL_BSESVLD			(1 << 19)
-#define S3C_GOTGCTL_ASESVLD			(1 << 18)
-#define S3C_GOTGCTL_DBNC_SHORT			(1 << 17)
-#define S3C_GOTGCTL_CONID_B			(1 << 16)
-#define S3C_GOTGCTL_DEVHNPEN			(1 << 11)
-#define S3C_GOTGCTL_HSSETHNPEN			(1 << 10)
-#define S3C_GOTGCTL_HNPREQ			(1 << 9)
-#define S3C_GOTGCTL_HSTNEGSCS			(1 << 8)
-#define S3C_GOTGCTL_SESREQ			(1 << 1)
-#define S3C_GOTGCTL_SESREQSCS			(1 << 0)
-
-#define S3C_GOTGINT				S3C_HSOTG_REG(0x004)
-#define S3C_GOTGINT_DbnceDone			(1 << 19)
-#define S3C_GOTGINT_ADevTOUTChg			(1 << 18)
-#define S3C_GOTGINT_HstNegDet			(1 << 17)
-#define S3C_GOTGINT_HstnegSucStsChng		(1 << 9)
-#define S3C_GOTGINT_SesReqSucStsChng		(1 << 8)
-#define S3C_GOTGINT_SesEndDet			(1 << 2)
-
-#define S3C_GAHBCFG				S3C_HSOTG_REG(0x008)
-#define S3C_GAHBCFG_PTxFEmpLvl			(1 << 8)
-#define S3C_GAHBCFG_NPTxFEmpLvl			(1 << 7)
-#define S3C_GAHBCFG_DMAEn			(1 << 5)
-#define S3C_GAHBCFG_HBstLen_MASK		(0xf << 1)
-#define S3C_GAHBCFG_HBstLen_SHIFT		(1)
-#define S3C_GAHBCFG_HBstLen_Single		(0x0 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr		(0x1 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr4		(0x3 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr8		(0x5 << 1)
-#define S3C_GAHBCFG_HBstLen_Incr16		(0x7 << 1)
-#define S3C_GAHBCFG_GlblIntrEn			(1 << 0)
-
-#define S3C_GUSBCFG				S3C_HSOTG_REG(0x00C)
-#define S3C_GUSBCFG_PHYLPClkSel			(1 << 15)
-#define S3C_GUSBCFG_HNPCap			(1 << 9)
-#define S3C_GUSBCFG_SRPCap			(1 << 8)
-#define S3C_GUSBCFG_PHYIf16			(1 << 3)
-#define S3C_GUSBCFG_TOutCal_MASK		(0x7 << 0)
-#define S3C_GUSBCFG_TOutCal_SHIFT		(0)
-#define S3C_GUSBCFG_TOutCal_LIMIT		(0x7)
-#define S3C_GUSBCFG_TOutCal(_x)			((_x) << 0)
-
-#define S3C_GRSTCTL				S3C_HSOTG_REG(0x010)
-
-#define S3C_GRSTCTL_AHBIdle			(1 << 31)
-#define S3C_GRSTCTL_DMAReq			(1 << 30)
-#define S3C_GRSTCTL_TxFNum_MASK			(0x1f << 6)
-#define S3C_GRSTCTL_TxFNum_SHIFT		(6)
-#define S3C_GRSTCTL_TxFNum_LIMIT		(0x1f)
-#define S3C_GRSTCTL_TxFNum(_x)			((_x) << 6)
-#define S3C_GRSTCTL_TxFFlsh			(1 << 5)
-#define S3C_GRSTCTL_RxFFlsh			(1 << 4)
-#define S3C_GRSTCTL_INTknQFlsh			(1 << 3)
-#define S3C_GRSTCTL_FrmCntrRst			(1 << 2)
-#define S3C_GRSTCTL_HSftRst			(1 << 1)
-#define S3C_GRSTCTL_CSftRst			(1 << 0)
-
-#define S3C_GINTSTS				S3C_HSOTG_REG(0x014)
-#define S3C_GINTMSK				S3C_HSOTG_REG(0x018)
-
-#define S3C_GINTSTS_WkUpInt			(1 << 31)
-#define S3C_GINTSTS_SessReqInt			(1 << 30)
-#define S3C_GINTSTS_DisconnInt			(1 << 29)
-#define S3C_GINTSTS_ConIDStsChng		(1 << 28)
-#define S3C_GINTSTS_PTxFEmp			(1 << 26)
-#define S3C_GINTSTS_HChInt			(1 << 25)
-#define S3C_GINTSTS_PrtInt			(1 << 24)
-#define S3C_GINTSTS_FetSusp			(1 << 22)
-#define S3C_GINTSTS_incompIP			(1 << 21)
-#define S3C_GINTSTS_IncomplSOIN			(1 << 20)
-#define S3C_GINTSTS_OEPInt			(1 << 19)
-#define S3C_GINTSTS_IEPInt			(1 << 18)
-#define S3C_GINTSTS_EPMis			(1 << 17)
-#define S3C_GINTSTS_EOPF			(1 << 15)
-#define S3C_GINTSTS_ISOutDrop			(1 << 14)
-#define S3C_GINTSTS_EnumDone			(1 << 13)
-#define S3C_GINTSTS_USBRst			(1 << 12)
-#define S3C_GINTSTS_USBSusp			(1 << 11)
-#define S3C_GINTSTS_ErlySusp			(1 << 10)
-#define S3C_GINTSTS_GOUTNakEff			(1 << 7)
-#define S3C_GINTSTS_GINNakEff			(1 << 6)
-#define S3C_GINTSTS_NPTxFEmp			(1 << 5)
-#define S3C_GINTSTS_RxFLvl			(1 << 4)
-#define S3C_GINTSTS_SOF				(1 << 3)
-#define S3C_GINTSTS_OTGInt			(1 << 2)
-#define S3C_GINTSTS_ModeMis			(1 << 1)
-#define S3C_GINTSTS_CurMod_Host			(1 << 0)
-
-#define S3C_GRXSTSR				S3C_HSOTG_REG(0x01C)
-#define S3C_GRXSTSP				S3C_HSOTG_REG(0x020)
-
-#define S3C_GRXSTS_FN_MASK			(0x7f << 25)
-#define S3C_GRXSTS_FN_SHIFT			(25)
-
-#define S3C_GRXSTS_PktSts_MASK			(0xf << 17)
-#define S3C_GRXSTS_PktSts_SHIFT			(17)
-#define S3C_GRXSTS_PktSts_GlobalOutNAK		(0x1 << 17)
-#define S3C_GRXSTS_PktSts_OutRX			(0x2 << 17)
-#define S3C_GRXSTS_PktSts_OutDone		(0x3 << 17)
-#define S3C_GRXSTS_PktSts_SetupDone		(0x4 << 17)
-#define S3C_GRXSTS_PktSts_SetupRX		(0x6 << 17)
-
-#define S3C_GRXSTS_DPID_MASK			(0x3 << 15)
-#define S3C_GRXSTS_DPID_SHIFT			(15)
-#define S3C_GRXSTS_ByteCnt_MASK			(0x7ff << 4)
-#define S3C_GRXSTS_ByteCnt_SHIFT		(4)
-#define S3C_GRXSTS_EPNum_MASK			(0xf << 0)
-#define S3C_GRXSTS_EPNum_SHIFT			(0)
-
-#define S3C_GRXFSIZ				S3C_HSOTG_REG(0x024)
-
-#define S3C_GNPTXFSIZ				S3C_HSOTG_REG(0x028)
-
-#define S3C_GNPTXFSIZ_NPTxFDep_MASK		(0xffff << 16)
-#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT		(16)
-#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT		(0xffff)
-#define S3C_GNPTXFSIZ_NPTxFDep(_x)		((_x) << 16)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK		(0xffff << 0)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT		(0)
-#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT		(0xffff)
-#define S3C_GNPTXFSIZ_NPTxFStAddr(_x)		((_x) << 0)
-
-#define S3C_GNPTXSTS				S3C_HSOTG_REG(0x02C)
-
-#define S3C_GNPTXSTS_NPtxQTop_MASK		(0x7f << 24)
-#define S3C_GNPTXSTS_NPtxQTop_SHIFT		(24)
-
-#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK		(0xff << 16)
-#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT	(16)
-#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v)	(((_v) >> 16) & 0xff)
-
-#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK		(0xffff << 0)
-#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT	(0)
-#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v)	(((_v) >> 0) & 0xffff)
-
-
-#define S3C_HPTXFSIZ				S3C_HSOTG_REG(0x100)
-
-#define S3C_DPTXFSIZn(_a)			S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
-
-#define S3C_DPTXFSIZn_DPTxFSize_MASK		(0xffff << 16)
-#define S3C_DPTXFSIZn_DPTxFSize_SHIFT		(16)
-#define S3C_DPTXFSIZn_DPTxFSize_GET(_v)		(((_v) >> 16) & 0xffff)
-#define S3C_DPTXFSIZn_DPTxFSize_LIMIT		(0xffff)
-#define S3C_DPTXFSIZn_DPTxFSize(_x)		((_x) << 16)
-
-#define S3C_DPTXFSIZn_DPTxFStAddr_MASK		(0xffff << 0)
-#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT		(0)
-
-/* Device mode registers */
-#define S3C_DCFG				S3C_HSOTG_REG(0x800)
-
-#define S3C_DCFG_EPMisCnt_MASK			(0x1f << 18)
-#define S3C_DCFG_EPMisCnt_SHIFT			(18)
-#define S3C_DCFG_EPMisCnt_LIMIT			(0x1f)
-#define S3C_DCFG_EPMisCnt(_x)			((_x) << 18)
-
-#define S3C_DCFG_PerFrInt_MASK			(0x3 << 11)
-#define S3C_DCFG_PerFrInt_SHIFT			(11)
-#define S3C_DCFG_PerFrInt_LIMIT			(0x3)
-#define S3C_DCFG_PerFrInt(_x)			((_x) << 11)
-
-#define S3C_DCFG_DevAddr_MASK			(0x7f << 4)
-#define S3C_DCFG_DevAddr_SHIFT			(4)
-#define S3C_DCFG_DevAddr_LIMIT			(0x7f)
-#define S3C_DCFG_DevAddr(_x)			((_x) << 4)
-
-#define S3C_DCFG_NZStsOUTHShk			(1 << 2)
-
-#define S3C_DCFG_DevSpd_MASK			(0x3 << 0)
-#define S3C_DCFG_DevSpd_SHIFT			(0)
-#define S3C_DCFG_DevSpd_HS			(0x0 << 0)
-#define S3C_DCFG_DevSpd_FS			(0x1 << 0)
-#define S3C_DCFG_DevSpd_LS			(0x2 << 0)
-#define S3C_DCFG_DevSpd_FS48			(0x3 << 0)
-
-#define S3C_DCTL				S3C_HSOTG_REG(0x804)
-
-#define S3C_DCTL_PWROnPrgDone			(1 << 11)
-#define S3C_DCTL_CGOUTNak			(1 << 10)
-#define S3C_DCTL_SGOUTNak			(1 << 9)
-#define S3C_DCTL_CGNPInNAK			(1 << 8)
-#define S3C_DCTL_SGNPInNAK			(1 << 7)
-#define S3C_DCTL_TstCtl_MASK			(0x7 << 4)
-#define S3C_DCTL_TstCtl_SHIFT			(4)
-#define S3C_DCTL_GOUTNakSts			(1 << 3)
-#define S3C_DCTL_GNPINNakSts			(1 << 2)
-#define S3C_DCTL_SftDiscon			(1 << 1)
-#define S3C_DCTL_RmtWkUpSig			(1 << 0)
-
-#define S3C_DSTS				S3C_HSOTG_REG(0x808)
-
-#define S3C_DSTS_SOFFN_MASK			(0x3fff << 8)
-#define S3C_DSTS_SOFFN_SHIFT			(8)
-#define S3C_DSTS_SOFFN_LIMIT			(0x3fff)
-#define S3C_DSTS_SOFFN(_x)			((_x) << 8)
-#define S3C_DSTS_ErraticErr			(1 << 3)
-#define S3C_DSTS_EnumSpd_MASK			(0x3 << 1)
-#define S3C_DSTS_EnumSpd_SHIFT			(1)
-#define S3C_DSTS_EnumSpd_HS			(0x0 << 1)
-#define S3C_DSTS_EnumSpd_FS			(0x1 << 1)
-#define S3C_DSTS_EnumSpd_LS			(0x2 << 1)
-#define S3C_DSTS_EnumSpd_FS48			(0x3 << 1)
-
-#define S3C_DSTS_SuspSts			(1 << 0)
-
-#define S3C_DIEPMSK				S3C_HSOTG_REG(0x810)
-
-#define S3C_DIEPMSK_TxFIFOEmpty			(1 << 7)
-#define S3C_DIEPMSK_INEPNakEffMsk		(1 << 6)
-#define S3C_DIEPMSK_INTknEPMisMsk		(1 << 5)
-#define S3C_DIEPMSK_INTknTXFEmpMsk		(1 << 4)
-#define S3C_DIEPMSK_TimeOUTMsk			(1 << 3)
-#define S3C_DIEPMSK_AHBErrMsk			(1 << 2)
-#define S3C_DIEPMSK_EPDisbldMsk			(1 << 1)
-#define S3C_DIEPMSK_XferComplMsk		(1 << 0)
-
-#define S3C_DOEPMSK				S3C_HSOTG_REG(0x814)
-
-#define S3C_DOEPMSK_Back2BackSetup		(1 << 6)
-#define S3C_DOEPMSK_OUTTknEPdisMsk		(1 << 4)
-#define S3C_DOEPMSK_SetupMsk			(1 << 3)
-#define S3C_DOEPMSK_AHBErrMsk			(1 << 2)
-#define S3C_DOEPMSK_EPDisbldMsk			(1 << 1)
-#define S3C_DOEPMSK_XferComplMsk		(1 << 0)
-
-#define S3C_DAINT				S3C_HSOTG_REG(0x818)
-#define S3C_DAINTMSK				S3C_HSOTG_REG(0x81C)
-
-#define S3C_DAINT_OutEP_SHIFT			(16)
-#define S3C_DAINT_OutEP(x)			(1 << ((x) + 16))
-#define S3C_DAINT_InEP(x)			(1 << (x))
-
-#define S3C_DTKNQR1				S3C_HSOTG_REG(0x820)
-#define S3C_DTKNQR2				S3C_HSOTG_REG(0x824)
-#define S3C_DTKNQR3				S3C_HSOTG_REG(0x830)
-#define S3C_DTKNQR4				S3C_HSOTG_REG(0x834)
-
-#define S3C_DVBUSDIS				S3C_HSOTG_REG(0x828)
-#define S3C_DVBUSPULSE				S3C_HSOTG_REG(0x82C)
-
-#define S3C_DIEPCTL0				S3C_HSOTG_REG(0x900)
-#define S3C_DOEPCTL0				S3C_HSOTG_REG(0xB00)
-#define S3C_DIEPCTL(_a)				S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
-#define S3C_DOEPCTL(_a)				S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
-
-/* EP0 specialness:
- * bits[29..28] - reserved (no SetD0PID, SetD1PID)
- * bits[25..22] - should always be zero, this isn't a periodic endpoint
- * bits[10..0] - MPS setting differenct for EP0
-*/
-#define S3C_D0EPCTL_MPS_MASK			(0x3 << 0)
-#define S3C_D0EPCTL_MPS_SHIFT			(0)
-#define S3C_D0EPCTL_MPS_64			(0x0 << 0)
-#define S3C_D0EPCTL_MPS_32			(0x1 << 0)
-#define S3C_D0EPCTL_MPS_16			(0x2 << 0)
-#define S3C_D0EPCTL_MPS_8			(0x3 << 0)
-
-#define S3C_DxEPCTL_EPEna			(1 << 31)
-#define S3C_DxEPCTL_EPDis			(1 << 30)
-#define S3C_DxEPCTL_SetD1PID			(1 << 29)
-#define S3C_DxEPCTL_SetOddFr			(1 << 29)
-#define S3C_DxEPCTL_SetD0PID			(1 << 28)
-#define S3C_DxEPCTL_SetEvenFr			(1 << 28)
-#define S3C_DxEPCTL_SNAK			(1 << 27)
-#define S3C_DxEPCTL_CNAK			(1 << 26)
-#define S3C_DxEPCTL_TxFNum_MASK			(0xf << 22)
-#define S3C_DxEPCTL_TxFNum_SHIFT		(22)
-#define S3C_DxEPCTL_TxFNum_LIMIT		(0xf)
-#define S3C_DxEPCTL_TxFNum(_x)			((_x) << 22)
-
-#define S3C_DxEPCTL_Stall			(1 << 21)
-#define S3C_DxEPCTL_Snp				(1 << 20)
-#define S3C_DxEPCTL_EPType_MASK			(0x3 << 18)
-#define S3C_DxEPCTL_EPType_SHIFT		(18)
-#define S3C_DxEPCTL_EPType_Control		(0x0 << 18)
-#define S3C_DxEPCTL_EPType_Iso			(0x1 << 18)
-#define S3C_DxEPCTL_EPType_Bulk			(0x2 << 18)
-#define S3C_DxEPCTL_EPType_Intterupt		(0x3 << 18)
-
-#define S3C_DxEPCTL_NAKsts			(1 << 17)
-#define S3C_DxEPCTL_DPID			(1 << 16)
-#define S3C_DxEPCTL_EOFrNum			(1 << 16)
-#define S3C_DxEPCTL_USBActEp			(1 << 15)
-#define S3C_DxEPCTL_NextEp_MASK			(0xf << 11)
-#define S3C_DxEPCTL_NextEp_SHIFT		(11)
-#define S3C_DxEPCTL_NextEp_LIMIT		(0xf)
-#define S3C_DxEPCTL_NextEp(_x)			((_x) << 11)
-
-#define S3C_DxEPCTL_MPS_MASK			(0x7ff << 0)
-#define S3C_DxEPCTL_MPS_SHIFT			(0)
-#define S3C_DxEPCTL_MPS_LIMIT			(0x7ff)
-#define S3C_DxEPCTL_MPS(_x)			((_x) << 0)
-
-#define S3C_DIEPINT(_a)				S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
-#define S3C_DOEPINT(_a)				S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
-
-#define S3C_DxEPINT_INEPNakEff			(1 << 6)
-#define S3C_DxEPINT_Back2BackSetup		(1 << 6)
-#define S3C_DxEPINT_INTknEPMis			(1 << 5)
-#define S3C_DxEPINT_INTknTXFEmp			(1 << 4)
-#define S3C_DxEPINT_OUTTknEPdis			(1 << 4)
-#define S3C_DxEPINT_Timeout			(1 << 3)
-#define S3C_DxEPINT_Setup			(1 << 3)
-#define S3C_DxEPINT_AHBErr			(1 << 2)
-#define S3C_DxEPINT_EPDisbld			(1 << 1)
-#define S3C_DxEPINT_XferCompl			(1 << 0)
-
-#define S3C_DIEPTSIZ0				S3C_HSOTG_REG(0x910)
-
-#define S3C_DIEPTSIZ0_PktCnt_MASK		(0x3 << 19)
-#define S3C_DIEPTSIZ0_PktCnt_SHIFT		(19)
-#define S3C_DIEPTSIZ0_PktCnt_LIMIT		(0x3)
-#define S3C_DIEPTSIZ0_PktCnt(_x)		((_x) << 19)
-
-#define S3C_DIEPTSIZ0_XferSize_MASK		(0x7f << 0)
-#define S3C_DIEPTSIZ0_XferSize_SHIFT		(0)
-#define S3C_DIEPTSIZ0_XferSize_LIMIT		(0x7f)
-#define S3C_DIEPTSIZ0_XferSize(_x)		((_x) << 0)
-
-
-#define DOEPTSIZ0				S3C_HSOTG_REG(0xB10)
-#define S3C_DOEPTSIZ0_SUPCnt_MASK		(0x3 << 29)
-#define S3C_DOEPTSIZ0_SUPCnt_SHIFT		(29)
-#define S3C_DOEPTSIZ0_SUPCnt_LIMIT		(0x3)
-#define S3C_DOEPTSIZ0_SUPCnt(_x)		((_x) << 29)
-
-#define S3C_DOEPTSIZ0_PktCnt			(1 << 19)
-#define S3C_DOEPTSIZ0_XferSize_MASK		(0x7f << 0)
-#define S3C_DOEPTSIZ0_XferSize_SHIFT		(0)
-
-#define S3C_DIEPTSIZ(_a)			S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
-#define S3C_DOEPTSIZ(_a)			S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
-
-#define S3C_DxEPTSIZ_MC_MASK			(0x3 << 29)
-#define S3C_DxEPTSIZ_MC_SHIFT			(29)
-#define S3C_DxEPTSIZ_MC_LIMIT			(0x3)
-#define S3C_DxEPTSIZ_MC(_x)			((_x) << 29)
-
-#define S3C_DxEPTSIZ_PktCnt_MASK		(0x3ff << 19)
-#define S3C_DxEPTSIZ_PktCnt_SHIFT		(19)
-#define S3C_DxEPTSIZ_PktCnt_GET(_v)		(((_v) >> 19) & 0x3ff)
-#define S3C_DxEPTSIZ_PktCnt_LIMIT		(0x3ff)
-#define S3C_DxEPTSIZ_PktCnt(_x)			((_x) << 19)
-
-#define S3C_DxEPTSIZ_XferSize_MASK		(0x7ffff << 0)
-#define S3C_DxEPTSIZ_XferSize_SHIFT		(0)
-#define S3C_DxEPTSIZ_XferSize_GET(_v)		(((_v) >> 0) & 0x7ffff)
-#define S3C_DxEPTSIZ_XferSize_LIMIT		(0x7ffff)
-#define S3C_DxEPTSIZ_XferSize(_x)		((_x) << 0)
-
-
-#define S3C_DIEPDMA(_a)				S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
-#define S3C_DOEPDMA(_a)				S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
-#define S3C_DTXFSTS(_a)				S3C_HSOTG_REG(0x918 + ((_a) * 0x20))
-
-#define S3C_EPFIFO(_a)				S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
-
-#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 29a4a5c..1564e09 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -69,6 +69,7 @@
 	up_read(&bus_type_sem);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(register_acpi_bus_type);
 
 static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
 {
@@ -85,6 +86,7 @@
 	up_read(&bus_type_sem);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);
 
 /* Get device's handler per its address under its parent */
 struct acpi_find_child {
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index b002a47..adbbc1c 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -382,3 +382,33 @@
 }
 
 EXPORT_SYMBOL(acpi_evaluate_reference);
+
+acpi_status
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *output;
+
+	status = acpi_evaluate_object(handle, "_PLD", NULL, &buffer);
+
+	if (ACPI_FAILURE(status))
+		return status;
+
+	output = buffer.pointer;
+
+	if (!output || output->type != ACPI_TYPE_PACKAGE
+	    || !output->package.count
+	    || output->package.elements[0].type != ACPI_TYPE_BUFFER
+	    || output->package.elements[0].buffer.length > sizeof(*pld)) {
+		status = AE_TYPE;
+		goto out;
+	}
+
+	memcpy(pld, output->package.elements[0].buffer.pointer,
+	       output->package.elements[0].buffer.length);
+out:
+	kfree(buffer.pointer);
+	return status;
+}
+EXPORT_SYMBOL(acpi_get_physical_device_location);
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index f94cccc..3bea7fe 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -297,6 +297,23 @@
 			return -EILSEQ;
 	}
 
+	/* First Slave Address Descriptor should be port 0:
+	 * the main register space for the core
+	 */
+	tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
+	if (tmp <= 0) {
+		/* Try again to see if it is a bridge */
+		tmp = bcma_erom_get_addr_desc(bus, eromptr,
+					      SCAN_ADDR_TYPE_BRIDGE, 0);
+		if (tmp <= 0) {
+			return -EILSEQ;
+		} else {
+			pr_info("Bridge found\n");
+			return -ENXIO;
+		}
+	}
+	core->addr = tmp;
+
 	/* get & parse slave ports */
 	for (i = 0; i < ports[1]; i++) {
 		for (j = 0; ; j++) {
@@ -309,7 +326,7 @@
 				break;
 			} else {
 				if (i == 0 && j == 0)
-					core->addr = tmp;
+					core->addr1 = tmp;
 			}
 		}
 	}
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 5bf91db..340d6ae 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -203,7 +203,7 @@
 		return 0;
 
 	if ((kicked = (usbhid->outhead != usbhid->outtail))) {
-		dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+		hid_dbg(hid, "Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
 
 		r = usb_autopm_get_interface_async(usbhid->intf);
 		if (r < 0)
@@ -230,7 +230,7 @@
 		return 0;
 
 	if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
-		dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+		hid_dbg(hid, "Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
 
 		r = usb_autopm_get_interface_async(usbhid->intf);
 		if (r < 0)
@@ -399,6 +399,16 @@
  * Output interrupt completion handler.
  */
 
+static int irq_out_pump_restart(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+
+	if (usbhid->outhead != usbhid->outtail)
+		return hid_submit_out(hid);
+	else
+		return -1;
+}
+
 static void hid_irq_out(struct urb *urb)
 {
 	struct hid_device *hid = urb->context;
@@ -428,7 +438,7 @@
 	else
 		usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
 
-	if (usbhid->outhead != usbhid->outtail && !hid_submit_out(hid)) {
+	if (!irq_out_pump_restart(hid)) {
 		/* Successfully submitted next urb in queue */
 		spin_unlock_irqrestore(&usbhid->lock, flags);
 		return;
@@ -443,6 +453,15 @@
 /*
  * Control pipe completion handler.
  */
+static int ctrl_pump_restart(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+
+	if (usbhid->ctrlhead != usbhid->ctrltail)
+		return hid_submit_ctrl(hid);
+	else
+		return -1;
+}
 
 static void hid_ctrl(struct urb *urb)
 {
@@ -476,7 +495,7 @@
 	else
 		usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
-	if (usbhid->ctrlhead != usbhid->ctrltail && !hid_submit_ctrl(hid)) {
+	if (!ctrl_pump_restart(hid)) {
 		/* Successfully submitted next urb in queue */
 		spin_unlock(&usbhid->lock);
 		return;
@@ -535,11 +554,27 @@
 			 * the queue is known to run
 			 * but an earlier request may be stuck
 			 * we may need to time out
-			 * no race because this is called under
+			 * no race because the URB is blocked under
 			 * spinlock
 			 */
-			if (time_after(jiffies, usbhid->last_out + HZ * 5))
+			if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
+				usb_block_urb(usbhid->urbout);
+				/* drop lock to not deadlock if the callback is called */
+				spin_unlock(&usbhid->lock);
 				usb_unlink_urb(usbhid->urbout);
+				spin_lock(&usbhid->lock);
+				usb_unblock_urb(usbhid->urbout);
+				/*
+				 * if the unlinking has already completed
+				 * the pump will have been stopped
+				 * it must be restarted now
+				 */
+				if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
+					if (!irq_out_pump_restart(hid))
+						set_bit(HID_OUT_RUNNING, &usbhid->iofl);
+
+
+			}
 		}
 		return;
 	}
@@ -583,11 +618,25 @@
 		 * the queue is known to run
 		 * but an earlier request may be stuck
 		 * we may need to time out
-		 * no race because this is called under
+		 * no race because the URB is blocked under
 		 * spinlock
 		 */
-		if (time_after(jiffies, usbhid->last_ctrl + HZ * 5))
+		if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
+			usb_block_urb(usbhid->urbctrl);
+			/* drop lock to not deadlock if the callback is called */
+			spin_unlock(&usbhid->lock);
 			usb_unlink_urb(usbhid->urbctrl);
+			spin_lock(&usbhid->lock);
+			usb_unblock_urb(usbhid->urbctrl);
+			/*
+			 * if the unlinking has already completed
+			 * the pump will have been stopped
+			 * it must be restarted now
+			 */
+			if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+				if (!ctrl_pump_restart(hid))
+					set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+		}
 	}
 }
 
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index 0f6be45..bf16d72 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -92,9 +92,10 @@
 resubmit:
 	status = usb_submit_urb (urb, GFP_ATOMIC);
 	if (status)
-		err ("can't resubmit intr, %s-%s/input0, status %d",
-				mouse->usbdev->bus->bus_name,
-				mouse->usbdev->devpath, status);
+		dev_err(&mouse->usbdev->dev,
+			"can't resubmit intr, %s-%s/input0, status %d\n",
+			mouse->usbdev->bus->bus_name,
+			mouse->usbdev->devpath, status);
 }
 
 static int usb_mouse_open(struct input_dev *dev)
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 405febd..daeeb4c 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -317,7 +317,8 @@
 			break;
 
 	if (i == 20) { /* 5 seconds */
-		err("Timeout waiting for response from device.");
+		dev_err(&input_dev->dev,
+			"Timeout waiting for response from device.\n");
 		error = -ENODEV;
 		goto fail;
 	}
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index a17b500..08f98f2 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -257,7 +257,8 @@
 
 		status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC);
 		if (status) {
-			err("usb_submit_urb failed %d", status);
+			dev_err(&iforce->intf->dev,
+				"usb_submit_urb failed %d\n", status);
 			return -1;
 		}
 
@@ -265,12 +266,14 @@
 			iforce->ctrl->status != -EINPROGRESS, HZ);
 
 		if (iforce->ctrl->status) {
-			dbg("iforce->ctrl->status = %d", iforce->ctrl->status);
+			dev_dbg(&iforce->intf->dev,
+				"iforce->ctrl->status = %d\n",
+				iforce->ctrl->status);
 			usb_unlink_urb(iforce->ctrl);
 			return -1;
 		}
 #else
-		dbg("iforce_get_id_packet: iforce->bus = USB!");
+		printk(KERN_DEBUG "iforce_get_id_packet: iforce->bus = USB!\n");
 #endif
 		}
 		break;
@@ -289,12 +292,15 @@
 			return -1;
 		}
 #else
-		err("iforce_get_id_packet: iforce->bus = SERIO!");
+		dev_err(&iforce->dev->dev,
+			"iforce_get_id_packet: iforce->bus = SERIO!\n");
 #endif
 		break;
 
 	default:
-		err("iforce_get_id_packet: iforce->bus = %d", iforce->bus);
+		dev_err(&iforce->dev->dev,
+			"iforce_get_id_packet: iforce->bus = %d\n",
+			iforce->bus);
 		break;
 	}
 
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 6c96631..d96aa27 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -64,7 +64,7 @@
 
 	if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
 		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
-		dev_warn(&iforce->dev->dev, "usb_submit_urb failed %d\n", n);
+		dev_warn(&iforce->intf->dev, "usb_submit_urb failed %d\n", n);
 	}
 
 	/* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
@@ -76,6 +76,7 @@
 static void iforce_usb_irq(struct urb *urb)
 {
 	struct iforce *iforce = urb->context;
+	struct device *dev = &iforce->intf->dev;
 	int status;
 
 	switch (urb->status) {
@@ -86,11 +87,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, urb->status);
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 	default:
-		dbg("%s - urb has status of: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - urb has status of: %d\n",
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -100,8 +102,8 @@
 exit:
 	status = usb_submit_urb (urb, GFP_ATOMIC);
 	if (status)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __func__, status);
+		dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
+			__func__, status);
 }
 
 static void iforce_usb_out(struct urb *urb)
@@ -110,7 +112,8 @@
 
 	if (urb->status) {
 		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
-		dbg("urb->status %d, exiting", urb->status);
+		dev_dbg(&iforce->intf->dev, "urb->status %d, exiting\n",
+			urb->status);
 		return;
 	}
 
@@ -155,6 +158,7 @@
 
 	iforce->bus = IFORCE_USB;
 	iforce->usbdev = dev;
+	iforce->intf = intf;
 
 	iforce->cr.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE;
 	iforce->cr.wIndex = 0;
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 9f494b7..b1d7d9b 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -115,6 +115,7 @@
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
 	struct usb_device *usbdev;	/* USB transfer */
+	struct usb_interface *intf;
 	struct urb *irq, *out, *ctrl;
 	struct usb_ctrlrequest cr;
 #endif
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index fd7a0d5..ee16fb6 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -252,6 +252,7 @@
 struct usb_xpad {
 	struct input_dev *dev;		/* input device interface */
 	struct usb_device *udev;	/* usb device */
+	struct usb_interface *intf;	/* usb interface */
 
 	int pad_present;
 
@@ -457,6 +458,7 @@
 static void xpad_irq_in(struct urb *urb)
 {
 	struct usb_xpad *xpad = urb->context;
+	struct device *dev = &xpad->intf->dev;
 	int retval, status;
 
 	status = urb->status;
@@ -469,11 +471,11 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
 			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
 			__func__, status);
 		goto exit;
 	}
@@ -492,12 +494,15 @@
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __func__, retval);
+		dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
+			__func__, retval);
 }
 
 static void xpad_bulk_out(struct urb *urb)
 {
+	struct usb_xpad *xpad = urb->context;
+	struct device *dev = &xpad->intf->dev;
+
 	switch (urb->status) {
 	case 0:
 		/* success */
@@ -506,16 +511,20 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		break;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 	}
 }
 
 #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
 static void xpad_irq_out(struct urb *urb)
 {
+	struct usb_xpad *xpad = urb->context;
+	struct device *dev = &xpad->intf->dev;
 	int retval, status;
 
 	status = urb->status;
@@ -529,19 +538,21 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, status);
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, status);
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err("%s - usb_submit_urb failed with result %d",
-		    __func__, retval);
+		dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
+			__func__, retval);
 }
 
 static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
@@ -654,7 +665,8 @@
 			return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
 
 		default:
-			dbg("%s - rumble command sent to unsupported xpad type: %d",
+			dev_dbg(&xpad->dev->dev,
+				"%s - rumble command sent to unsupported xpad type: %d\n",
 				__func__, xpad->xtype);
 			return -1;
 		}
@@ -844,6 +856,7 @@
 	}
 
 	xpad->udev = udev;
+	xpad->intf = intf;
 	xpad->mapping = xpad_device[i].mapping;
 	xpad->xtype = xpad_device[i].xtype;
 
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
index ab86051..082684e 100644
--- a/drivers/input/misc/cm109.c
+++ b/drivers/input/misc/cm109.c
@@ -327,7 +327,9 @@
 
 	error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
 	if (error)
-		err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
+		dev_err(&dev->intf->dev,
+			"%s: usb_submit_urb (urb_ctl) failed %d\n",
+			__func__, error);
 }
 
 /*
@@ -339,7 +341,7 @@
 	const int status = urb->status;
 	int error;
 
-	dev_dbg(&urb->dev->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
+	dev_dbg(&dev->intf->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
 	     dev->irq_data->byte[0],
 	     dev->irq_data->byte[1],
 	     dev->irq_data->byte[2],
@@ -349,7 +351,7 @@
 	if (status) {
 		if (status == -ESHUTDOWN)
 			return;
-		err("%s: urb status %d", __func__, status);
+		dev_err(&dev->intf->dev, "%s: urb status %d\n", __func__, status);
 	}
 
 	/* Special keys */
@@ -396,7 +398,8 @@
 
 		error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
 		if (error)
-			err("%s: usb_submit_urb (urb_ctl) failed %d",
+			dev_err(&dev->intf->dev,
+				"%s: usb_submit_urb (urb_ctl) failed %d\n",
 				__func__, error);
 	}
 
@@ -409,14 +412,14 @@
 	const int status = urb->status;
 	int error;
 
-	dev_dbg(&urb->dev->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
+	dev_dbg(&dev->intf->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
 	     dev->ctl_data->byte[0],
 	     dev->ctl_data->byte[1],
 	     dev->ctl_data->byte[2],
 	     dev->ctl_data->byte[3]);
 
 	if (status)
-		err("%s: urb status %d", __func__, status);
+		dev_err(&dev->intf->dev, "%s: urb status %d\n", __func__, status);
 
 	spin_lock(&dev->ctl_submit_lock);
 
@@ -433,7 +436,8 @@
 			dev->irq_urb_pending = 1;
 			error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC);
 			if (error)
-				err("%s: usb_submit_urb (urb_irq) failed %d",
+				dev_err(&dev->intf->dev,
+					"%s: usb_submit_urb (urb_irq) failed %d\n",
 					__func__, error);
 		}
 	}
@@ -476,7 +480,8 @@
 				dev->ctl_data,
 				USB_PKT_LEN, USB_CTRL_SET_TIMEOUT);
 	if (error < 0 && error != -EINTR)
-		err("%s: usb_control_msg() failed %d", __func__, error);
+		dev_err(&dev->intf->dev, "%s: usb_control_msg() failed %d\n",
+			__func__, error);
 }
 
 static void cm109_stop_traffic(struct cm109_dev *dev)
@@ -518,8 +523,8 @@
 
 	error = usb_autopm_get_interface(dev->intf);
 	if (error < 0) {
-		err("%s - cannot autoresume, result %d",
-		    __func__, error);
+		dev_err(&idev->dev, "%s - cannot autoresume, result %d\n",
+			__func__, error);
 		return error;
 	}
 
@@ -537,7 +542,8 @@
 
 	error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL);
 	if (error)
-		err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
+		dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n",
+			__func__, error);
 	else
 		dev->open = 1;
 
@@ -573,7 +579,7 @@
 {
 	struct cm109_dev *dev = input_get_drvdata(idev);
 
-	dev_dbg(&dev->udev->dev,
+	dev_dbg(&dev->intf->dev,
 		"input_ev: type=%u code=%u value=%d\n", type, code, value);
 
 	if (type != EV_SND)
@@ -710,7 +716,8 @@
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 	ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 	if (ret != USB_PKT_LEN)
-		err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
+		dev_err(&intf->dev, "invalid payload size %d, expected %d\n",
+			ret, USB_PKT_LEN);
 
 	/* initialise irq urb */
 	usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data,
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index d99151a..290fa5f 100644
--- a/drivers/input/misc/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
@@ -157,7 +157,7 @@
 	 * though so it's not too big a deal
 	 */
 	if (dev->data.pos >= dev->data.len) {
-		dev_dbg(&dev->udev->dev,
+		dev_dbg(&dev->interface->dev,
 			"%s - Error ran out of data. pos: %d, len: %d\n",
 			__func__, dev->data.pos, dev->data.len);
 		return -1;
@@ -267,7 +267,9 @@
 				remote->data.tester = remote->data.tester >> 6;
 				remote->data.bits_left -= 6;
 			} else {
-				err("%s - Unknown sequence found in system data.\n", __func__);
+				dev_err(&remote->interface->dev,
+					"%s - Unknown sequence found in system data.\n",
+					__func__);
 				remote->stage = 0;
 				return;
 			}
@@ -286,7 +288,9 @@
 				remote->data.tester = remote->data.tester >> 6;
 				remote->data.bits_left -= 6;
 			} else {
-				err("%s - Unknown sequence found in button data.\n", __func__);
+				dev_err(&remote->interface->dev,
+					"%s - Unknown sequence found in button data.\n",
+					__func__);
 				remote->stage = 0;
 				return;
 			}
@@ -302,7 +306,9 @@
 			remote->data.tester = remote->data.tester >> 6;
 			remote->data.bits_left -= 6;
 		} else {
-			err("%s - Error in message, invalid toggle.\n", __func__);
+			dev_err(&remote->interface->dev,
+				"%s - Error in message, invalid toggle.\n",
+				__func__);
 			remote->stage = 0;
 			return;
 		}
@@ -312,10 +318,11 @@
 			remote->data.tester = remote->data.tester >> 5;
 			remote->data.bits_left -= 5;
 		} else {
-			err("Bad message received, no stop bit found.\n");
+			dev_err(&remote->interface->dev,
+				"Bad message received, no stop bit found.\n");
 		}
 
-		dev_dbg(&remote->udev->dev,
+		dev_dbg(&remote->interface->dev,
 			"%s found valid message: system: %d, button: %d, toggle: %d\n",
 			__func__, message.system, message.button, message.toggle);
 
@@ -397,7 +404,9 @@
 resubmit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err ("%s - usb_submit_urb failed with result: %d", __func__, retval);
+		dev_err(&dev->interface->dev,
+			"%s - usb_submit_urb failed with result: %d\n",
+			__func__, retval);
 }
 
 static int keyspan_open(struct input_dev *dev)
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index 538f704..49c0c3e 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -65,6 +65,7 @@
 	struct urb *irq, *config;
 	struct usb_ctrlrequest *configcr;
 	struct usb_device *udev;
+	struct usb_interface *intf;
 	struct input_dev *input;
 	spinlock_t lock;
 	int static_brightness;
@@ -85,6 +86,7 @@
 static void powermate_irq(struct urb *urb)
 {
 	struct powermate_device *pm = urb->context;
+	struct device *dev = &pm->intf->dev;
 	int retval;
 
 	switch (urb->status) {
@@ -95,10 +97,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -110,8 +114,8 @@
 exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __func__, retval);
+		dev_err(dev, "%s - usb_submit_urb failed with result: %d\n",
+			__func__, retval);
 }
 
 /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
@@ -330,6 +334,7 @@
 		goto fail3;
 
 	pm->udev = udev;
+	pm->intf = intf;
 	pm->input = input_dev;
 
 	usb_make_path(udev, pm->phys, sizeof(pm->phys));
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index f4776e7..285a5bd 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -101,6 +101,7 @@
 struct yealink_dev {
 	struct input_dev *idev;		/* input device */
 	struct usb_device *udev;	/* usb device */
+	struct usb_interface *intf;	/* usb interface */
 
 	/* irq input channel */
 	struct yld_ctl_packet	*irq_data;
@@ -428,7 +429,8 @@
 	int ret, status = urb->status;
 
 	if (status)
-		err("%s - urb status %d", __func__, status);
+		dev_err(&yld->intf->dev, "%s - urb status %d\n",
+			__func__, status);
 
 	switch (yld->irq_data->cmd) {
 	case CMD_KEYPRESS:
@@ -437,13 +439,15 @@
 		break;
 
 	case CMD_SCANCODE:
-		dbg("get scancode %x", yld->irq_data->data[0]);
+		dev_dbg(&yld->intf->dev, "get scancode %x\n",
+			yld->irq_data->data[0]);
 
 		report_key(yld, map_p1k_to_key(yld->irq_data->data[0]));
 		break;
 
 	default:
-		err("unexpected response %x", yld->irq_data->cmd);
+		dev_err(&yld->intf->dev, "unexpected response %x\n",
+			yld->irq_data->cmd);
 	}
 
 	yealink_do_idle_tasks(yld);
@@ -451,7 +455,9 @@
 	if (!yld->shutdown) {
 		ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
 		if (ret && ret != -EPERM)
-			err("%s - usb_submit_urb failed %d", __func__, ret);
+			dev_err(&yld->intf->dev,
+				"%s - usb_submit_urb failed %d\n",
+				__func__, ret);
 	}
 }
 
@@ -461,7 +467,8 @@
 	int ret = 0, status = urb->status;
 
 	if (status)
-		err("%s - urb status %d", __func__, status);
+		dev_err(&yld->intf->dev, "%s - urb status %d\n",
+			__func__, status);
 
 	switch (yld->ctl_data->cmd) {
 	case CMD_KEYPRESS:
@@ -479,7 +486,8 @@
 	}
 
 	if (ret && ret != -EPERM)
-		err("%s - usb_submit_urb failed %d", __func__, ret);
+		dev_err(&yld->intf->dev, "%s - usb_submit_urb failed %d\n",
+			__func__, ret);
 }
 
 /*******************************************************************************
@@ -511,7 +519,7 @@
 	struct yealink_dev *yld = input_get_drvdata(dev);
 	int i, ret;
 
-	dbg("%s", __func__);
+	dev_dbg(&yld->intf->dev, "%s\n", __func__);
 
 	/* force updates to device */
 	for (i = 0; i<sizeof(yld->master); i++)
@@ -526,8 +534,9 @@
 	yld->ctl_data->size	= 10;
 	yld->ctl_data->sum	= 0x100-CMD_INIT-10;
 	if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
-		dbg("%s - usb_submit_urb failed with result %d",
-		     __func__, ret);
+		dev_dbg(&yld->intf->dev,
+			"%s - usb_submit_urb failed with result %d\n",
+			__func__, ret);
 		return ret;
 	}
 	return 0;
@@ -876,6 +885,7 @@
 		return -ENOMEM;
 
 	yld->udev = udev;
+	yld->intf = intf;
 
 	yld->idev = input_dev = input_allocate_device();
 	if (!input_dev)
@@ -909,7 +919,8 @@
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 	ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 	if (ret != USB_PKT_LEN)
-		err("invalid payload size %d, expected %zd", ret, USB_PKT_LEN);
+		dev_err(&intf->dev, "invalid payload size %d, expected %zd\n",
+			ret, USB_PKT_LEN);
 
 	/* initialise irq urb */
 	usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 0acbc7d..e42f1fa 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -195,6 +195,7 @@
 struct atp {
 	char			phys[64];
 	struct usb_device	*udev;		/* usb device */
+	struct usb_interface	*intf;		/* usb interface */
 	struct urb		*urb;		/* usb request block */
 	u8			*data;		/* transferred data */
 	struct input_dev	*input;		/* input dev */
@@ -253,8 +254,9 @@
  * packets (Report ID 2). This code changes device mode, so it
  * sends raw sensor reports (Report ID 5).
  */
-static int atp_geyser_init(struct usb_device *udev)
+static int atp_geyser_init(struct atp *dev)
 {
+	struct usb_device *udev = dev->udev;
 	char *data;
 	int size;
 	int i;
@@ -262,7 +264,7 @@
 
 	data = kmalloc(8, GFP_KERNEL);
 	if (!data) {
-		err("Out of memory");
+		dev_err(&dev->intf->dev, "Out of memory\n");
 		return -ENOMEM;
 	}
 
@@ -277,7 +279,7 @@
 		for (i = 0; i < 8; i++)
 			dprintk("appletouch[%d]: %d\n", i, data[i]);
 
-		err("Failed to read mode from device.");
+		dev_err(&dev->intf->dev, "Failed to read mode from device.\n");
 		ret = -EIO;
 		goto out_free;
 	}
@@ -296,7 +298,7 @@
 		for (i = 0; i < 8; i++)
 			dprintk("appletouch[%d]: %d\n", i, data[i]);
 
-		err("Failed to request geyser raw mode");
+		dev_err(&dev->intf->dev, "Failed to request geyser raw mode\n");
 		ret = -EIO;
 		goto out_free;
 	}
@@ -313,16 +315,16 @@
 static void atp_reinit(struct work_struct *work)
 {
 	struct atp *dev = container_of(work, struct atp, work);
-	struct usb_device *udev = dev->udev;
 	int retval;
 
 	dprintk("appletouch: putting appletouch to sleep (reinit)\n");
-	atp_geyser_init(udev);
+	atp_geyser_init(dev);
 
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
 	if (retval)
-		err("atp_reinit: usb_submit_urb failed with error %d",
-		    retval);
+		dev_err(&dev->intf->dev,
+			"atp_reinit: usb_submit_urb failed with error %d\n",
+			retval);
 }
 
 static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
@@ -400,6 +402,7 @@
 static int atp_status_check(struct urb *urb)
 {
 	struct atp *dev = urb->context;
+	struct usb_interface *intf = dev->intf;
 
 	switch (urb->status) {
 	case 0:
@@ -407,8 +410,8 @@
 		break;
 	case -EOVERFLOW:
 		if (!dev->overflow_warned) {
-			printk(KERN_WARNING "appletouch: OVERFLOW with data "
-				"length %d, actual length is %d\n",
+			dev_warn(&intf->dev,
+				"appletouch: OVERFLOW with data length %d, actual length is %d\n",
 				dev->info->datalen, dev->urb->actual_length);
 			dev->overflow_warned = true;
 		}
@@ -416,13 +419,15 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* This urb is terminated, clean up */
-		dbg("atp_complete: urb shutting down with status: %d",
-		    urb->status);
+		dev_dbg(&intf->dev,
+			"atp_complete: urb shutting down with status: %d\n",
+			urb->status);
 		return ATP_URB_STATUS_ERROR_FATAL;
 
 	default:
-		dbg("atp_complete: nonzero urb status received: %d",
-		    urb->status);
+		dev_dbg(&intf->dev,
+			"atp_complete: nonzero urb status received: %d\n",
+			urb->status);
 		return ATP_URB_STATUS_ERROR;
 	}
 
@@ -445,7 +450,8 @@
 	for (i = dev->info->xsensors; i < ATP_XSENSORS; i++) {
 		if (dev->xy_cur[i]) {
 
-			printk(KERN_INFO "appletouch: 17\" model detected.\n");
+			dev_info(&dev->intf->dev,
+				"appletouch: 17\" model detected.\n");
 
 			input_set_abs_params(dev->input, ABS_X, 0,
 					     (dev->info->xsensors_17 - 1) *
@@ -588,8 +594,9 @@
  exit:
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
 	if (retval)
-		err("atp_complete: usb_submit_urb failed with result %d",
-		    retval);
+		dev_err(&dev->intf->dev,
+			"atp_complete: usb_submit_urb failed with result %d\n",
+			retval);
 }
 
 /* Interrupt function for older touchpads: GEYSER3/GEYSER4 */
@@ -722,8 +729,9 @@
  exit:
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
 	if (retval)
-		err("atp_complete: usb_submit_urb failed with result %d",
-		    retval);
+		dev_err(&dev->intf->dev,
+			"atp_complete: usb_submit_urb failed with result %d\n",
+			retval);
 }
 
 static int atp_open(struct input_dev *input)
@@ -748,14 +756,12 @@
 
 static int atp_handle_geyser(struct atp *dev)
 {
-	struct usb_device *udev = dev->udev;
-
 	if (dev->info != &fountain_info) {
 		/* switch to raw sensor mode */
-		if (atp_geyser_init(udev))
+		if (atp_geyser_init(dev))
 			return -EIO;
 
-		printk(KERN_INFO "appletouch: Geyser mode initialized.\n");
+		dev_info(&dev->intf->dev, "Geyser mode initialized.\n");
 	}
 
 	return 0;
@@ -785,7 +791,7 @@
 		}
 	}
 	if (!int_in_endpointAddr) {
-		err("Could not find int-in endpoint");
+		dev_err(&iface->dev, "Could not find int-in endpoint\n");
 		return -EIO;
 	}
 
@@ -793,11 +799,12 @@
 	dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!dev || !input_dev) {
-		err("Out of memory");
+		dev_err(&iface->dev, "Out of memory\n");
 		goto err_free_devs;
 	}
 
 	dev->udev = udev;
+	dev->intf = iface;
 	dev->input = input_dev;
 	dev->info = info;
 	dev->overflow_warned = false;
@@ -886,7 +893,7 @@
 		usb_free_urb(dev->urb);
 		kfree(dev);
 	}
-	printk(KERN_INFO "input: appletouch disconnected\n");
+	dev_info(&iface->dev, "input: appletouch disconnected\n");
 }
 
 static int atp_recover(struct atp *dev)
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index f9e2758..2cf681d 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -584,7 +584,7 @@
 	int retval = 0, size;
 
 	if (!data) {
-		err("bcm5974: out of memory");
+		dev_err(&dev->intf->dev, "out of memory\n");
 		retval = -ENOMEM;
 		goto out;
 	}
@@ -597,7 +597,7 @@
 			BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
 
 	if (size != 8) {
-		err("bcm5974: could not read from device");
+		dev_err(&dev->intf->dev, "could not read from device\n");
 		retval = -EIO;
 		goto out;
 	}
@@ -615,7 +615,7 @@
 			BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
 
 	if (size != 8) {
-		err("bcm5974: could not write to device");
+		dev_err(&dev->intf->dev, "could not write to device\n");
 		retval = -EIO;
 		goto out;
 	}
@@ -631,6 +631,7 @@
 static void bcm5974_irq_button(struct urb *urb)
 {
 	struct bcm5974 *dev = urb->context;
+	struct usb_interface *intf = dev->intf;
 	int error;
 
 	switch (urb->status) {
@@ -640,10 +641,11 @@
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
-		dbg("bcm5974: button urb shutting down: %d", urb->status);
+		dev_dbg(&intf->dev, "button urb shutting down: %d\n",
+			urb->status);
 		return;
 	default:
-		dbg("bcm5974: button urb status: %d", urb->status);
+		dev_dbg(&intf->dev, "button urb status: %d\n", urb->status);
 		goto exit;
 	}
 
@@ -654,12 +656,13 @@
 exit:
 	error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC);
 	if (error)
-		err("bcm5974: button urb failed: %d", error);
+		dev_err(&intf->dev, "button urb failed: %d\n", error);
 }
 
 static void bcm5974_irq_trackpad(struct urb *urb)
 {
 	struct bcm5974 *dev = urb->context;
+	struct usb_interface *intf = dev->intf;
 	int error;
 
 	switch (urb->status) {
@@ -669,10 +672,11 @@
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
-		dbg("bcm5974: trackpad urb shutting down: %d", urb->status);
+		dev_dbg(&intf->dev, "trackpad urb shutting down: %d\n",
+			urb->status);
 		return;
 	default:
-		dbg("bcm5974: trackpad urb status: %d", urb->status);
+		dev_dbg(&intf->dev, "trackpad urb status: %d\n", urb->status);
 		goto exit;
 	}
 
@@ -687,7 +691,7 @@
 exit:
 	error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
 	if (error)
-		err("bcm5974: trackpad urb failed: %d", error);
+		dev_err(&intf->dev, "trackpad urb failed: %d\n", error);
 }
 
 /*
@@ -833,7 +837,7 @@
 	dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!dev || !input_dev) {
-		err("bcm5974: out of memory");
+		dev_err(&iface->dev, "out of memory\n");
 		goto err_free_devs;
 	}
 
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
index f8b0b1d..e062ec8 100644
--- a/drivers/input/tablet/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -51,6 +51,7 @@
 	char name[128];
 	char phys[64];
 	struct usb_device *usbdev;
+	struct usb_interface *intf;
 	struct input_dev *input;
 	struct urb *irq;
 
@@ -63,6 +64,7 @@
 	struct usb_acecad *acecad = urb->context;
 	unsigned char *data = acecad->data;
 	struct input_dev *dev = acecad->input;
+	struct usb_interface *intf = acecad->intf;
 	int prox, status;
 
 	switch (urb->status) {
@@ -73,10 +75,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+		dev_dbg(&intf->dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+		dev_dbg(&intf->dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 		goto resubmit;
 	}
 
@@ -105,8 +109,10 @@
 resubmit:
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status)
-		err("can't resubmit intr, %s-%s/input0, status %d",
-			acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status);
+		dev_err(&intf->dev,
+			"can't resubmit intr, %s-%s/input0, status %d\n",
+			acecad->usbdev->bus->bus_name,
+			acecad->usbdev->devpath, status);
 }
 
 static int usb_acecad_open(struct input_dev *dev)
@@ -168,6 +174,7 @@
 	}
 
 	acecad->usbdev = dev;
+	acecad->intf = intf;
 	acecad->input = input_dev;
 
 	if (dev->manufacturer)
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 205d16a..755a39e 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -309,6 +309,7 @@
 struct aiptek {
 	struct input_dev *inputdev;		/* input device struct           */
 	struct usb_device *usbdev;		/* usb device struct             */
+	struct usb_interface *intf;		/* usb interface struct          */
 	struct urb *urb;			/* urb for incoming reports      */
 	dma_addr_t data_dma;			/* our dma stuffage              */
 	struct aiptek_features features;	/* tablet's array of features    */
@@ -435,6 +436,7 @@
 	struct aiptek *aiptek = urb->context;
 	unsigned char *data = aiptek->data;
 	struct input_dev *inputdev = aiptek->inputdev;
+	struct usb_interface *intf = aiptek->intf;
 	int jitterable = 0;
 	int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
 
@@ -447,13 +449,13 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* This urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, urb->status);
+		dev_dbg(&intf->dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, urb->status);
+		dev_dbg(&intf->dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -785,7 +787,7 @@
 				 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
 		input_sync(inputdev);
 	} else {
-		dbg("Unknown report %d", data[0]);
+		dev_dbg(&intf->dev, "Unknown report %d\n", data[0]);
 	}
 
 	/* Jitter may occur when the user presses a button on the stlyus
@@ -811,8 +813,9 @@
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval != 0) {
-		err("%s - usb_submit_urb failed with result %d",
-		    __func__, retval);
+		dev_err(&intf->dev,
+			"%s - usb_submit_urb failed with result %d\n",
+			__func__, retval);
 	}
 }
 
@@ -912,8 +915,9 @@
 
 	if ((ret =
 	     aiptek_set_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
-		dbg("aiptek_program: failed, tried to send: 0x%02x 0x%02x",
-		    command, data);
+		dev_dbg(&aiptek->intf->dev,
+			"aiptek_program: failed, tried to send: 0x%02x 0x%02x\n",
+			command, data);
 	}
 	kfree(buf);
 	return ret < 0 ? ret : 0;
@@ -947,8 +951,9 @@
 
 	if ((ret =
 	     aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
-		dbg("aiptek_query failed: returned 0x%02x 0x%02x 0x%02x",
-		    buf[0], buf[1], buf[2]);
+		dev_dbg(&aiptek->intf->dev,
+			"aiptek_query failed: returned 0x%02x 0x%02x 0x%02x\n",
+			buf[0], buf[1], buf[2]);
 		ret = -EIO;
 	} else {
 		ret = get_unaligned_le16(buf + 1);
@@ -1726,6 +1731,7 @@
 
 	aiptek->inputdev = inputdev;
 	aiptek->usbdev = usbdev;
+	aiptek->intf = intf;
 	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
 	aiptek->inDelay = 0;
 	aiptek->endDelay = 0;
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index 89a2978..29e01ab 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -2,8 +2,6 @@
 
 GTCO digitizer USB driver
 
-Use the err() and dbg() macros from usb.h for system logging
-
 TO CHECK:  Is pressure done right on report 5?
 
 Copyright (C) 2006  GTCO CalComp
@@ -108,6 +106,7 @@
 
 	struct input_dev  *inputdevice; /* input device struct pointer  */
 	struct usb_device *usbdev; /* the usb device for this device */
+	struct usb_interface *intf;	/* the usb interface for this device */
 	struct urb        *urbinfo;	 /* urb for incoming reports      */
 	dma_addr_t        buf_dma;  /* dma addr of the data buffer*/
 	unsigned char *   buffer;   /* databuffer for reports */
@@ -202,6 +201,7 @@
 static void parse_hid_report_descriptor(struct gtco *device, char * report,
 					int length)
 {
+	struct device *ddev = &device->intf->dev;
 	int   x, i = 0;
 
 	/* Tag primitive vars */
@@ -228,7 +228,7 @@
 	char  indentstr[10] = "";
 
 
-	dbg("======>>>>>>PARSE<<<<<<======");
+	dev_dbg(ddev, "======>>>>>>PARSE<<<<<<======\n");
 
 	/* Walk  this report and pull out the info we need */
 	while (i < length) {
@@ -277,11 +277,11 @@
 				else if (data == 3)
 					strcpy(globtype, "Var|Const");
 
-				dbg("::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits",
-				    globalval[TAG_GLOB_REPORT_ID], inputnum,
-				    globalval[TAG_GLOB_LOG_MAX], globalval[TAG_GLOB_LOG_MAX],
-				    globalval[TAG_GLOB_LOG_MIN], globalval[TAG_GLOB_LOG_MIN],
-				    globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT]);
+				dev_dbg(ddev, "::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits\n",
+					globalval[TAG_GLOB_REPORT_ID], inputnum,
+					globalval[TAG_GLOB_LOG_MAX], globalval[TAG_GLOB_LOG_MAX],
+					globalval[TAG_GLOB_LOG_MIN], globalval[TAG_GLOB_LOG_MIN],
+					globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT]);
 
 
 				/*
@@ -292,7 +292,7 @@
 				 */
 				switch (inputnum) {
 				case 0:  /* X coord */
-					dbg("GER: X Usage: 0x%x", usage);
+					dev_dbg(ddev, "GER: X Usage: 0x%x\n", usage);
 					if (device->max_X == 0) {
 						device->max_X = globalval[TAG_GLOB_LOG_MAX];
 						device->min_X = globalval[TAG_GLOB_LOG_MIN];
@@ -300,7 +300,7 @@
 					break;
 
 				case 1:  /* Y coord */
-					dbg("GER: Y Usage: 0x%x", usage);
+					dev_dbg(ddev, "GER: Y Usage: 0x%x\n", usage);
 					if (device->max_Y == 0) {
 						device->max_Y = globalval[TAG_GLOB_LOG_MAX];
 						device->min_Y = globalval[TAG_GLOB_LOG_MIN];
@@ -350,10 +350,10 @@
 				maintype = 'S';
 
 				if (data == 0) {
-					dbg("======>>>>>> Physical");
+					dev_dbg(ddev, "======>>>>>> Physical\n");
 					strcpy(globtype, "Physical");
 				} else
-					dbg("======>>>>>>");
+					dev_dbg(ddev, "======>>>>>>\n");
 
 				/* Indent the debug output */
 				indent++;
@@ -368,7 +368,7 @@
 				break;
 
 			case TAG_MAIN_COL_END:
-				dbg("<<<<<<======");
+				dev_dbg(ddev, "<<<<<<======\n");
 				maintype = 'E';
 				indent--;
 				for (x = 0; x < indent; x++)
@@ -384,18 +384,18 @@
 
 			switch (size) {
 			case 1:
-				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
-				    indentstr, tag, maintype, size, globtype, data);
+				dev_dbg(ddev, "%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x\n",
+					indentstr, tag, maintype, size, globtype, data);
 				break;
 
 			case 2:
-				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
-				    indentstr, tag, maintype, size, globtype, data16);
+				dev_dbg(ddev, "%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x\n",
+					indentstr, tag, maintype, size, globtype, data16);
 				break;
 
 			case 4:
-				dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
-				    indentstr, tag, maintype, size, globtype, data32);
+				dev_dbg(ddev, "%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x\n",
+					indentstr, tag, maintype, size, globtype, data32);
 				break;
 			}
 			break;
@@ -465,26 +465,26 @@
 			if (tag < TAG_GLOB_MAX) {
 				switch (size) {
 				case 1:
-					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
-					    indentstr, globtype, tag, size, data);
+					dev_dbg(ddev, "%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x\n",
+						indentstr, globtype, tag, size, data);
 					globalval[tag] = data;
 					break;
 
 				case 2:
-					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
-					    indentstr, globtype, tag, size, data16);
+					dev_dbg(ddev, "%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x\n",
+						indentstr, globtype, tag, size, data16);
 					globalval[tag] = data16;
 					break;
 
 				case 4:
-					dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
-					    indentstr, globtype, tag, size, data32);
+					dev_dbg(ddev, "%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x\n",
+						indentstr, globtype, tag, size, data32);
 					globalval[tag] = data32;
 					break;
 				}
 			} else {
-				dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ",
-				    indentstr, tag, size);
+				dev_dbg(ddev, "%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d\n",
+					indentstr, tag, size);
 			}
 			break;
 
@@ -511,18 +511,18 @@
 
 			switch (size) {
 			case 1:
-				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
-				    indentstr, tag, globtype, size, data);
+				dev_dbg(ddev, "%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x\n",
+					indentstr, tag, globtype, size, data);
 				break;
 
 			case 2:
-				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
-				    indentstr, tag, globtype, size, data16);
+				dev_dbg(ddev, "%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x\n",
+					indentstr, tag, globtype, size, data16);
 				break;
 
 			case 4:
-				dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
-				    indentstr, tag, globtype, size, data32);
+				dev_dbg(ddev, "%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x\n",
+					indentstr, tag, globtype, size, data32);
 				break;
 			}
 
@@ -714,8 +714,9 @@
 				 * the rest as 0
 				 */
 				val = device->buffer[5] & MASK_BUTTON;
-				dbg("======>>>>>>REPORT 1: val 0x%X(%d)",
-				    val, val);
+				dev_dbg(&device->intf->dev,
+					"======>>>>>>REPORT 1: val 0x%X(%d)\n",
+					val, val);
 
 				/*
 				 * We don't apply any meaning to the button
@@ -808,7 +809,8 @@
  resubmit:
 	rc = usb_submit_urb(urbinfo, GFP_ATOMIC);
 	if (rc != 0)
-		err("usb_submit_urb failed rc=0x%x", rc);
+		dev_err(&device->intf->dev,
+			"usb_submit_urb failed rc=0x%x\n", rc);
 }
 
 /*
@@ -838,7 +840,7 @@
 	gtco = kzalloc(sizeof(struct gtco), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!gtco || !input_dev) {
-		err("No more memory");
+		dev_err(&usbinterface->dev, "No more memory\n");
 		error = -ENOMEM;
 		goto err_free_devs;
 	}
@@ -848,12 +850,13 @@
 
 	/* Save interface information */
 	gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface));
+	gtco->intf = usbinterface;
 
 	/* Allocate some data for incoming reports */
 	gtco->buffer = usb_alloc_coherent(gtco->usbdev, REPORT_MAX_SIZE,
 					  GFP_KERNEL, &gtco->buf_dma);
 	if (!gtco->buffer) {
-		err("No more memory for us buffers");
+		dev_err(&usbinterface->dev, "No more memory for us buffers\n");
 		error = -ENOMEM;
 		goto err_free_devs;
 	}
@@ -861,7 +864,7 @@
 	/* Allocate URB for reports */
 	gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL);
 	if (!gtco->urbinfo) {
-		err("Failed to allocate URB");
+		dev_err(&usbinterface->dev, "Failed to allocate URB\n");
 		error = -ENOMEM;
 		goto err_free_buf;
 	}
@@ -873,14 +876,14 @@
 	endpoint = &usbinterface->altsetting[0].endpoint[0].desc;
 
 	/* Some debug */
-	dbg("gtco # interfaces: %d", usbinterface->num_altsetting);
-	dbg("num endpoints:     %d", usbinterface->cur_altsetting->desc.bNumEndpoints);
-	dbg("interface class:   %d", usbinterface->cur_altsetting->desc.bInterfaceClass);
-	dbg("endpoint: attribute:0x%x type:0x%x", endpoint->bmAttributes, endpoint->bDescriptorType);
+	dev_dbg(&usbinterface->dev, "gtco # interfaces: %d\n", usbinterface->num_altsetting);
+	dev_dbg(&usbinterface->dev, "num endpoints:     %d\n", usbinterface->cur_altsetting->desc.bNumEndpoints);
+	dev_dbg(&usbinterface->dev, "interface class:   %d\n", usbinterface->cur_altsetting->desc.bInterfaceClass);
+	dev_dbg(&usbinterface->dev, "endpoint: attribute:0x%x type:0x%x\n", endpoint->bmAttributes, endpoint->bDescriptorType);
 	if (usb_endpoint_xfer_int(endpoint))
-		dbg("endpoint: we have interrupt endpoint\n");
+		dev_dbg(&usbinterface->dev, "endpoint: we have interrupt endpoint\n");
 
-	dbg("endpoint extra len:%d ", usbinterface->altsetting[0].extralen);
+	dev_dbg(&usbinterface->dev, "endpoint extra len:%d\n", usbinterface->altsetting[0].extralen);
 
 	/*
 	 * Find the HID descriptor so we can find out the size of the
@@ -888,17 +891,19 @@
 	 */
 	if (usb_get_extra_descriptor(usbinterface->cur_altsetting,
 				     HID_DEVICE_TYPE, &hid_desc) != 0){
-		err("Can't retrieve exta USB descriptor to get hid report descriptor length");
+		dev_err(&usbinterface->dev,
+			"Can't retrieve exta USB descriptor to get hid report descriptor length\n");
 		error = -EIO;
 		goto err_free_urb;
 	}
 
-	dbg("Extra descriptor success: type:%d  len:%d",
-	    hid_desc->bDescriptorType,  hid_desc->wDescriptorLength);
+	dev_dbg(&usbinterface->dev,
+		"Extra descriptor success: type:%d  len:%d\n",
+		hid_desc->bDescriptorType,  hid_desc->wDescriptorLength);
 
 	report = kzalloc(le16_to_cpu(hid_desc->wDescriptorLength), GFP_KERNEL);
 	if (!report) {
-		err("No more memory for report");
+		dev_err(&usbinterface->dev, "No more memory for report\n");
 		error = -ENOMEM;
 		goto err_free_urb;
 	}
@@ -915,7 +920,7 @@
 					 le16_to_cpu(hid_desc->wDescriptorLength),
 					 5000); /* 5 secs */
 
-		dbg("usb_control_msg result: %d", result);
+		dev_dbg(&usbinterface->dev, "usb_control_msg result: %d\n", result);
 		if (result == le16_to_cpu(hid_desc->wDescriptorLength)) {
 			parse_hid_report_descriptor(gtco, report, result);
 			break;
@@ -926,8 +931,9 @@
 
 	/* If we didn't get the report, fail */
 	if (result != le16_to_cpu(hid_desc->wDescriptorLength)) {
-		err("Failed to get HID Report Descriptor of size: %d",
-		    hid_desc->wDescriptorLength);
+		dev_err(&usbinterface->dev,
+			"Failed to get HID Report Descriptor of size: %d\n",
+			hid_desc->wDescriptorLength);
 		error = -EIO;
 		goto err_free_urb;
 	}
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index 85a5b40..3fba74b 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -33,6 +33,7 @@
 	dma_addr_t data_dma;
 	struct input_dev *dev;
 	struct usb_device *usbdev;
+	struct usb_interface *intf;
 	struct urb *irq;
 	char phys[32];
 };
@@ -53,10 +54,14 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+		dev_dbg(&kbtab->intf->dev,
+			"%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+		dev_dbg(&kbtab->intf->dev,
+			"%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -80,8 +85,9 @@
  exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err("%s - usb_submit_urb failed with result %d",
-		     __func__, retval);
+		dev_err(&kbtab->intf->dev,
+			"%s - usb_submit_urb failed with result %d\n",
+			__func__, retval);
 }
 
 static struct usb_device_id kbtab_ids[] = {
@@ -131,6 +137,7 @@
 		goto fail2;
 
 	kbtab->usbdev = dev;
+	kbtab->intf = intf;
 	kbtab->dev = input_dev;
 
 	usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 0d26921..79a0509 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -99,6 +99,7 @@
 static void wacom_sys_irq(struct urb *urb)
 {
 	struct wacom *wacom = urb->context;
+	struct device *dev = &wacom->intf->dev;
 	int retval;
 
 	switch (urb->status) {
@@ -109,10 +110,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -122,8 +125,8 @@
 	usb_mark_last_busy(wacom->usbdev);
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __func__, retval);
+		dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
+			__func__, retval);
 }
 
 static int wacom_open(struct input_dev *dev)
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index cecd35c..b327790 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -76,7 +76,8 @@
 	int prox, pressure;
 
 	if (data[0] != WACOM_REPORT_PENABLED) {
-		dbg("wacom_pl_irq: received unknown report #%d", data[0]);
+		dev_dbg(&input->dev,
+			"wacom_pl_irq: received unknown report #%d\n", data[0]);
 		return 0;
 	}
 
@@ -175,7 +176,7 @@
 	struct input_dev *input = wacom->input;
 	int prox = data[1] & 0x20, pressure;
 
-	dbg("wacom_dtu_irq: received report #%d", data[0]);
+	dev_dbg(&input->dev, "wacom_dtu_irq: received report #%d\n", data[0]);
 
 	if (prox) {
 		/* Going into proximity select tool */
@@ -211,7 +212,9 @@
 	int retval = 0;
 
 	if (data[0] != WACOM_REPORT_PENABLED) {
-		dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
+		dev_dbg(&input->dev,
+			"wacom_graphire_irq: received unknown report #%d\n",
+			data[0]);
 		goto exit;
 	}
 
@@ -484,7 +487,9 @@
 
 	if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_INTUOSREAD
 		&& data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSPAD) {
-		dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
+		dev_dbg(&input->dev,
+			"wacom_intuos_irq: received unknown report #%d\n",
+			data[0]);
                 return 0;
 	}
 
@@ -830,7 +835,8 @@
 {
 	char *data = wacom->data;
 
-	dbg("wacom_tpc_irq: received report #%d", data[0]);
+	dev_dbg(&wacom->input->dev, "wacom_tpc_irq: received report #%d\n",
+		data[0]);
 
 	switch (len) {
 	case WACOM_PKGLEN_TPC1FG:
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 22cd96f..e32709e 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -269,8 +269,9 @@
 	                      0x01, 0x02, 0x0000, 0x0081,
 	                      NULL, 0, USB_CTRL_SET_TIMEOUT);
 
-	dbg("%s - usb_control_msg - E2I_RESET - bytes|err: %d",
-	    __func__, ret);
+	dev_dbg(&usbtouch->interface->dev,
+		"%s - usb_control_msg - E2I_RESET - bytes|err: %d\n",
+		__func__, ret);
 	return ret;
 }
 
@@ -425,8 +426,9 @@
 	                      MTOUCHUSB_RESET,
 	                      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 	                      1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
-	dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
-	    __func__, ret);
+	dev_dbg(&usbtouch->interface->dev,
+		"%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d\n",
+		__func__, ret);
 	if (ret < 0)
 		return ret;
 	msleep(150);
@@ -436,8 +438,9 @@
 				      MTOUCHUSB_ASYNC_REPORT,
 				      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				      1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
-		dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
-		    __func__, ret);
+		dev_dbg(&usbtouch->interface->dev,
+			"%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d\n",
+			__func__, ret);
 		if (ret >= 0)
 			break;
 		if (ret != -EPIPE)
@@ -737,27 +740,29 @@
 #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
 static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
+	struct usb_interface *intf = dev->interface;
+
 	switch (pkt[0]) {
 	case 0x3A: /* command response */
-		dbg("%s: Command response %d", __func__, pkt[1]);
+		dev_dbg(&intf->dev, "%s: Command response %d\n", __func__, pkt[1]);
 		break;
 
 	case 0xC0: /* down */
 		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
 		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
 		dev->touch = 1;
-		dbg("%s: down %d,%d", __func__, dev->x, dev->y);
+		dev_dbg(&intf->dev, "%s: down %d,%d\n", __func__, dev->x, dev->y);
 		return 1;
 
 	case 0x80: /* up */
 		dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7);
 		dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7);
 		dev->touch = 0;
-		dbg("%s: up %d,%d", __func__, dev->x, dev->y);
+		dev_dbg(&intf->dev, "%s: up %d,%d\n", __func__, dev->x, dev->y);
 		return 1;
 
 	default:
-		dbg("%s: Unknown return %d", __func__, pkt[0]);
+		dev_dbg(&intf->dev, "%s: Unknown return %d\n", __func__, pkt[0]);
 		break;
 	}
 
@@ -812,7 +817,8 @@
 
 	priv->ack = usb_alloc_urb(0, GFP_KERNEL);
 	if (!priv->ack) {
-		dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__);
+		dev_dbg(&usbtouch->interface->dev,
+			"%s - usb_alloc_urb failed: usbtouch->ack\n", __func__);
 		goto err_ack_buf;
 	}
 
@@ -1349,6 +1355,7 @@
 static void usbtouch_irq(struct urb *urb)
 {
 	struct usbtouch_usb *usbtouch = urb->context;
+	struct device *dev = &usbtouch->interface->dev;
 	int retval;
 
 	switch (urb->status) {
@@ -1357,20 +1364,21 @@
 		break;
 	case -ETIME:
 		/* this urb is timing out */
-		dbg("%s - urb timed out - was the device unplugged?",
-		    __func__);
+		dev_dbg(dev,
+			"%s - urb timed out - was the device unplugged?\n",
+			__func__);
 		return;
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
 	case -EPIPE:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, urb->status);
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, urb->status);
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -1380,8 +1388,8 @@
 	usb_mark_last_busy(interface_to_usbdev(usbtouch->interface));
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err("%s - usb_submit_urb failed with result: %d",
-		    __func__, retval);
+		dev_err(dev, "%s - usb_submit_urb failed with result: %d\n",
+			__func__, retval);
 }
 
 static int usbtouch_open(struct input_dev *input)
@@ -1456,8 +1464,9 @@
 	if (usbtouch->type->init) {
 		err = usbtouch->type->init(usbtouch);
 		if (err) {
-			dbg("%s - type->init() failed, err: %d",
-			    __func__, err);
+			dev_dbg(&intf->dev,
+				"%s - type->init() failed, err: %d\n",
+				__func__, err);
 			return err;
 		}
 	}
@@ -1532,7 +1541,8 @@
 
 	usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!usbtouch->irq) {
-		dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__);
+		dev_dbg(&intf->dev,
+			"%s - usb_alloc_urb failed: usbtouch->irq\n", __func__);
 		goto out_free_buffers;
 	}
 
@@ -1594,7 +1604,9 @@
 	if (type->alloc) {
 		err = type->alloc(usbtouch);
 		if (err) {
-			dbg("%s - type->alloc() failed, err: %d", __func__, err);
+			dev_dbg(&intf->dev,
+				"%s - type->alloc() failed, err: %d\n",
+				__func__, err);
 			goto out_free_urb;
 		}
 	}
@@ -1603,14 +1615,18 @@
 	if (type->init) {
 		err = type->init(usbtouch);
 		if (err) {
-			dbg("%s - type->init() failed, err: %d", __func__, err);
+			dev_dbg(&intf->dev,
+				"%s - type->init() failed, err: %d\n",
+				__func__, err);
 			goto out_do_exit;
 		}
 	}
 
 	err = input_register_device(usbtouch->input);
 	if (err) {
-		dbg("%s - input_register_device failed, err: %d", __func__, err);
+		dev_dbg(&intf->dev,
+			"%s - input_register_device failed, err: %d\n",
+			__func__, err);
 		goto out_do_exit;
 	}
 
@@ -1622,8 +1638,9 @@
 		err = usb_submit_urb(usbtouch->irq, GFP_KERNEL);
 		if (err) {
 			usb_autopm_put_interface(intf);
-			err("%s - usb_submit_urb failed with result: %d",
-			    __func__, err);
+			dev_err(&intf->dev,
+				"%s - usb_submit_urb failed with result: %d\n",
+				__func__, err);
 			goto out_unregister_input;
 		}
 	}
@@ -1650,12 +1667,12 @@
 {
 	struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
 
-	dbg("%s - called", __func__);
-
 	if (!usbtouch)
 		return;
 
-	dbg("%s - usbtouch is initialized, cleaning up", __func__);
+	dev_dbg(&intf->dev,
+		"%s - usbtouch is initialized, cleaning up\n", __func__);
+
 	usb_set_intfdata(intf, NULL);
 	/* this will stop IO via close */
 	input_unregister_device(usbtouch->input);
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
index e6601b8..b579730 100644
--- a/drivers/media/video/gspca/ov534_9.c
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -1376,7 +1376,7 @@
 				ARRAY_SIZE(ov562x_init_2));
 		reg_w(gspca_dev, 0xe0, 0x00);
 	} else {
-		err("Unknown sensor %04x", sensor_id);
+		pr_err("Unknown sensor %04x", sensor_id);
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 6510110..304f43e 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -303,7 +303,7 @@
 	/* allocate memory for our device state and initialize it */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		err("Out of memory");
+		dev_err(&interface->dev, "Out of memory\n");
 		goto error;
 	}
 
@@ -311,7 +311,7 @@
 
 	/* register v4l2_device early so it can be used for printks */
 	if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
-		err("v4l2_device_register failed");
+		dev_err(&interface->dev, "v4l2_device_register failed\n");
 		goto error;
 	}
 
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 72f687b..f9a86bd 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1671,7 +1671,7 @@
 
 	/* Is this really necessary? (no, except maybe for broken devices) */
 	if (usb_reset_configuration (dev) < 0) {
-		err("reset_configuration failed");
+		dev_err(&intf->dev, "reset_configuration failed\n");
 		ret = -EIO;
 		goto err_out_3;
 	}
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index 79aebee..7b48338 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -134,14 +134,16 @@
 
 	/* in process of stopping, just drop data */
 	if (!netif_running(kingsun->netdev)) {
-		err("kingsun_send_irq: Network not running!");
+		dev_err(&kingsun->usbdev->dev,
+			"kingsun_send_irq: Network not running!\n");
 		return;
 	}
 
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("kingsun_send_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&kingsun->usbdev->dev,
+			"kingsun_send_irq: urb asynchronously failed - %d\n",
+			urb->status);
 	}
 	netif_wake_queue(netdev);
 }
@@ -177,7 +179,8 @@
 		kingsun, 1);
 
 	if ((ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC))) {
-		err("kingsun_hard_xmit: failed tx_urb submit: %d", ret);
+		dev_err(&kingsun->usbdev->dev,
+			"kingsun_hard_xmit: failed tx_urb submit: %d\n", ret);
 		switch (ret) {
 		case -ENODEV:
 		case -EPIPE:
@@ -211,8 +214,9 @@
 
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("kingsun_rcv_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&kingsun->usbdev->dev,
+			"kingsun_rcv_irq: urb asynchronously failed - %d\n",
+			urb->status);
 		kingsun->receiving = 0;
 		return;
 	}
@@ -238,8 +242,9 @@
 				? 1 : 0;
 		}
 	} else if (urb->actual_length > 0) {
-		err("%s(): Unexpected response length, expected %d got %d",
-		    __func__, kingsun->max_rx, urb->actual_length);
+		dev_err(&kingsun->usbdev->dev,
+			"%s(): Unexpected response length, expected %d got %d\n",
+			__func__, kingsun->max_rx, urb->actual_length);
 	}
 	/* This urb has already been filled in kingsun_net_open */
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
@@ -286,7 +291,7 @@
 	sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
 	kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
 	if (!kingsun->irlap) {
-		err("kingsun-sir: irlap_open failed");
+		dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
 		goto free_mem;
 	}
 
@@ -298,7 +303,8 @@
 	kingsun->rx_urb->status = 0;
 	err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
 	if (err) {
-		err("kingsun-sir: first urb-submit failed: %d", err);
+		dev_err(&kingsun->usbdev->dev,
+			"first urb-submit failed: %d\n", err);
 		goto close_irlap;
 	}
 
@@ -446,13 +452,15 @@
 	 */
 	interface = intf->cur_altsetting;
 	if (interface->desc.bNumEndpoints != 2) {
-		err("kingsun-sir: expected 2 endpoints, found %d",
-		    interface->desc.bNumEndpoints);
+		dev_err(&intf->dev,
+			"kingsun-sir: expected 2 endpoints, found %d\n",
+			interface->desc.bNumEndpoints);
 		return -ENODEV;
 	}
 	endpoint = &interface->endpoint[KINGSUN_EP_IN].desc;
 	if (!usb_endpoint_is_int_in(endpoint)) {
-		err("kingsun-sir: endpoint 0 is not interrupt IN");
+		dev_err(&intf->dev,
+			"kingsun-sir: endpoint 0 is not interrupt IN\n");
 		return -ENODEV;
 	}
 
@@ -460,14 +468,16 @@
 	pipe = usb_rcvintpipe(dev, ep_in);
 	maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 	if (maxp_in > 255 || maxp_in <= 1) {
-		err("%s: endpoint 0 has max packet size %d not in range",
-		    __FILE__, maxp_in);
+		dev_err(&intf->dev,
+			"endpoint 0 has max packet size %d not in range\n",
+			maxp_in);
 		return -ENODEV;
 	}
 
 	endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc;
 	if (!usb_endpoint_is_int_out(endpoint)) {
-		err("kingsun-sir: endpoint 1 is not interrupt OUT");
+		dev_err(&intf->dev,
+			"kingsun-sir: endpoint 1 is not interrupt OUT\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index abe689d..824e2a9 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -247,8 +247,9 @@
 {
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("ks959_speed_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&urb->dev->dev,
+			"ks959_speed_irq: urb asynchronously failed - %d\n",
+			urb->status);
 	}
 }
 
@@ -332,14 +333,16 @@
 
 	/* in process of stopping, just drop data */
 	if (!netif_running(kingsun->netdev)) {
-		err("ks959_send_irq: Network not running!");
+		dev_err(&kingsun->usbdev->dev,
+			"ks959_send_irq: Network not running!\n");
 		return;
 	}
 
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("ks959_send_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&kingsun->usbdev->dev,
+			"ks959_send_irq: urb asynchronously failed - %d\n",
+			urb->status);
 		return;
 	}
 
@@ -358,8 +361,9 @@
 		if (kingsun->tx_buf_clear_used > 0) {
 			/* There is more data to be sent */
 			if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
-				err("ks959_send_irq: failed tx_urb submit: %d",
-				    ret);
+				dev_err(&kingsun->usbdev->dev,
+					"ks959_send_irq: failed tx_urb submit: %d\n",
+					ret);
 				switch (ret) {
 				case -ENODEV:
 				case -EPIPE:
@@ -407,7 +411,8 @@
 	kingsun->tx_buf_clear_used = wraplen;
 
 	if ((ret = ks959_submit_tx_fragment(kingsun)) != 0) {
-		err("ks959_hard_xmit: failed tx_urb submit: %d", ret);
+		dev_err(&kingsun->usbdev->dev,
+			"ks959_hard_xmit: failed tx_urb submit: %d\n", ret);
 		switch (ret) {
 		case -ENODEV:
 		case -EPIPE:
@@ -442,8 +447,9 @@
 
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("kingsun_rcv_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&kingsun->usbdev->dev,
+			"kingsun_rcv_irq: urb asynchronously failed - %d\n",
+			urb->status);
 		kingsun->receiving = 0;
 		return;
 	}
@@ -536,7 +542,7 @@
 	sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
 	kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
 	if (!kingsun->irlap) {
-		err("ks959-sir: irlap_open failed");
+		dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
 		goto free_mem;
 	}
 
@@ -549,7 +555,8 @@
 	kingsun->rx_urb->status = 0;
 	err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
 	if (err) {
-		err("ks959-sir: first urb-submit failed: %d", err);
+		dev_err(&kingsun->usbdev->dev,
+			"first urb-submit failed: %d\n", err);
 		goto close_irlap;
 	}
 
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index f8c0108..5a278ab 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -168,10 +168,10 @@
 static void ksdazzle_speed_irq(struct urb *urb)
 {
 	/* unlink, shutdown, unplug, other nasties */
-	if (urb->status != 0) {
-		err("ksdazzle_speed_irq: urb asynchronously failed - %d",
-		    urb->status);
-	}
+	if (urb->status != 0)
+		dev_err(&urb->dev->dev,
+			"ksdazzle_speed_irq: urb asynchronously failed - %d\n",
+			urb->status);
 }
 
 /* Send a control request to change speed of the dongle */
@@ -245,14 +245,16 @@
 
 	/* in process of stopping, just drop data */
 	if (!netif_running(kingsun->netdev)) {
-		err("ksdazzle_send_irq: Network not running!");
+		dev_err(&kingsun->usbdev->dev,
+			"ksdazzle_send_irq: Network not running!\n");
 		return;
 	}
 
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("ksdazzle_send_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&kingsun->usbdev->dev,
+			"ksdazzle_send_irq: urb asynchronously failed - %d\n",
+			urb->status);
 		return;
 	}
 
@@ -271,7 +273,9 @@
 		if (kingsun->tx_buf_clear_used > 0) {
 			/* There is more data to be sent */
 			if ((ret = ksdazzle_submit_tx_fragment(kingsun)) != 0) {
-				err("ksdazzle_send_irq: failed tx_urb submit: %d", ret);
+				dev_err(&kingsun->usbdev->dev,
+					"ksdazzle_send_irq: failed tx_urb submit: %d\n",
+					ret);
 				switch (ret) {
 				case -ENODEV:
 				case -EPIPE:
@@ -320,7 +324,8 @@
 	kingsun->tx_buf_clear_used = wraplen;
 
 	if ((ret = ksdazzle_submit_tx_fragment(kingsun)) != 0) {
-		err("ksdazzle_hard_xmit: failed tx_urb submit: %d", ret);
+		dev_err(&kingsun->usbdev->dev,
+			"ksdazzle_hard_xmit: failed tx_urb submit: %d\n", ret);
 		switch (ret) {
 		case -ENODEV:
 		case -EPIPE:
@@ -355,8 +360,9 @@
 
 	/* unlink, shutdown, unplug, other nasties */
 	if (urb->status != 0) {
-		err("ksdazzle_rcv_irq: urb asynchronously failed - %d",
-		    urb->status);
+		dev_err(&kingsun->usbdev->dev,
+			"ksdazzle_rcv_irq: urb asynchronously failed - %d\n",
+			urb->status);
 		kingsun->receiving = 0;
 		return;
 	}
@@ -430,7 +436,7 @@
 	sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
 	kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
 	if (!kingsun->irlap) {
-		err("ksdazzle-sir: irlap_open failed");
+		dev_err(&kingsun->usbdev->dev, "irlap_open failed\n");
 		goto free_mem;
 	}
 
@@ -442,7 +448,7 @@
 	kingsun->rx_urb->status = 0;
 	err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
 	if (err) {
-		err("ksdazzle-sir: first urb-submit failed: %d", err);
+		dev_err(&kingsun->usbdev->dev, "first urb-submit failed: %d\n", err);
 		goto close_irlap;
 	}
 
@@ -590,13 +596,14 @@
 	 */
 	interface = intf->cur_altsetting;
 	if (interface->desc.bNumEndpoints != 2) {
-		err("ksdazzle: expected 2 endpoints, found %d",
-		    interface->desc.bNumEndpoints);
+		dev_err(&intf->dev, "ksdazzle: expected 2 endpoints, found %d\n",
+			interface->desc.bNumEndpoints);
 		return -ENODEV;
 	}
 	endpoint = &interface->endpoint[KINGSUN_EP_IN].desc;
 	if (!usb_endpoint_is_int_in(endpoint)) {
-		err("ksdazzle: endpoint 0 is not interrupt IN");
+		dev_err(&intf->dev,
+			"ksdazzle: endpoint 0 is not interrupt IN\n");
 		return -ENODEV;
 	}
 
@@ -604,13 +611,16 @@
 	pipe = usb_rcvintpipe(dev, ep_in);
 	maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 	if (maxp_in > 255 || maxp_in <= 1) {
-		err("ksdazzle: endpoint 0 has max packet size %d not in range [2..255]", maxp_in);
+		dev_err(&intf->dev,
+			"ksdazzle: endpoint 0 has max packet size %d not in range [2..255]\n",
+			maxp_in);
 		return -ENODEV;
 	}
 
 	endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc;
 	if (!usb_endpoint_is_int_out(endpoint)) {
-		err("ksdazzle: endpoint 1 is not interrupt OUT");
+		dev_err(&intf->dev,
+			"ksdazzle: endpoint 1 is not interrupt OUT\n");
 		return -ENODEV;
 	}
 
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index e6e59a0..876e709 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -904,7 +904,7 @@
 	sprintf(hwname, "usb#%d", stir->usbdev->devnum);
 	stir->irlap = irlap_open(netdev, &stir->qos, hwname);
 	if (!stir->irlap) {
-		err("stir4200: irlap_open failed");
+		dev_err(&stir->usbdev->dev, "irlap_open failed\n");
 		goto err_out5;
 	}
 
@@ -913,7 +913,7 @@
 				   "%s", stir->netdev->name);
         if (IS_ERR(stir->thread)) {
                 err = PTR_ERR(stir->thread);
-		err("stir4200: unable to start kernel thread");
+		dev_err(&stir->usbdev->dev, "unable to start kernel thread\n");
 		goto err_out6;
 	}
 
@@ -1042,7 +1042,7 @@
 
 	ret = usb_reset_configuration(dev);
 	if (ret != 0) {
-		err("stir4200: usb reset configuration failed");
+		dev_err(&intf->dev, "usb reset configuration failed\n");
 		goto err_out2;
 	}
 
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 182cfb4..5a73730 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -338,16 +338,18 @@
 		} else {
 			catc->rx_urb->dev = catc->usbdev;
 			if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) {
-				err("submit(rx_urb) status %d", res);
+				dev_err(&catc->usbdev->dev,
+					"submit(rx_urb) status %d\n", res);
 			}
 		} 
 	}
 resubmit:
 	res = usb_submit_urb (urb, GFP_ATOMIC);
 	if (res)
-		err ("can't resubmit intr, %s-%s, status %d",
-				catc->usbdev->bus->bus_name,
-				catc->usbdev->devpath, res);
+		dev_err(&catc->usbdev->dev,
+			"can't resubmit intr, %s-%s, status %d\n",
+			catc->usbdev->bus->bus_name,
+			catc->usbdev->devpath, res);
 }
 
 /*
@@ -366,7 +368,8 @@
 	catc->tx_urb->dev = catc->usbdev;
 
 	if ((status = usb_submit_urb(catc->tx_urb, GFP_ATOMIC)) < 0)
-		err("submit(tx_urb), status %d", status);
+		dev_err(&catc->usbdev->dev, "submit(tx_urb), status %d\n",
+			status);
 
 	catc->tx_idx = !catc->tx_idx;
 	catc->tx_ptr = 0;
@@ -496,7 +499,8 @@
 		memcpy(catc->ctrl_buf, q->buf, q->len);
 
 	if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC)))
-		err("submit(ctrl_urb) status %d", status);
+		dev_err(&catc->usbdev->dev, "submit(ctrl_urb) status %d\n",
+			status);
 }
 
 static void catc_ctrl_done(struct urb *urb)
@@ -555,7 +559,7 @@
 	catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1);
 
 	if (catc->ctrl_head == catc->ctrl_tail) {
-		err("ctrl queue full");
+		dev_err(&catc->usbdev->dev, "ctrl queue full\n");
 		catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
 		retval = -1;
 	}
@@ -714,7 +718,8 @@
 
 	catc->irq_urb->dev = catc->usbdev;
 	if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) {
-		err("submit(irq_urb) status %d", status);
+		dev_err(&catc->usbdev->dev, "submit(irq_urb) status %d\n",
+			status);
 		return -1;
 	}
 
@@ -769,7 +774,7 @@
 
 	if (usb_set_interface(usbdev,
 			intf->altsetting->desc.bInterfaceNumber, 1)) {
-                err("Can't set altsetting 1.");
+                dev_err(&intf->dev, "Can't set altsetting 1.\n");
 		return -EIO;
 	}
 
@@ -799,7 +804,7 @@
 	catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if ((!catc->ctrl_urb) || (!catc->tx_urb) || 
 	    (!catc->rx_urb) || (!catc->irq_urb)) {
-		err("No free urbs available.");
+		dev_err(&intf->dev, "No free urbs available.\n");
 		usb_free_urb(catc->ctrl_urb);
 		usb_free_urb(catc->tx_urb);
 		usb_free_urb(catc->rx_urb);
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index dd78c4c..32519e5 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -209,7 +209,8 @@
 	case 0:
 		break;
 	default:
-		err("%s: urb status: %d", __func__, status);
+		dev_err(&dev->intf->dev, "%s: urb status: %d\n",
+			__func__, status);
 		return;
 	}
 
@@ -222,7 +223,8 @@
 
 	skb = dev_alloc_skb(len);
 	if (!skb) {
-		err("%s: dev_alloc_skb: -ENOMEM", __func__);
+		dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n",
+			__func__);
 		dev->net->stats.rx_dropped++;
 		return;
 	}
@@ -251,7 +253,8 @@
 	    status != -ENOENT &&
 	    status != -ECONNRESET &&
 	    status != -ESHUTDOWN)
-		err("%s: urb status: %d", __func__, status);
+		dev_err(&dev->intf->dev, "%s: urb status: %d\n",
+		__func__, status);
 
 	dev_kfree_skb_irq(dev->tx_skb);
 	netif_wake_queue(dev->net);
@@ -271,7 +274,8 @@
 			dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
 			IPHETH_CTRL_TIMEOUT);
 	if (retval < 0) {
-		err("%s: usb_control_msg: %d", __func__, retval);
+		dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n",
+			__func__, retval);
 		return retval;
 	}
 
@@ -308,9 +312,11 @@
 				 IPHETH_CTRL_BUF_SIZE,
 				 IPHETH_CTRL_TIMEOUT);
 	if (retval < 0) {
-		err("%s: usb_control_msg: %d", __func__, retval);
+		dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n",
+			__func__, retval);
 	} else if (retval < ETH_ALEN) {
-		err("%s: usb_control_msg: short packet: %d bytes",
+		dev_err(&dev->intf->dev,
+			"%s: usb_control_msg: short packet: %d bytes\n",
 			__func__, retval);
 		retval = -EINVAL;
 	} else {
@@ -335,7 +341,8 @@
 
 	retval = usb_submit_urb(dev->rx_urb, mem_flags);
 	if (retval)
-		err("%s: usb_submit_urb: %d", __func__, retval);
+		dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
+			__func__, retval);
 	return retval;
 }
 
@@ -396,7 +403,8 @@
 
 	retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
 	if (retval) {
-		err("%s: usb_submit_urb: %d", __func__, retval);
+		dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
+			__func__, retval);
 		dev->net->stats.tx_errors++;
 		dev_kfree_skb_irq(skb);
 	} else {
@@ -414,7 +422,7 @@
 {
 	struct ipheth_device *dev = netdev_priv(net);
 
-	err("%s: TX timeout", __func__);
+	dev_err(&dev->intf->dev, "%s: TX timeout\n", __func__);
 	dev->net->stats.tx_errors++;
 	usb_unlink_urb(dev->tx_urb);
 }
@@ -464,7 +472,7 @@
 	hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
 	if (hintf == NULL) {
 		retval = -ENODEV;
-		err("Unable to find alternate settings interface");
+		dev_err(&intf->dev, "Unable to find alternate settings interface\n");
 		goto err_endpoints;
 	}
 
@@ -477,7 +485,7 @@
 	}
 	if (!(dev->bulk_in && dev->bulk_out)) {
 		retval = -ENODEV;
-		err("Unable to find endpoints");
+		dev_err(&intf->dev, "Unable to find endpoints\n");
 		goto err_endpoints;
 	}
 
@@ -495,7 +503,7 @@
 
 	retval = ipheth_alloc_urbs(dev);
 	if (retval) {
-		err("error allocating urbs: %d", retval);
+		dev_err(&intf->dev, "error allocating urbs: %d\n", retval);
 		goto err_alloc_urbs;
 	}
 
@@ -506,7 +514,7 @@
 
 	retval = register_netdev(netdev);
 	if (retval) {
-		err("error registering netdev: %d", retval);
+		dev_err(&intf->dev, "error registering netdev: %d\n", retval);
 		retval = -EIO;
 		goto err_register_netdev;
 	}
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index df2a2cf..b8baf08 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -400,12 +400,13 @@
 
 	ret = request_firmware(&fw, fwname, &kaweth->dev->dev);
 	if (ret) {
-		err("Firmware request failed\n");
+		dev_err(&kaweth->intf->dev, "Firmware request failed\n");
 		return ret;
 	}
 
 	if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) {
-		err("Firmware too big: %zu", fw->size);
+		dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n",
+			fw->size);
 		release_firmware(fw);
 		return -ENOSPC;
 	}
@@ -501,9 +502,10 @@
 	}
 
 	if (status)
-		err ("can't resubmit intr, %s-%s, status %d",
-				kaweth->dev->bus->bus_name,
-				kaweth->dev->devpath, status);
+		dev_err(&kaweth->intf->dev,
+			"can't resubmit intr, %s-%s, status %d\n",
+			kaweth->dev->bus->bus_name,
+			kaweth->dev->devpath, status);
 }
 
 static void int_callback(struct urb *u)
@@ -576,7 +578,8 @@
 			kaweth->suspend_lowmem_rx = 1;
 			schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
 		}
-		err("resubmitting rx_urb %d failed", result);
+		dev_err(&kaweth->intf->dev, "resubmitting rx_urb %d failed\n",
+			result);
 	} else {
 		kaweth->suspend_lowmem_rx = 0;
 	}
@@ -634,20 +637,21 @@
 	spin_unlock(&kaweth->device_lock);
 
 	if(status && status != -EREMOTEIO && count != 1) {
-		err("%s RX status: %d count: %d packet_len: %d",
-                           net->name,
-			   status,
-			   count,
-			   (int)pkt_len);
+		dev_err(&kaweth->intf->dev,
+			"%s RX status: %d count: %d packet_len: %d\n",
+			net->name, status, count, (int)pkt_len);
 		kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
                 return;
 	}
 
 	if(kaweth->net && (count > 2)) {
 		if(pkt_len > (count - 2)) {
-			err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);
-			err("Packet len & 2047: %x", pkt_len & 2047);
-			err("Count 2: %x", count2);
+			dev_err(&kaweth->intf->dev,
+				"Packet length too long for USB frame (pkt_len: %x, count: %x)\n",
+				pkt_len, count);
+			dev_err(&kaweth->intf->dev, "Packet len & 2047: %x\n",
+				pkt_len & 2047);
+			dev_err(&kaweth->intf->dev, "Count 2: %x\n", count2);
 		        kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
                         return;
                 }
@@ -686,7 +690,7 @@
 
 	res = usb_autopm_get_interface(kaweth->intf);
 	if (res) {
-		err("Interface cannot be resumed.");
+		dev_err(&kaweth->intf->dev, "Interface cannot be resumed.\n");
 		return -EIO;
 	}
 	res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL);
@@ -907,7 +911,8 @@
 				KAWETH_CONTROL_TIMEOUT);
 
 	if(result < 0) {
-		err("Failed to set Rx mode: %d", result);
+		dev_err(&kaweth->intf->dev, "Failed to set Rx mode: %d\n",
+			result);
 	}
 	else {
 		dbg("Set Rx mode to %d", packet_filter_bitmap);
@@ -1045,7 +1050,8 @@
 						      "kaweth/new_code.bin",
 						      100,
 						      2)) < 0) {
-			err("Error downloading firmware (%d)", result);
+			dev_err(&intf->dev, "Error downloading firmware (%d)\n",
+				result);
 			goto err_fw;
 		}
 
@@ -1053,7 +1059,9 @@
 						      "kaweth/new_code_fix.bin",
 						      100,
 						      3)) < 0) {
-			err("Error downloading firmware fix (%d)", result);
+			dev_err(&intf->dev,
+				"Error downloading firmware fix (%d)\n",
+				result);
 			goto err_fw;
 		}
 
@@ -1061,7 +1069,9 @@
 						      "kaweth/trigger_code.bin",
 						      126,
 						      2)) < 0) {
-			err("Error downloading trigger code (%d)", result);
+			dev_err(&intf->dev,
+				"Error downloading trigger code (%d)\n",
+				result);
 			goto err_fw;
 
 		}
@@ -1070,13 +1080,14 @@
 						      "kaweth/trigger_code_fix.bin",
 						      126,
 						      3)) < 0) {
-			err("Error downloading trigger code fix (%d)", result);
+			dev_err(&intf->dev, "Error downloading trigger code fix (%d)\n", result);
 			goto err_fw;
 		}
 
 
 		if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
-			err("Error triggering firmware (%d)", result);
+			dev_err(&intf->dev, "Error triggering firmware (%d)\n",
+				result);
 			goto err_fw;
 		}
 
@@ -1091,7 +1102,7 @@
 	result = kaweth_read_configuration(kaweth);
 
 	if(result < 0) {
-		err("Error reading configuration (%d), no net device created", result);
+		dev_err(&intf->dev, "Error reading configuration (%d), no net device created\n", result);
 		goto err_free_netdev;
 	}
 
@@ -1103,7 +1114,7 @@
 	if(!memcmp(&kaweth->configuration.hw_addr,
                    &bcast_addr,
 		   sizeof(bcast_addr))) {
-		err("Firmware not functioning properly, no net device created");
+		dev_err(&intf->dev, "Firmware not functioning properly, no net device created\n");
 		goto err_free_netdev;
 	}
 
@@ -1113,7 +1124,7 @@
 	}
 
 	if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
-		err("Error setting SOFS wait");
+		dev_err(&intf->dev, "Error setting SOFS wait\n");
 		goto err_free_netdev;
 	}
 
@@ -1123,7 +1134,7 @@
                                            KAWETH_PACKET_FILTER_MULTICAST);
 
 	if(result < 0) {
-		err("Error setting receive filter");
+		dev_err(&intf->dev, "Error setting receive filter\n");
 		goto err_free_netdev;
 	}
 
@@ -1175,7 +1186,7 @@
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	if (register_netdev(netdev) != 0) {
-		err("Error registering netdev.");
+		dev_err(&intf->dev, "Error registering netdev.\n");
 		goto err_intfdata;
 	}
 
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index d363b31..65854cd 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -203,7 +203,8 @@
 	if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
 		if (ret == -ENODEV)
 			netif_device_detach(dev->netdev);
-		err("control request submission failed: %d", ret);
+		dev_err(&dev->udev->dev,
+			"control request submission failed: %d\n", ret);
 	} else
 		set_bit(RX_REG_SET, &dev->flags);
 
@@ -516,9 +517,9 @@
 	if (res == -ENODEV)
 		netif_device_detach(dev->netdev);
 	else if (res)
-		err ("can't resubmit intr, %s-%s/input0, status %d",
-				dev->udev->bus->bus_name,
-				dev->udev->devpath, res);
+		dev_err(&dev->udev->dev,
+			"can't resubmit intr, %s-%s/input0, status %d\n",
+			dev->udev->bus->bus_name, dev->udev->devpath, res);
 }
 
 static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
@@ -890,11 +891,11 @@
 	dev->intr_interval = 100;	/* 100ms */
 
 	if (!alloc_all_urbs(dev)) {
-		err("out of memory");
+		dev_err(&intf->dev, "out of memory\n");
 		goto out;
 	}
 	if (!rtl8150_reset(dev)) {
-		err("couldn't reset the device");
+		dev_err(&intf->dev, "couldn't reset the device\n");
 		goto out1;
 	}
 	fill_skb_pool(dev);
@@ -903,7 +904,7 @@
 	usb_set_intfdata(intf, dev);
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	if (register_netdev(netdev) != 0) {
-		err("couldn't register the device");
+		dev_err(&intf->dev, "couldn't register the device\n");
 		goto out2;
 	}
 
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4045e5a..cc741b3 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1955,7 +1955,7 @@
 	ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
 
 	if (ret < 0) {
-		err("CMD_SCAN failed: %d", ret);
+		wiphy_err(priv->hw->wiphy, "CMD_SCAN failed: %d\n", ret);
 		goto exit;
 	}
 
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 97d412d..32bd967f 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -68,8 +68,6 @@
 
 source "drivers/staging/serqt_usb2/Kconfig"
 
-source "drivers/staging/quatech_usb2/Kconfig"
-
 source "drivers/staging/vt6655/Kconfig"
 
 source "drivers/staging/vt6656/Kconfig"
@@ -132,4 +130,6 @@
 
 source "drivers/staging/ozwpan/Kconfig"
 
+source "drivers/staging/ccg/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index ffe7d44..eae8a21 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -25,7 +25,6 @@
 obj-$(CONFIG_IDE_PHISON)	+= phison/
 obj-$(CONFIG_LINE6_USB)		+= line6/
 obj-$(CONFIG_USB_SERIAL_QUATECH2)	+= serqt_usb2/
-obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)	+= quatech_usb2/
 obj-$(CONFIG_OCTEON_ETHERNET)	+= octeon/
 obj-$(CONFIG_VT6655)		+= vt6655/
 obj-$(CONFIG_VT6656)		+= vt6656/
@@ -57,3 +56,4 @@
 obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_RAMSTER)		+= ramster/
 obj-$(CONFIG_USB_WPAN_HCD)	+= ozwpan/
+obj-$(CONFIG_USB_G_CCG)		+= ccg/
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 83549d9..510d796 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -782,20 +782,20 @@
 	oled_class = class_create(THIS_MODULE, ASUS_OLED_UNDERSCORE_NAME);
 
 	if (IS_ERR(oled_class)) {
-		err("Error creating " ASUS_OLED_UNDERSCORE_NAME " class");
+		printk(KERN_ERR "Error creating " ASUS_OLED_UNDERSCORE_NAME " class\n");
 		return PTR_ERR(oled_class);
 	}
 
 	retval = class_create_file(oled_class, &class_attr_version.attr);
 	if (retval) {
-		err("Error creating class version file");
+		printk(KERN_ERR "Error creating class version file\n");
 		goto error;
 	}
 
 	retval = usb_register(&oled_driver);
 
 	if (retval) {
-		err("usb_register failed. Error number %d", retval);
+		printk(KERN_ERR "usb_register failed. Error number %d\n", retval);
 		goto error;
 	}
 
diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig
new file mode 100644
index 0000000..ff05e52
--- /dev/null
+++ b/drivers/staging/ccg/Kconfig
@@ -0,0 +1,20 @@
+if USB_GADGET
+
+config USB_G_CCG
+	tristate "Configurable Composite Gadget (STAGING)"
+	depends on STAGING && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM
+	help
+	  The Configurable Composite Gadget supports multiple USB
+	  functions: acm, mass storage, rndis and FunctionFS.
+	  Each function can be configured and enabled/disabled
+	  dynamically from userspace through a sysfs interface.
+
+	  In order to compile this (either as a module or built-in),
+	  "USB Gadget Drivers" and anything under it must not be
+	  selected compiled-in in
+	  Device Drivers->USB Support->USB Gadget Support.
+	  However, you can say "M" there, if you do, the
+	  Configurable Composite Gadget can be compiled "M" only
+	  or not at all.
+
+endif # USB_GADGET
diff --git a/drivers/staging/ccg/Makefile b/drivers/staging/ccg/Makefile
new file mode 100644
index 0000000..693da63
--- /dev/null
+++ b/drivers/staging/ccg/Makefile
@@ -0,0 +1,4 @@
+g_ccg-y				:= ccg.o
+ccflags-y			+= -Idrivers/usb/gadget
+
+obj-$(CONFIG_USB_G_CCG)		+= g_ccg.o
diff --git a/drivers/staging/ccg/TODO b/drivers/staging/ccg/TODO
new file mode 100644
index 0000000..18612fe
--- /dev/null
+++ b/drivers/staging/ccg/TODO
@@ -0,0 +1,6 @@
+TODO:
+	- change configuration interface from sysfs to configfs
+
+Please send patches to Greg Kroah-Hartmann <gregkh@linuxfoundation.org>,
+Andrzej Pietrasiewicz <andrzej.p@samsung.com>, and
+Cc: Mike Lockwood <lockwood@android.com>
diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c
new file mode 100644
index 0000000..a5b36a9
--- /dev/null
+++ b/drivers/staging/ccg/ccg.c
@@ -0,0 +1,1299 @@
+/*
+ * Configurable Composite Gadget
+ *
+ * Initially contributed as "Android Composite Gdaget" by:
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Mike Lockwood <lockwood@android.com>
+ *         Benoit Goby <benoit@android.com>
+ *
+ * Tailoring it to become a generic Configurable Composite Gadget is
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/platform_device.h>
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/composite.h>
+#include <linux/usb/gadget.h>
+
+#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module.  So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "../../usb/gadget/usbstring.c"
+#include "../../usb/gadget/config.c"
+#include "../../usb/gadget/epautoconf.c"
+#include "../../usb/gadget/composite.c"
+
+#include "../../usb/gadget/f_mass_storage.c"
+#include "../../usb/gadget/u_serial.c"
+#include "../../usb/gadget/f_acm.c"
+#define USB_ETH_RNDIS y
+#include "../../usb/gadget/f_rndis.c"
+#include "../../usb/gadget/rndis.c"
+#include "../../usb/gadget/u_ether.c"
+#include "../../usb/gadget/f_fs.c"
+
+MODULE_AUTHOR("Mike Lockwood, Andrzej Pietrasiewicz");
+MODULE_DESCRIPTION("Configurable Composite USB Gadget");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+
+static const char longname[] = "Configurable Composite Gadget";
+
+/* Default vendor and product IDs, overridden by userspace */
+#define VENDOR_ID		0x1d6b /* Linux Foundation */
+#define PRODUCT_ID		0x0107
+#define GFS_MAX_DEVS		10
+
+struct ccg_usb_function {
+	char *name;
+	void *config;
+
+	struct device *dev;
+	char *dev_name;
+	struct device_attribute **attributes;
+
+	/* for ccg_dev.enabled_functions */
+	struct list_head enabled_list;
+
+	/* Optional: initialization during gadget bind */
+	int (*init)(struct ccg_usb_function *, struct usb_composite_dev *);
+	/* Optional: cleanup during gadget unbind */
+	void (*cleanup)(struct ccg_usb_function *);
+
+	int (*bind_config)(struct ccg_usb_function *,
+			   struct usb_configuration *);
+
+	/* Optional: called when the configuration is removed */
+	void (*unbind_config)(struct ccg_usb_function *,
+			      struct usb_configuration *);
+	/* Optional: handle ctrl requests before the device is configured */
+	int (*ctrlrequest)(struct ccg_usb_function *,
+			   struct usb_composite_dev *,
+			   const struct usb_ctrlrequest *);
+};
+
+struct ffs_obj {
+	const char *name;
+	bool mounted;
+	bool desc_ready;
+	bool used;
+	struct ffs_data *ffs_data;
+};
+
+struct ccg_dev {
+	struct ccg_usb_function **functions;
+	struct list_head enabled_functions;
+	struct usb_composite_dev *cdev;
+	struct device *dev;
+
+	bool enabled;
+	struct mutex mutex;
+	bool connected;
+	bool sw_connected;
+	struct work_struct work;
+
+	unsigned int max_func_num;
+	unsigned int func_num;
+	struct ffs_obj ffs_tab[GFS_MAX_DEVS];
+};
+
+static struct class *ccg_class;
+static struct ccg_dev *_ccg_dev;
+static int ccg_bind_config(struct usb_configuration *c);
+static void ccg_unbind_config(struct usb_configuration *c);
+
+static char func_names_buf[256];
+
+static struct usb_device_descriptor device_desc = {
+	.bLength              = sizeof(device_desc),
+	.bDescriptorType      = USB_DT_DEVICE,
+	.bcdUSB               = __constant_cpu_to_le16(0x0200),
+	.bDeviceClass         = USB_CLASS_PER_INTERFACE,
+	.idVendor             = __constant_cpu_to_le16(VENDOR_ID),
+	.idProduct            = __constant_cpu_to_le16(PRODUCT_ID),
+	.bcdDevice            = __constant_cpu_to_le16(0xffff),
+	.bNumConfigurations   = 1,
+};
+
+static struct usb_configuration ccg_config_driver = {
+	.label		= "ccg",
+	.unbind		= ccg_unbind_config,
+	.bConfigurationValue = 1,
+	.bmAttributes	= USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+	.bMaxPower	= 0xFA, /* 500ma */
+};
+
+static void ccg_work(struct work_struct *data)
+{
+	struct ccg_dev *dev = container_of(data, struct ccg_dev, work);
+	struct usb_composite_dev *cdev = dev->cdev;
+	static char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
+	static char *connected[2]    = { "USB_STATE=CONNECTED", NULL };
+	static char *configured[2]   = { "USB_STATE=CONFIGURED", NULL };
+	char **uevent_envp = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	if (cdev->config)
+		uevent_envp = configured;
+	else if (dev->connected != dev->sw_connected)
+		uevent_envp = dev->connected ? connected : disconnected;
+	dev->sw_connected = dev->connected;
+	spin_unlock_irqrestore(&cdev->lock, flags);
+
+	if (uevent_envp) {
+		kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
+		pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
+	} else {
+		pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
+			 dev->connected, dev->sw_connected, cdev->config);
+	}
+}
+
+
+/*-------------------------------------------------------------------------*/
+/* Supported functions initialization */
+
+static struct ffs_obj *functionfs_find_dev(struct ccg_dev *dev,
+					   const char *dev_name)
+{
+	int i;
+
+	for (i = 0; i < dev->max_func_num; i++)
+		if (strcmp(dev->ffs_tab[i].name, dev_name) == 0)
+			return &dev->ffs_tab[i];
+
+	return NULL;
+}
+
+static bool functionfs_all_ready(struct ccg_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < dev->max_func_num; i++)
+		if (dev->ffs_tab[i].used && !dev->ffs_tab[i].desc_ready)
+			return false;
+
+	return true;
+}
+
+static int functionfs_ready_callback(struct ffs_data *ffs)
+{
+	struct ffs_obj *ffs_obj;
+	int ret;
+
+	mutex_lock(&_ccg_dev->mutex);
+
+	ffs_obj = ffs->private_data;
+	if (!ffs_obj) {
+		ret = -EINVAL;
+		goto done;
+	}
+	if (WARN_ON(ffs_obj->desc_ready)) {
+		ret = -EBUSY;
+		goto done;
+	}
+	ffs_obj->ffs_data = ffs;
+
+	if (functionfs_all_ready(_ccg_dev)) {
+		ret = -EBUSY;
+		goto done;
+	}
+	ffs_obj->desc_ready = true;
+
+done:
+	mutex_unlock(&_ccg_dev->mutex);
+	return ret;
+}
+
+static void reset_usb(struct ccg_dev *dev)
+{
+	/* Cancel pending control requests */
+	usb_ep_dequeue(dev->cdev->gadget->ep0, dev->cdev->req);
+	usb_remove_config(dev->cdev, &ccg_config_driver);
+	dev->enabled = false;
+	usb_gadget_disconnect(dev->cdev->gadget);
+}
+
+static void functionfs_closed_callback(struct ffs_data *ffs)
+{
+	struct ffs_obj *ffs_obj;
+
+	mutex_lock(&_ccg_dev->mutex);
+
+	ffs_obj = ffs->private_data;
+	if (!ffs_obj)
+		goto done;
+
+	ffs_obj->desc_ready = false;
+
+	if (_ccg_dev->enabled)
+		reset_usb(_ccg_dev);
+
+done:
+	mutex_unlock(&_ccg_dev->mutex);
+}
+
+static void *functionfs_acquire_dev_callback(const char *dev_name)
+{
+	struct ffs_obj *ffs_dev;
+
+	mutex_lock(&_ccg_dev->mutex);
+
+	ffs_dev = functionfs_find_dev(_ccg_dev, dev_name);
+	if (!ffs_dev) {
+		ffs_dev = ERR_PTR(-ENODEV);
+		goto done;
+	}
+
+	if (ffs_dev->mounted) {
+		ffs_dev = ERR_PTR(-EBUSY);
+		goto done;
+	}
+	ffs_dev->mounted = true;
+
+done:
+	mutex_unlock(&_ccg_dev->mutex);
+	return ffs_dev;
+}
+
+static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+{
+	struct ffs_obj *ffs_dev;
+
+	mutex_lock(&_ccg_dev->mutex);
+
+	ffs_dev = ffs_data->private_data;
+	if (ffs_dev)
+		ffs_dev->mounted = false;
+
+	mutex_unlock(&_ccg_dev->mutex);
+}
+
+static int functionfs_function_init(struct ccg_usb_function *f,
+				struct usb_composite_dev *cdev)
+{
+	return functionfs_init();
+}
+
+static void functionfs_function_cleanup(struct ccg_usb_function *f)
+{
+	functionfs_cleanup();
+}
+
+static int functionfs_function_bind_config(struct ccg_usb_function *f,
+					   struct usb_configuration *c)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	int i, ret;
+
+	for (i = dev->max_func_num; i--; ) {
+		if (!dev->ffs_tab[i].used)
+			continue;
+		ret = functionfs_bind(dev->ffs_tab[i].ffs_data, c->cdev);
+		if (unlikely(ret < 0)) {
+			while (++i < dev->max_func_num)
+				functionfs_unbind(dev->ffs_tab[i].ffs_data);
+			return ret;
+		}
+	}
+
+	for (i = dev->max_func_num; i--; ) {
+		if (!dev->ffs_tab[i].used)
+			continue;
+		ret = functionfs_bind_config(c->cdev, c,
+					     dev->ffs_tab[i].ffs_data);
+		if (unlikely(ret < 0))
+			return ret;
+	}
+
+	return 0;
+}
+
+static void functionfs_function_unbind_config(struct ccg_usb_function *f,
+					      struct usb_configuration *c)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	int i;
+
+	for (i = dev->max_func_num; i--; )
+		if (dev->ffs_tab[i].ffs_data)
+			functionfs_unbind(dev->ffs_tab[i].ffs_data);
+}
+
+static ssize_t functionfs_user_functions_show(struct device *_dev,
+					      struct device_attribute *attr,
+					      char *buf)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	char *buff = buf;
+	int i;
+
+	mutex_lock(&dev->mutex);
+
+	for (i = 0; i < dev->max_func_num; i++)
+		buff += snprintf(buff, PAGE_SIZE + buf - buff, "%s,",
+				 dev->ffs_tab[i].name);
+
+	mutex_unlock(&dev->mutex);
+
+	if (buff != buf)
+		*(buff - 1) = '\n';
+	return buff - buf;
+}
+
+static ssize_t functionfs_user_functions_store(struct device *_dev,
+					       struct device_attribute *attr,
+					       const char *buff, size_t size)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	char *name, *b;
+	ssize_t ret = size;
+	int i;
+
+	buff = skip_spaces(buff);
+	if (!*buff)
+		return -EINVAL;
+
+	mutex_lock(&dev->mutex);
+
+	if (dev->enabled) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	for (i = 0; i < dev->max_func_num; i++)
+		if (dev->ffs_tab[i].mounted) {
+			ret = -EBUSY;
+			goto end;
+		}
+
+	strlcpy(func_names_buf, buff, sizeof(func_names_buf));
+	b = strim(func_names_buf);
+
+	/* replace the list of functions */
+	dev->max_func_num = 0;
+	while (b) {
+		name = strsep(&b, ",");
+		if (dev->max_func_num == GFS_MAX_DEVS) {
+			ret = -ENOSPC;
+			goto end;
+		}
+		if (functionfs_find_dev(dev, name)) {
+			ret = -EEXIST;
+			continue;
+		}
+		dev->ffs_tab[dev->max_func_num++].name = name;
+	}
+
+end:
+	mutex_unlock(&dev->mutex);
+	return ret;
+}
+
+static DEVICE_ATTR(user_functions, S_IRUGO | S_IWUSR,
+		   functionfs_user_functions_show,
+		   functionfs_user_functions_store);
+
+static ssize_t functionfs_max_user_functions_show(struct device *_dev,
+						  struct device_attribute *attr,
+						  char *buf)
+{
+	return sprintf(buf, "%d", GFS_MAX_DEVS);
+}
+
+static DEVICE_ATTR(max_user_functions, S_IRUGO,
+		   functionfs_max_user_functions_show, NULL);
+
+static struct device_attribute *functionfs_function_attributes[] = {
+	&dev_attr_user_functions,
+	&dev_attr_max_user_functions,
+	NULL
+};
+
+static struct ccg_usb_function functionfs_function = {
+	.name		= "fs",
+	.init		= functionfs_function_init,
+	.cleanup	= functionfs_function_cleanup,
+	.bind_config	= functionfs_function_bind_config,
+	.unbind_config  = functionfs_function_unbind_config,
+	.attributes	= functionfs_function_attributes,
+};
+
+#define MAX_ACM_INSTANCES 4
+struct acm_function_config {
+	int instances;
+};
+
+static int
+acm_function_init(struct ccg_usb_function *f, struct usb_composite_dev *cdev)
+{
+	f->config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL);
+	if (!f->config)
+		return -ENOMEM;
+
+	return gserial_setup(cdev->gadget, MAX_ACM_INSTANCES);
+}
+
+static void acm_function_cleanup(struct ccg_usb_function *f)
+{
+	gserial_cleanup();
+	kfree(f->config);
+	f->config = NULL;
+}
+
+static int
+acm_function_bind_config(struct ccg_usb_function *f,
+		struct usb_configuration *c)
+{
+	int i;
+	int ret = 0;
+	struct acm_function_config *config = f->config;
+
+	for (i = 0; i < config->instances; i++) {
+		ret = acm_bind_config(c, i);
+		if (ret) {
+			pr_err("Could not bind acm%u config\n", i);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static ssize_t acm_instances_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct acm_function_config *config = f->config;
+	return sprintf(buf, "%d\n", config->instances);
+}
+
+static ssize_t acm_instances_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct acm_function_config *config = f->config;
+	int value;
+	int ret = 0;
+
+	ret = kstrtoint(buf, 10, &value);
+	if (ret)
+		return ret;
+
+	if (value > MAX_ACM_INSTANCES)
+		return -EINVAL;
+
+	config->instances = value;
+
+	return size;
+}
+
+static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show,
+						 acm_instances_store);
+static struct device_attribute *acm_function_attributes[] = {
+	&dev_attr_instances,
+	NULL
+};
+
+static struct ccg_usb_function acm_function = {
+	.name		= "acm",
+	.init		= acm_function_init,
+	.cleanup	= acm_function_cleanup,
+	.bind_config	= acm_function_bind_config,
+	.attributes	= acm_function_attributes,
+};
+
+struct rndis_function_config {
+	u8      ethaddr[ETH_ALEN];
+	u32     vendorID;
+	char	manufacturer[256];
+	/* "Wireless" RNDIS; auto-detected by Windows */
+	bool	wceis;
+};
+
+static int rndis_function_init(struct ccg_usb_function *f,
+			       struct usb_composite_dev *cdev)
+{
+	f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
+	if (!f->config)
+		return -ENOMEM;
+	return 0;
+}
+
+static void rndis_function_cleanup(struct ccg_usb_function *f)
+{
+	kfree(f->config);
+	f->config = NULL;
+}
+
+static int rndis_function_bind_config(struct ccg_usb_function *f,
+				      struct usb_configuration *c)
+{
+	int ret;
+	struct rndis_function_config *rndis = f->config;
+
+	if (!rndis) {
+		pr_err("%s: rndis_pdata\n", __func__);
+		return -1;
+	}
+
+	pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
+		rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
+		rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
+
+	ret = gether_setup_name(c->cdev->gadget, rndis->ethaddr, "rndis");
+	if (ret) {
+		pr_err("%s: gether_setup failed\n", __func__);
+		return ret;
+	}
+
+	if (rndis->wceis) {
+		/* "Wireless" RNDIS; auto-detected by Windows */
+		rndis_iad_descriptor.bFunctionClass =
+						USB_CLASS_WIRELESS_CONTROLLER;
+		rndis_iad_descriptor.bFunctionSubClass = 0x01;
+		rndis_iad_descriptor.bFunctionProtocol = 0x03;
+		rndis_control_intf.bInterfaceClass =
+						USB_CLASS_WIRELESS_CONTROLLER;
+		rndis_control_intf.bInterfaceSubClass =	 0x01;
+		rndis_control_intf.bInterfaceProtocol =	 0x03;
+	}
+
+	return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
+					   rndis->manufacturer);
+}
+
+static void rndis_function_unbind_config(struct ccg_usb_function *f,
+						struct usb_configuration *c)
+{
+	gether_cleanup();
+}
+
+static ssize_t rndis_manufacturer_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	return sprintf(buf, "%s\n", config->manufacturer);
+}
+
+static ssize_t rndis_manufacturer_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+
+	if (size >= sizeof(config->manufacturer))
+		return -EINVAL;
+	memcpy(config->manufacturer, buf, size);
+	config->manufacturer[size] = 0;
+
+	return size;
+}
+
+static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
+						    rndis_manufacturer_store);
+
+static ssize_t rndis_wceis_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	return sprintf(buf, "%d\n", config->wceis);
+}
+
+static ssize_t rndis_wceis_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	int value;
+	int ret;
+
+	ret = kstrtoint(buf, 10, &value);
+	if (ret)
+		return ret;
+
+	config->wceis = value;
+
+	return size;
+}
+
+static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
+					     rndis_wceis_store);
+
+static ssize_t rndis_ethaddr_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *rndis = f->config;
+	return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+		rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
+		rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
+}
+
+static ssize_t rndis_ethaddr_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *rndis = f->config;
+	unsigned char tmp[6];
+
+	if (sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+		   tmp + 0, tmp + 1, tmp + 2, tmp + 3, tmp + 4, tmp + 5) !=
+	    ETH_ALEN)
+		return -EINVAL;
+
+	memcpy(rndis->ethaddr, tmp, ETH_ALEN);
+
+	return ETH_ALEN;
+
+}
+
+static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
+					       rndis_ethaddr_store);
+
+static ssize_t rndis_vendorID_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	return sprintf(buf, "%04x\n", config->vendorID);
+}
+
+static ssize_t rndis_vendorID_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct ccg_usb_function *f = dev_get_drvdata(dev);
+	struct rndis_function_config *config = f->config;
+	int value;
+	int ret;
+
+	ret = kstrtou32(buf, 16, &value);
+	if (ret)
+		return ret;
+
+	config->vendorID = value;
+
+	return size;
+}
+
+static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
+						rndis_vendorID_store);
+
+static struct device_attribute *rndis_function_attributes[] = {
+	&dev_attr_manufacturer,
+	&dev_attr_wceis,
+	&dev_attr_ethaddr,
+	&dev_attr_vendorID,
+	NULL
+};
+
+static struct ccg_usb_function rndis_function = {
+	.name		= "rndis",
+	.init		= rndis_function_init,
+	.cleanup	= rndis_function_cleanup,
+	.bind_config	= rndis_function_bind_config,
+	.unbind_config	= rndis_function_unbind_config,
+	.attributes	= rndis_function_attributes,
+};
+
+static int mass_storage_function_init(struct ccg_usb_function *f,
+					struct usb_composite_dev *cdev)
+{
+	struct fsg_config fsg;
+	struct fsg_common *common;
+	int err;
+
+	memset(&fsg, 0, sizeof fsg);
+	fsg.nluns = 1;
+	fsg.luns[0].removable = 1;
+	fsg.vendor_name = iManufacturer;
+	fsg.product_name = iProduct;
+
+	common = fsg_common_init(NULL, cdev, &fsg);
+	if (IS_ERR(common))
+		return PTR_ERR(common);
+
+	err = sysfs_create_link(&f->dev->kobj,
+				&common->luns[0].dev.kobj,
+				"lun");
+	if (err) {
+		fsg_common_put(common);
+		return err;
+	}
+
+	f->config = common;
+	return 0;
+}
+
+static void mass_storage_function_cleanup(struct ccg_usb_function *f)
+{
+	fsg_common_put(f->config);
+	f->config = NULL;
+}
+
+static int mass_storage_function_bind_config(struct ccg_usb_function *f,
+					     struct usb_configuration *c)
+{
+	struct fsg_common *common = f->config;
+	return fsg_bind_config(c->cdev, c, common);
+}
+
+static struct ccg_usb_function mass_storage_function = {
+	.name		= "mass_storage",
+	.init		= mass_storage_function_init,
+	.cleanup	= mass_storage_function_cleanup,
+	.bind_config	= mass_storage_function_bind_config,
+};
+
+static struct ccg_usb_function *supported_functions[] = {
+	&functionfs_function,
+	&acm_function,
+	&rndis_function,
+	&mass_storage_function,
+	NULL
+};
+
+
+static int ccg_init_functions(struct ccg_usb_function **functions,
+				  struct usb_composite_dev *cdev)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	struct ccg_usb_function *f;
+	struct device_attribute **attrs;
+	struct device_attribute *attr;
+	int err;
+	int index = 0;
+
+	for (; (f = *functions++); index++) {
+		f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
+		if (!f->dev_name) {
+			pr_err("%s: Failed to alloc name %s", __func__,
+			       f->name);
+			err = -ENOMEM;
+			goto err_alloc;
+		}
+		f->dev = device_create(ccg_class, dev->dev,
+				MKDEV(0, index), f, f->dev_name);
+		if (IS_ERR(f->dev)) {
+			pr_err("%s: Failed to create dev %s", __func__,
+							f->dev_name);
+			err = PTR_ERR(f->dev);
+			f->dev = NULL;
+			goto err_create;
+		}
+
+		if (f->init) {
+			err = f->init(f, cdev);
+			if (err) {
+				pr_err("%s: Failed to init %s", __func__,
+								f->name);
+				goto err_out;
+			}
+		}
+
+		attrs = f->attributes;
+		if (attrs) {
+			while ((attr = *attrs++) && !err)
+				err = device_create_file(f->dev, attr);
+		}
+		if (err) {
+			pr_err("%s: Failed to create function %s attributes",
+					__func__, f->name);
+			goto err_uninit;
+		}
+	}
+	return 0;
+
+err_uninit:
+	if (f->cleanup)
+		f->cleanup(f);
+err_out:
+	device_destroy(ccg_class, f->dev->devt);
+	f->dev = NULL;
+err_create:
+	kfree(f->dev_name);
+err_alloc:
+	return err;
+}
+
+static void ccg_cleanup_functions(struct ccg_usb_function **functions)
+{
+	struct ccg_usb_function *f;
+
+	while (*functions) {
+		f = *functions++;
+
+		if (f->dev) {
+			if (f->cleanup)
+				f->cleanup(f);
+			device_destroy(ccg_class, f->dev->devt);
+			kfree(f->dev_name);
+		}
+	}
+}
+
+static int ccg_bind_enabled_functions(struct ccg_dev *dev,
+				      struct usb_configuration *c)
+{
+	struct ccg_usb_function *f;
+	int ret;
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
+		ret = f->bind_config(f, c);
+		if (ret) {
+			pr_err("%s: %s failed", __func__, f->name);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static void ccg_unbind_enabled_functions(struct ccg_dev *dev,
+					 struct usb_configuration *c)
+{
+	struct ccg_usb_function *f;
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list)
+		if (f->unbind_config)
+			f->unbind_config(f, c);
+}
+
+static int ccg_enable_function(struct ccg_dev *dev, char *name)
+{
+	struct ccg_usb_function **functions = dev->functions;
+	struct ccg_usb_function *f;
+	while ((f = *functions++)) {
+		if (!strcmp(name, f->name)) {
+			list_add_tail(&f->enabled_list,
+						&dev->enabled_functions);
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+/*-------------------------------------------------------------------------*/
+/* /sys/class/ccg_usb/ccg%d/ interface */
+
+static ssize_t
+functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
+{
+	struct ccg_dev *dev = dev_get_drvdata(pdev);
+	struct ccg_usb_function *f;
+	char *buff = buf;
+	int i;
+
+	mutex_lock(&dev->mutex);
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list)
+		buff += sprintf(buff, "%s,", f->name);
+	for (i = 0; i < dev->max_func_num; i++)
+		if (dev->ffs_tab[i].used)
+			buff += sprintf(buff, "%s", dev->ffs_tab[i].name);
+
+	mutex_unlock(&dev->mutex);
+
+	if (buff != buf)
+		*(buff-1) = '\n';
+	return buff - buf;
+}
+
+static ssize_t
+functions_store(struct device *pdev, struct device_attribute *attr,
+			       const char *buff, size_t size)
+{
+	struct ccg_dev *dev = dev_get_drvdata(pdev);
+	char *name;
+	char buf[256], *b;
+	int err, i;
+	bool functionfs_enabled;
+
+	buff = skip_spaces(buff);
+	if (!*buff)
+		return -EINVAL;
+
+	mutex_lock(&dev->mutex);
+
+	if (dev->enabled) {
+		mutex_unlock(&dev->mutex);
+		return -EBUSY;
+	}
+
+	INIT_LIST_HEAD(&dev->enabled_functions);
+	functionfs_enabled = false;
+	for (i = 0; i < dev->max_func_num; i++)
+		dev->ffs_tab[i].used = false;
+
+	strlcpy(buf, buff, sizeof(buf));
+	b = strim(buf);
+
+	while (b) {
+		struct ffs_obj *user_func;
+
+		name = strsep(&b, ",");
+		/* handle FunctionFS implicitly */
+		if (!strcmp(name, functionfs_function.name)) {
+			pr_err("ccg_usb: Cannot explicitly enable '%s'", name);
+			continue;
+		}
+		user_func = functionfs_find_dev(dev, name);
+		if (user_func)
+			name = functionfs_function.name;
+		err = 0;
+		if (!user_func || !functionfs_enabled)
+			err = ccg_enable_function(dev, name);
+		if (err)
+			pr_err("ccg_usb: Cannot enable '%s'", name);
+		else if (user_func) {
+			user_func->used = true;
+			dev->func_num++;
+			functionfs_enabled = true;
+		}
+	}
+
+	mutex_unlock(&dev->mutex);
+
+	return size;
+}
+
+static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct ccg_dev *dev = dev_get_drvdata(pdev);
+	return sprintf(buf, "%d\n", dev->enabled);
+}
+
+static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
+			    const char *buff, size_t size)
+{
+	struct ccg_dev *dev = dev_get_drvdata(pdev);
+	struct usb_composite_dev *cdev = dev->cdev;
+	int enabled = 0;
+
+	mutex_lock(&dev->mutex);
+	sscanf(buff, "%d", &enabled);
+	if (enabled && dev->func_num && !functionfs_all_ready(dev)) {
+		mutex_unlock(&dev->mutex);
+		return -ENODEV;
+	}
+
+	if (enabled && !dev->enabled) {
+		int ret;
+
+		cdev->next_string_id = 0;
+		/*
+		 * Update values in composite driver's copy of
+		 * device descriptor.
+		 */
+		cdev->desc.bDeviceClass = device_desc.bDeviceClass;
+		cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
+		cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
+		cdev->desc.idVendor = idVendor;
+		cdev->desc.idProduct = idProduct;
+		cdev->desc.bcdDevice = bcdDevice;
+
+		usb_add_config(cdev, &ccg_config_driver, ccg_bind_config);
+		dev->enabled = true;
+		ret = usb_gadget_connect(cdev->gadget);
+		if (ret) {
+			dev->enabled = false;
+			usb_remove_config(cdev, &ccg_config_driver);
+		}
+	} else if (!enabled && dev->enabled) {
+		reset_usb(dev);
+	} else {
+		pr_err("ccg_usb: already %s\n",
+			dev->enabled ? "enabled" : "disabled");
+	}
+
+	mutex_unlock(&dev->mutex);
+	return size;
+}
+
+static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct ccg_dev *dev = dev_get_drvdata(pdev);
+	struct usb_composite_dev *cdev = dev->cdev;
+	char *state = "DISCONNECTED";
+	unsigned long flags;
+
+	if (!cdev)
+		goto out;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	if (cdev->config)
+		state = "CONFIGURED";
+	else if (dev->connected)
+		state = "CONNECTED";
+	spin_unlock_irqrestore(&cdev->lock, flags);
+out:
+	return sprintf(buf, "%s\n", state);
+}
+
+#define DESCRIPTOR_ATTR(field, format_string)				\
+static ssize_t								\
+field ## _show(struct device *dev, struct device_attribute *attr,	\
+		char *buf)						\
+{									\
+	return sprintf(buf, format_string, device_desc.field);		\
+}									\
+static ssize_t								\
+field ## _store(struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t size)				\
+{									\
+	int value;							\
+	if (sscanf(buf, format_string, &value) == 1) {			\
+		device_desc.field = value;				\
+		return size;						\
+	}								\
+	return -1;							\
+}									\
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
+
+DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
+DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
+DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
+
+static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show,
+						 functions_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
+static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
+
+static struct device_attribute *ccg_usb_attributes[] = {
+	&dev_attr_bDeviceClass,
+	&dev_attr_bDeviceSubClass,
+	&dev_attr_bDeviceProtocol,
+	&dev_attr_functions,
+	&dev_attr_enable,
+	&dev_attr_state,
+	NULL
+};
+
+/*-------------------------------------------------------------------------*/
+/* Composite driver */
+
+static int ccg_bind_config(struct usb_configuration *c)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	int ret = 0;
+
+	ret = ccg_bind_enabled_functions(dev, c);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void ccg_unbind_config(struct usb_configuration *c)
+{
+	struct ccg_dev *dev = _ccg_dev;
+
+	ccg_unbind_enabled_functions(dev, c);
+
+	usb_ep_autoconfig_reset(dev->cdev->gadget);
+}
+
+static int ccg_bind(struct usb_composite_dev *cdev)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	struct usb_gadget	*gadget = cdev->gadget;
+	int			gcnum, ret;
+
+	/*
+	 * Start disconnected. Userspace will connect the gadget once
+	 * it is done configuring the functions.
+	 */
+	usb_gadget_disconnect(gadget);
+
+	ret = ccg_init_functions(dev->functions, cdev);
+	if (ret)
+		return ret;
+
+	gcnum = usb_gadget_controller_number(gadget);
+	if (gcnum >= 0)
+		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
+	else {
+		pr_warning("%s: controller '%s' not recognized\n",
+			longname, gadget->name);
+		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+	}
+
+	usb_gadget_set_selfpowered(gadget);
+	dev->cdev = cdev;
+
+	return 0;
+}
+
+static int ccg_usb_unbind(struct usb_composite_dev *cdev)
+{
+	struct ccg_dev *dev = _ccg_dev;
+
+	cancel_work_sync(&dev->work);
+	ccg_cleanup_functions(dev->functions);
+	return 0;
+}
+
+static struct usb_composite_driver ccg_usb_driver = {
+	.name		= "configurable_usb",
+	.dev		= &device_desc,
+	.unbind		= ccg_usb_unbind,
+	.needs_serial	= true,
+	.iManufacturer	= "Linux Foundation",
+	.iProduct	= longname,
+	.iSerialNumber	= "1234567890123456",
+};
+
+static int ccg_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
+{
+	struct ccg_dev		*dev = _ccg_dev;
+	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
+	struct usb_request		*req = cdev->req;
+	struct ccg_usb_function	*f;
+	int value = -EOPNOTSUPP;
+	unsigned long flags;
+
+	req->zero = 0;
+	req->complete = composite_setup_complete;
+	req->length = 0;
+	gadget->ep0->driver_data = cdev;
+
+	list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
+		if (f->ctrlrequest) {
+			value = f->ctrlrequest(f, cdev, c);
+			if (value >= 0)
+				break;
+		}
+	}
+
+	if (value < 0)
+		value = composite_setup(gadget, c);
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	if (!dev->connected) {
+		dev->connected = 1;
+		schedule_work(&dev->work);
+	} else if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
+						cdev->config) {
+		schedule_work(&dev->work);
+	}
+	spin_unlock_irqrestore(&cdev->lock, flags);
+
+	return value;
+}
+
+static void ccg_disconnect(struct usb_gadget *gadget)
+{
+	struct ccg_dev *dev = _ccg_dev;
+	struct usb_composite_dev *cdev = get_gadget_data(gadget);
+	unsigned long flags;
+
+	composite_disconnect(gadget);
+
+	spin_lock_irqsave(&cdev->lock, flags);
+	dev->connected = 0;
+	schedule_work(&dev->work);
+	spin_unlock_irqrestore(&cdev->lock, flags);
+}
+
+static int ccg_create_device(struct ccg_dev *dev)
+{
+	struct device_attribute **attrs = ccg_usb_attributes;
+	struct device_attribute *attr;
+	int err;
+
+	dev->dev = device_create(ccg_class, NULL, MKDEV(0, 0), NULL, "ccg0");
+	if (IS_ERR(dev->dev))
+		return PTR_ERR(dev->dev);
+
+	dev_set_drvdata(dev->dev, dev);
+
+	while ((attr = *attrs++)) {
+		err = device_create_file(dev->dev, attr);
+		if (err) {
+			device_destroy(ccg_class, dev->dev->devt);
+			return err;
+		}
+	}
+	return 0;
+}
+
+
+static int __init init(void)
+{
+	struct ccg_dev *dev;
+	int err;
+
+	ccg_class = class_create(THIS_MODULE, "ccg_usb");
+	if (IS_ERR(ccg_class))
+		return PTR_ERR(ccg_class);
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->functions = supported_functions;
+	INIT_LIST_HEAD(&dev->enabled_functions);
+	INIT_WORK(&dev->work, ccg_work);
+	mutex_init(&dev->mutex);
+
+	err = ccg_create_device(dev);
+	if (err) {
+		class_destroy(ccg_class);
+		kfree(dev);
+		return err;
+	}
+
+	_ccg_dev = dev;
+
+	/* Override composite driver functions */
+	composite_driver.setup = ccg_setup;
+	composite_driver.disconnect = ccg_disconnect;
+
+	err = usb_composite_probe(&ccg_usb_driver, ccg_bind);
+	if (err) {
+		class_destroy(ccg_class);
+		kfree(dev);
+	}
+
+	return err;
+}
+module_init(init);
+
+static void __exit cleanup(void)
+{
+	usb_composite_unregister(&ccg_usb_driver);
+	class_destroy(ccg_class);
+	kfree(_ccg_dev);
+	_ccg_dev = NULL;
+}
+module_exit(cleanup);
diff --git a/drivers/staging/ccg/sysfs-class-ccg_usb b/drivers/staging/ccg/sysfs-class-ccg_usb
new file mode 100644
index 0000000..dd12a33
--- /dev/null
+++ b/drivers/staging/ccg/sysfs-class-ccg_usb
@@ -0,0 +1,158 @@
+What:		/sys/class/ccg_usb
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The ccg_usb/ class subdirectory belongs to ccg
+		USB gadget.
+
+What:		/sys/class/ccg_usb/ccgX
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccg{0,1,2,3...} class
+		subdirectories correspond to each ccg gadget device;
+		at the time of this writing there is only ccg0 and it
+		represents the ccg gadget.
+
+What:		/sys/class/ccg_usb/ccgX/functions
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		A comma-separated list of USB function names to be activated
+		in this ccg gadget. It includes both the functions provided
+		in-kernel by the ccg gadget and the functions provided from
+		userspace through FunctionFS.
+
+What:		/sys/class/ccg_usb/ccgX/enable
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		A flag activating/deactivating the ccg usb gadget.
+
+What:		/sys/class/ccg_usb/ccgX/state
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		Configurable usb gadget state:
+
+		DISCONNECTED
+		CONNECTED
+		CONFIGURED
+
+What:		/sys/class/ccg_usb/ccgX/f_acm/
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccgX/f_acm subdirectory
+		corresponds to the gadget's USB CDC serial (ACM) function
+		driver.
+
+What:		/sys/class/ccg_usb/ccgX/f_acm/instances
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		Maximum number of the /dev/ttyGS<X> interface the driver uses.
+
+What:		/sys/class/ccg_usb/ccgX/f_fs
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccgX/f_fs subdirectory
+		corresponds to the gadget's FunctionFS driver.
+
+What:		/sys/class/ccg_usb/ccgX/f_fs/user_functions
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		A comma-separeted list of USB function names to be supported
+		from userspace. No other userspace FunctionFS functions can
+		be supported than listed here. However, the actual activation
+		of these functions is still done through
+		/sys/class/ccg_usb/ccgX/functions, where it is possible
+		to specify any subset (including maximum and empty) of
+		/sys/class/ccg_usb/ccgX/f_fs/user_functions.
+
+What:		/sys/class/ccg_usb/ccgX/f_fs/max_user_functions
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		Maximum number of USB functions to be supported from userspace.
+
+What:		/sys/class/ccg_usb/ccgX/f_rndis
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccgX/f_rndis subdirectory
+		corresponds to the gadget's RNDIS driver.
+
+What:		/sys/class/ccg_usb/ccgX/f_rndis/manufacturer
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		RNDIS Ethernet port manufacturer string.
+
+What:		/sys/class/ccg_usb/ccgX/f_rndis/wceis
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		RNDIS Ethernet port wireless flag.
+
+What:		/sys/class/ccg_usb/ccgX/f_rndis/ethaddr
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		RNDIS Ethernet port Ethernet address.
+
+What:		/sys/class/ccg_usb/ccgX/f_rndis/vendorID
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		RNDIS Ethernet port vendor ID.
+
+What:		/sys/class/ccg_usb/ccgX/f_mass_storage
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccgX/f_mass_storage subdirectory
+		corresponds to the gadget's USB mass storage driver.
+
+What:		/sys/class/ccg_usb/ccgX/f_mass_storage/lun
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccgX/f_mass_storage/lun
+		subdirectory corresponds to the gadget's USB mass storage
+		driver and its underlying storage.
+
+What:		/sys/class/ccg_usb/ccgX/f_mass_storage/lun
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		The /sys/class/ccg_usb/ccgX/f_mass_storage/lun
+		subdirectory corresponds to the gadget's USB mass storage
+		driver and its underlying storage.
+
+What:		/sys/class/ccg_usb/ccgX/f_mass_storage/lun/file
+Date:		May 2012
+KernelVersion:	3.4
+Contact:	linux-usb@vger.kernel.org
+Description:
+		Gadget's USB mass storage underlying file.
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index e86ab58..89a49dd 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -547,7 +547,7 @@
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
 		break;
 	default:
-		err("Illegal gain %d\n", gain);
+		dev_err(&dev->interface->dev, "Illegal gain %d\n", gain);
 
 	}
 }
@@ -715,7 +715,7 @@
 	iface_desc = interface->cur_altsetting;
 
 	if (iface_desc->desc.bNumEndpoints != 5) {
-		err("Wrong number of endpints.");
+		dev_err(&interface->dev, "Wrong number of endpoints.\n");
 		retval = -ENODEV;
 		goto error;
 	}
@@ -781,22 +781,22 @@
 	}
 
 	if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) {
-		err("Failed to read vendor.");
+		dev_err(&interface->dev, "Failed to read vendor.\n");
 		retval = -ENODEV;
 		goto error;
 	}
 	if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) {
-		err("Failed to read product.");
+		dev_err(&interface->dev, "Failed to read product.\n");
 		retval = -ENODEV;
 		goto error;
 	}
 	if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) {
-		err("Failed to read device.");
+		dev_err(&interface->dev, "Failed to read device.\n");
 		retval = -ENODEV;
 		goto error;
 	}
 	if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) {
-		err("Failed to read serial.");
+		dev_err(&interface->dev, "Failed to read serial.\n");
 		retval = -ENODEV;
 		goto error;
 	}
@@ -1146,7 +1146,9 @@
 	result = comedi_driver_register(&dt9812_comedi_driver);
 	if (result) {
 		usb_deregister(&dt9812_usb_driver);
-		err("comedi_driver_register failed. Error number %d", result);
+		printk(KERN_ERR KBUILD_MODNAME
+			": comedi_driver_register failed. Error number %d\n",
+			result);
 	}
 
 	return result;
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 3d13ca6e1..2dba3ef 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -295,7 +295,9 @@
 		if (!usb_submit_urb(urb, GFP_KERNEL))
 			goto exit;
 
-		err("comedi#: vmk80xx: %s - submit urb failed\n", __func__);
+		dev_err(&urb->dev->dev,
+			"comedi#: vmk80xx: %s - submit urb failed\n",
+			__func__);
 
 		usb_unanchor_urb(urb);
 	}
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 3bf0f40e..acbb2cc 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -333,8 +333,8 @@
 	interface = usb_find_interface(&usb_alphatrack_driver, subminor);
 
 	if (!interface) {
-		err("%s - error, can't find device for minor %d\n",
-		    __func__, subminor);
+		printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+		       __func__, subminor);
 		retval = -ENODEV;
 		goto unlock_disconnect_exit;
 	}
@@ -494,7 +494,8 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->intf == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d\n", retval);
+		printk(KERN_ERR "%s: No device or device unplugged %d\n",
+		       __func__, retval);
 		goto unlock_exit;
 	}
 
@@ -564,7 +565,8 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->intf == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d\n", retval);
+		printk(KERN_ERR "%s: No device or device unplugged %d\n",
+		       __func__, retval);
 		goto unlock_exit;
 	}
 
@@ -599,7 +601,7 @@
 	}
 
 	if (dev->interrupt_out_endpoint == NULL) {
-		err("Endpoint should not be be null!\n");
+		dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
 		goto unlock_exit;
 	}
 
@@ -619,7 +621,8 @@
 	retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
 	if (retval) {
 		dev->interrupt_out_busy = 0;
-		err("Couldn't submit interrupt_out_urb %d\n", retval);
+		dev_err(&dev->intf->dev,
+			"Couldn't submit interrupt_out_urb %d\n", retval);
 		atomic_dec(&dev->writes_pending);
 		goto unlock_exit;
 	}
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index 29e99bb..376706f 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -353,7 +353,7 @@
 	interface = usb_find_interface(&usb_tranzport_driver, subminor);
 
 	if (!interface) {
-		err("%s - error, can't find device for minor %d\n",
+		printk(KERN_ERR "%s - error, can't find device for minor %d\n",
 			__func__, subminor);
 		retval = -ENODEV;
 		goto unlock_disconnect_exit;
@@ -517,9 +517,11 @@
 		goto exit;
 	}
 
-	/* verify that the device wasn't unplugged */ if (dev->intf == NULL) {
+	/* verify that the device wasn't unplugged */
+	if (dev->intf == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d\n", retval);
+		printk(KERN_ERR "%s: No device or device unplugged %d\n",
+			__func__, retval);
 		goto unlock_exit;
 	}
 
@@ -691,7 +693,8 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->intf == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d\n", retval);
+		printk(KERN_ERR "%s: No device or device unplugged %d\n",
+			__func__, retval);
 		goto unlock_exit;
 	}
 
@@ -726,7 +729,7 @@
 	}
 
 	if (dev->interrupt_out_endpoint == NULL) {
-		err("Endpoint should not be be null!\n");
+		dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
 		goto unlock_exit;
 	}
 
@@ -746,7 +749,8 @@
 	retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
 	if (retval) {
 		dev->interrupt_out_busy = 0;
-		err("Couldn't submit interrupt_out_urb %d\n", retval);
+		dev_err(&dev->intf->dev,
+			"Couldn't submit interrupt_out_urb %d\n", retval);
 		goto unlock_exit;
 	}
 	retval = bytes_to_write;
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index e8023af..2e602e1 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -1307,7 +1307,8 @@
 	retval = usb_register(&line6_driver);
 
 	if (retval) {
-		err("usb_register failed. Error number %d", retval);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": usb_register failed. Error number %d\n", retval);
 		return retval;
 	}
 
@@ -1315,7 +1316,7 @@
 					GFP_KERNEL);
 
 	if (line6_request_version == NULL) {
-		err("Out of memory");
+		printk(KERN_ERR KBUILD_MODNAME ":Out of memory\n");
 		return -ENOMEM;
 	}
 
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index b754f69..31b624b 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -168,7 +168,7 @@
 			      cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
 
 	if (ret < 0) {
-		err("send failed (error %d)\n", ret);
+		dev_err(&usbdev->dev, "send failed (error %d)\n", ret);
 		return ret;
 	}
 
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
index ea4f992..ac92eaf 100644
--- a/drivers/staging/media/as102/as102_drv.c
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -279,40 +279,8 @@
 	pr_info("Unregistered device %s", as102_dev->name);
 }
 
-static int __init as102_driver_init(void)
-{
-	int ret;
+module_usb_driver(as102_usb_driver);
 
-	/* register this driver with the low level subsystem */
-	ret = usb_register(&as102_usb_driver);
-	if (ret)
-		err("usb_register failed (ret = %d)", ret);
-
-	return ret;
-}
-
-/*
- * Mandatory function : Adds a special section to the module indicating
- * where initialisation function is defined
- */
-module_init(as102_driver_init);
-
-/**
- * as102_driver_exit - as102 driver exit point
- *
- * This function is called when device has to be removed.
- */
-static void __exit as102_driver_exit(void)
-{
-	/* deregister this driver with the low level bus subsystem */
-	usb_deregister(&as102_usb_driver);
-}
-
-/*
- * required function for unload: Adds a special section to the module
- * indicating where unload function is defined
- */
-module_exit(as102_driver_exit);
 /* modinfo details */
 MODULE_DESCRIPTION(DRIVER_FULL_NAME);
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
index 0f6bfe7..6875c88 100644
--- a/drivers/staging/media/as102/as102_usb_drv.c
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -375,7 +375,7 @@
 
 	as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL);
 	if (as102_dev == NULL) {
-		err("%s: kzalloc failed", __func__);
+		dev_err(&intf->dev, "%s: kzalloc failed\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -411,8 +411,9 @@
 	ret = usb_register_dev(intf, &as102_usb_class_driver);
 	if (ret < 0) {
 		/* something prevented us from registering this driver */
-		err("%s: usb_register_dev() failed (errno = %d)",
-		    __func__, ret);
+		dev_err(&intf->dev,
+			"%s: usb_register_dev() failed (errno = %d)\n",
+			__func__, ret);
 		goto failed;
 	}
 
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index d0fe34a..6f83d36 100644
--- a/drivers/staging/media/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
@@ -3578,7 +3578,8 @@
 
 		if (0 != (video_register_device(&(peasycap->video_device),
 							VFL_TYPE_GRABBER, -1))) {
-			err("Not able to register with videodev");
+			dev_err(&intf->dev,
+				"Not able to register with videodev\n");
 			videodev_release(&(peasycap->video_device));
 			return -ENODEV;
 		}
@@ -3822,7 +3823,8 @@
 
 		rc = easycap_alsa_probe(peasycap);
 		if (rc) {
-			err("easycap_alsa_probe() rc = %i\n", rc);
+			dev_err(&intf->dev, "easycap_alsa_probe() rc = %i\n",
+				rc);
 			return -ENODEV;
 		}
 
diff --git a/drivers/staging/media/go7007/go7007.txt b/drivers/staging/media/go7007/go7007.txt
index 9db1f39..fcb3e23 100644
--- a/drivers/staging/media/go7007/go7007.txt
+++ b/drivers/staging/media/go7007/go7007.txt
@@ -87,7 +87,6 @@
 	CONFIG_SOUND             - Sound card support
 	CONFIG_SND               - Advanced Linux Sound Architecture
 	CONFIG_USB               - Support for Host-side USB
-	CONFIG_USB_DEVICEFS      - USB device filesystem
 	CONFIG_USB_EHCI_HCD      - EHCI HCD (USB 2.0) support
 
 Additionally, to use the example application, the following options need to
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index 5f7f8cd..d7cf5ef 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -209,8 +209,9 @@
 
 	retval = lirc_unregister_driver(minor);
 	if (retval)
-		err("%s: unable to deregister from lirc(%d)",
-			__func__, retval);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: unable to deregister from lirc(%d)",
+		       __func__, retval);
 	else
 		printk(KERN_INFO MOD_NAME ": Deregistered iMON driver "
 		       "(minor:%d)\n", minor);
@@ -234,16 +235,18 @@
 	subminor = iminor(inode);
 	interface = usb_find_interface(&imon_driver, subminor);
 	if (!interface) {
-		err("%s: could not find interface for minor %d",
-		    __func__, subminor);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: could not find interface for minor %d\n",
+		       __func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
 	context = usb_get_intfdata(interface);
 
 	if (!context) {
-		err("%s: no context found for minor %d",
-					__func__, subminor);
+		dev_err(&interface->dev,
+			"%s: no context found for minor %d\n",
+			__func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
@@ -251,10 +254,12 @@
 	mutex_lock(&context->ctx_lock);
 
 	if (!context->display) {
-		err("%s: display not supported by device", __func__);
+		dev_err(&interface->dev,
+			"%s: display not supported by device\n", __func__);
 		retval = -ENODEV;
 	} else if (context->display_isopen) {
-		err("%s: display port is already open", __func__);
+		dev_err(&interface->dev,
+			"%s: display port is already open\n", __func__);
 		retval = -EBUSY;
 	} else {
 		context->display_isopen = 1;
@@ -281,17 +286,20 @@
 	context = file->private_data;
 
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       "%s: no context for device\n", __func__);
 		return -ENODEV;
 	}
 
 	mutex_lock(&context->ctx_lock);
 
 	if (!context->display) {
-		err("%s: display not supported by device", __func__);
+		dev_err(&context->usbdev->dev,
+			"%s: display not supported by device\n", __func__);
 		retval = -ENODEV;
 	} else if (!context->display_isopen) {
-		err("%s: display is not open", __func__);
+		dev_err(&context->usbdev->dev,
+			"%s: display is not open\n", __func__);
 		retval = -EIO;
 	} else {
 		context->display_isopen = 0;
@@ -340,19 +348,23 @@
 	retval = usb_submit_urb(context->tx_urb, GFP_KERNEL);
 	if (retval) {
 		atomic_set(&(context->tx.busy), 0);
-		err("%s: error submitting urb(%d)", __func__, retval);
+		dev_err(&context->usbdev->dev,
+			"%s: error submitting urb(%d)\n", __func__, retval);
 	} else {
 		/* Wait for transmission to complete (or abort) */
 		mutex_unlock(&context->ctx_lock);
 		retval = wait_for_completion_interruptible(
 				&context->tx.finished);
 		if (retval)
-			err("%s: task interrupted", __func__);
+			dev_err(&context->usbdev->dev,
+				"%s: task interrupted\n", __func__);
 		mutex_lock(&context->ctx_lock);
 
 		retval = context->tx.status;
 		if (retval)
-			err("%s: packet tx failed (%d)", __func__, retval);
+			dev_err(&context->usbdev->dev,
+				"%s: packet tx failed (%d)\n",
+				__func__, retval);
 	}
 
 	return retval;
@@ -383,20 +395,23 @@
 
 	context = file->private_data;
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       "%s: no context for device\n", __func__);
 		return -ENODEV;
 	}
 
 	mutex_lock(&context->ctx_lock);
 
 	if (!context->dev_present) {
-		err("%s: no iMON device present", __func__);
+		dev_err(&context->usbdev->dev,
+			"%s: no iMON device present\n", __func__);
 		retval = -ENODEV;
 		goto exit;
 	}
 
 	if (n_bytes <= 0 || n_bytes > IMON_DATA_BUF_SZ - 3) {
-		err("%s: invalid payload size", __func__);
+		dev_err(&context->usbdev->dev,
+			"%s: invalid payload size\n", __func__);
 		retval = -EINVAL;
 		goto exit;
 	}
@@ -425,8 +440,9 @@
 
 		retval = send_packet(context);
 		if (retval) {
-			err("%s: send packet failed for packet #%d",
-					__func__, seq/2);
+			dev_err(&context->usbdev->dev,
+				"%s: send packet failed for packet #%d\n",
+				__func__, seq/2);
 			goto exit;
 		} else {
 			seq += 2;
@@ -441,7 +457,8 @@
 		context->usb_tx_buf[7] = (unsigned char) seq;
 		retval = send_packet(context);
 		if (retval)
-			err("%s: send packet failed for packet #%d",
+			dev_err(&context->usbdev->dev,
+				"%s: send packet failed for packet #%d\n",
 					__func__, seq/2);
 	}
 
@@ -508,7 +525,8 @@
 
 	context = (struct imon_context *)data;
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       "%s: no context for device\n", __func__);
 		return;
 	}
 
@@ -732,7 +750,7 @@
 
 	context = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
 	if (!context) {
-		err("%s: kzalloc failed for context", __func__);
+		dev_err(dev, "%s: kzalloc failed for context\n", __func__);
 		alloc_status = 1;
 		goto alloc_status_switch;
 	}
@@ -797,7 +815,7 @@
 
 	/* Input endpoint is mandatory */
 	if (!ir_ep_found) {
-		err("%s: no valid input (IR) endpoint found.", __func__);
+		dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__);
 		retval = -ENODEV;
 		alloc_status = 2;
 		goto alloc_status_switch;
@@ -814,30 +832,30 @@
 
 	driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
 	if (!driver) {
-		err("%s: kzalloc failed for lirc_driver", __func__);
+		dev_err(dev, "%s: kzalloc failed for lirc_driver\n", __func__);
 		alloc_status = 2;
 		goto alloc_status_switch;
 	}
 	rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
 	if (!rbuf) {
-		err("%s: kmalloc failed for lirc_buffer", __func__);
+		dev_err(dev, "%s: kmalloc failed for lirc_buffer\n", __func__);
 		alloc_status = 3;
 		goto alloc_status_switch;
 	}
 	if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
-		err("%s: lirc_buffer_init failed", __func__);
+		dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
 		alloc_status = 4;
 		goto alloc_status_switch;
 	}
 	rx_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!rx_urb) {
-		err("%s: usb_alloc_urb failed for IR urb", __func__);
+		dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__);
 		alloc_status = 5;
 		goto alloc_status_switch;
 	}
 	tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!tx_urb) {
-		err("%s: usb_alloc_urb failed for display urb",
+		dev_err(dev, "%s: usb_alloc_urb failed for display urb\n",
 		    __func__);
 		alloc_status = 6;
 		goto alloc_status_switch;
@@ -865,7 +883,7 @@
 
 	lirc_minor = lirc_register_driver(driver);
 	if (lirc_minor < 0) {
-		err("%s: lirc_register_driver failed", __func__);
+		dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
 		alloc_status = 7;
 		goto unlock;
 	} else
@@ -900,8 +918,8 @@
 	retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
 
 	if (retval) {
-		err("%s: usb_submit_urb failed for intf0 (%d)",
-		    __func__, retval);
+		dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n",
+			__func__, retval);
 		mutex_unlock(&context->ctx_lock);
 		goto exit;
 	}
diff --git a/drivers/staging/media/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c
index 7442104..352a202 100644
--- a/drivers/staging/media/lirc/lirc_sasem.c
+++ b/drivers/staging/media/lirc/lirc_sasem.c
@@ -185,7 +185,7 @@
 
 	retval = lirc_unregister_driver(minor);
 	if (retval)
-		err("%s: unable to deregister from lirc (%d)",
+		printk(KERN_ERR "%s: unable to deregister from lirc (%d)\n",
 			__func__, retval);
 	else
 		printk(KERN_INFO "Deregistered Sasem driver (minor:%d)\n",
@@ -210,16 +210,18 @@
 	subminor = iminor(inode);
 	interface = usb_find_interface(&sasem_driver, subminor);
 	if (!interface) {
-		err("%s: could not find interface for minor %d",
-		    __func__, subminor);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: could not find interface for minor %d\n",
+		       __func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
 	context = usb_get_intfdata(interface);
 
 	if (!context) {
-		err("%s: no context found for minor %d",
-					__func__, subminor);
+		dev_err(&interface->dev,
+			"%s: no context found for minor %d\n",
+			__func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
@@ -227,12 +229,13 @@
 	mutex_lock(&context->ctx_lock);
 
 	if (context->vfd_isopen) {
-		err("%s: VFD port is already open", __func__);
+		dev_err(&interface->dev,
+			"%s: VFD port is already open", __func__);
 		retval = -EBUSY;
 	} else {
 		context->vfd_isopen = 1;
 		file->private_data = context;
-		printk(KERN_INFO "VFD port opened\n");
+		dev_info(&interface->dev, "VFD port opened\n");
 	}
 
 	mutex_unlock(&context->ctx_lock);
@@ -253,7 +256,8 @@
 	context = (struct sasem_context *) file->private_data;
 
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: no context for device\n", __func__);
 		return -ENODEV;
 	}
 
@@ -287,14 +291,15 @@
 	context = (struct sasem_context *) file->private_data;
 
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: no context for device\n", __func__);
 		return -ENODEV;
 	}
 
 	mutex_lock(&context->ctx_lock);
 
 	if (!context->vfd_isopen) {
-		err("%s: VFD is not open", __func__);
+		dev_err(&context->dev->dev, "%s: VFD is not open\n", __func__);
 		retval = -EIO;
 	} else {
 		context->vfd_isopen = 0;
@@ -339,7 +344,8 @@
 	retval =  usb_submit_urb(context->tx_urb, GFP_KERNEL);
 	if (retval) {
 		atomic_set(&(context->tx.busy), 0);
-		err("%s: error submitting urb (%d)", __func__, retval);
+		dev_err(&context->dev->dev, "%s: error submitting urb (%d)\n",
+			__func__, retval);
 	} else {
 		/* Wait for transmission to complete (or abort) */
 		mutex_unlock(&context->ctx_lock);
@@ -348,7 +354,9 @@
 
 		retval = context->tx.status;
 		if (retval)
-			err("%s: packet tx failed (%d)", __func__, retval);
+			dev_err(&context->dev->dev,
+				"%s: packet tx failed (%d)\n",
+				__func__, retval);
 	}
 
 	return retval;
@@ -369,20 +377,23 @@
 
 	context = (struct sasem_context *) file->private_data;
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: no context for device\n", __func__);
 		return -ENODEV;
 	}
 
 	mutex_lock(&context->ctx_lock);
 
 	if (!context->dev_present) {
-		err("%s: no Sasem device present", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: no Sasem device present\n", __func__);
 		retval = -ENODEV;
 		goto exit;
 	}
 
 	if (n_bytes <= 0 || n_bytes > SASEM_DATA_BUF_SZ) {
-		err("%s: invalid payload size", __func__);
+		dev_err(&context->dev->dev, "%s: invalid payload size\n",
+			__func__);
 		retval = -EINVAL;
 		goto exit;
 	}
@@ -440,9 +451,9 @@
 		}
 		retval = send_packet(context);
 		if (retval) {
-
-			err("%s: send packet failed for packet #%d",
-					__func__, i);
+			dev_err(&context->dev->dev,
+				"%s: send packet failed for packet #%d\n",
+				__func__, i);
 			goto exit;
 		}
 	}
@@ -492,7 +503,8 @@
 	mutex_lock(&context->ctx_lock);
 
 	if (context->ir_isopen) {
-		err("%s: IR port is already open", __func__);
+		dev_err(&context->dev->dev, "%s: IR port is already open\n",
+			__func__);
 		retval = -EBUSY;
 		goto exit;
 	}
@@ -506,8 +518,9 @@
 	retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
 
 	if (retval)
-		err("%s: usb_submit_urb failed for ir_open (%d)",
-		    __func__, retval);
+		dev_err(&context->dev->dev,
+			"%s: usb_submit_urb failed for ir_open (%d)\n",
+			__func__, retval);
 	else {
 		context->ir_isopen = 1;
 		printk(KERN_INFO "IR port opened\n");
@@ -529,7 +542,8 @@
 
 	context = (struct sasem_context *)data;
 	if (!context) {
-		err("%s: no context for device", __func__);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": %s: no context for device\n", __func__);
 		return;
 	}
 
@@ -687,7 +701,7 @@
 	struct sasem_context *context = NULL;
 	int i;
 
-	printk(KERN_INFO "%s: found Sasem device\n", __func__);
+	dev_info(&interface->dev, "%s: found Sasem device\n", __func__);
 
 
 	dev = usb_get_dev(interface_to_usbdev(interface));
@@ -719,8 +733,8 @@
 			rx_endpoint = ep;
 			ir_ep_found = 1;
 			if (debug)
-				printk(KERN_INFO "%s: found IR endpoint\n",
-				       __func__);
+				dev_info(&interface->dev,
+					"%s: found IR endpoint\n", __func__);
 
 		} else if (!vfd_ep_found &&
 			ep_dir == USB_DIR_OUT &&
@@ -729,22 +743,23 @@
 			tx_endpoint = ep;
 			vfd_ep_found = 1;
 			if (debug)
-				printk(KERN_INFO "%s: found VFD endpoint\n",
-				       __func__);
+				dev_info(&interface->dev,
+					"%s: found VFD endpoint\n", __func__);
 		}
 	}
 
 	/* Input endpoint is mandatory */
 	if (!ir_ep_found) {
-
-		err("%s: no valid input (IR) endpoint found.", __func__);
+		dev_err(&interface->dev,
+			"%s: no valid input (IR) endpoint found.\n", __func__);
 		retval = -ENODEV;
 		goto exit;
 	}
 
 	if (!vfd_ep_found)
-		printk(KERN_INFO "%s: no valid output (VFD) endpoint found.\n",
-		       __func__);
+		dev_info(&interface->dev,
+			"%s: no valid output (VFD) endpoint found.\n",
+			__func__);
 
 
 	/* Allocate memory */
@@ -752,38 +767,44 @@
 
 	context = kzalloc(sizeof(struct sasem_context), GFP_KERNEL);
 	if (!context) {
-		err("%s: kzalloc failed for context", __func__);
+		dev_err(&interface->dev,
+			"%s: kzalloc failed for context\n", __func__);
 		alloc_status = 1;
 		goto alloc_status_switch;
 	}
 	driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
 	if (!driver) {
-		err("%s: kzalloc failed for lirc_driver", __func__);
+		dev_err(&interface->dev,
+			"%s: kzalloc failed for lirc_driver\n", __func__);
 		alloc_status = 2;
 		goto alloc_status_switch;
 	}
 	rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
 	if (!rbuf) {
-		err("%s: kmalloc failed for lirc_buffer", __func__);
+		dev_err(&interface->dev,
+			"%s: kmalloc failed for lirc_buffer\n", __func__);
 		alloc_status = 3;
 		goto alloc_status_switch;
 	}
 	if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
-		err("%s: lirc_buffer_init failed", __func__);
+		dev_err(&interface->dev,
+			"%s: lirc_buffer_init failed\n", __func__);
 		alloc_status = 4;
 		goto alloc_status_switch;
 	}
 	rx_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!rx_urb) {
-		err("%s: usb_alloc_urb failed for IR urb", __func__);
+		dev_err(&interface->dev,
+			"%s: usb_alloc_urb failed for IR urb\n", __func__);
 		alloc_status = 5;
 		goto alloc_status_switch;
 	}
 	if (vfd_ep_found) {
 		tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!tx_urb) {
-			err("%s: usb_alloc_urb failed for VFD urb",
-			    __func__);
+			dev_err(&interface->dev,
+				"%s: usb_alloc_urb failed for VFD urb",
+				__func__);
 			alloc_status = 6;
 			goto alloc_status_switch;
 		}
@@ -807,7 +828,8 @@
 
 	lirc_minor = lirc_register_driver(driver);
 	if (lirc_minor < 0) {
-		err("%s: lirc_register_driver failed", __func__);
+		dev_err(&interface->dev,
+			"%s: lirc_register_driver failed\n", __func__);
 		alloc_status = 7;
 		retval = lirc_minor;
 		goto unlock;
diff --git a/drivers/staging/media/lirc/lirc_ttusbir.c b/drivers/staging/media/lirc/lirc_ttusbir.c
index 7950887..3bb865c 100644
--- a/drivers/staging/media/lirc/lirc_ttusbir.c
+++ b/drivers/staging/media/lirc/lirc_ttusbir.c
@@ -113,8 +113,9 @@
 	for (i = 0; i < num_urbs; i++) {
 		retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL);
 		if (retval) {
-			err("%s: usb_submit_urb failed on urb %d",
-			    __func__, i);
+			dev_err(&ttusbir->interf->dev,
+				"%s: usb_submit_urb failed on urb %d\n",
+				__func__, i);
 			return retval;
 		}
 	}
@@ -278,7 +279,7 @@
 	if (ttusbir->alt_setting != -1)
 		DPRINTK("alt setting: %d\n", ttusbir->alt_setting);
 	else {
-		err("Could not find alternate setting\n");
+		dev_err(&intf->dev, "Could not find alternate setting\n");
 		kfree(ttusbir);
 		return -EINVAL;
 	}
@@ -291,7 +292,7 @@
 
 	/* Register as a LIRC driver */
 	if (lirc_buffer_init(&ttusbir->rbuf, sizeof(int), 256) < 0) {
-		err("Could not get memory for LIRC data buffer\n");
+		dev_err(&intf->dev, "Could not get memory for LIRC data buffer\n");
 		usb_set_intfdata(intf, NULL);
 		kfree(ttusbir);
 		return -ENOMEM;
@@ -310,7 +311,7 @@
 	ttusbir->driver.features = LIRC_CAN_REC_MODE2;
 	ttusbir->minor = lirc_register_driver(&ttusbir->driver);
 	if (ttusbir->minor < 0) {
-		err("Error registering as LIRC driver\n");
+		dev_err(&intf->dev, "Error registering as LIRC driver\n");
 		usb_set_intfdata(intf, NULL);
 		lirc_buffer_free(&ttusbir->rbuf);
 		kfree(ttusbir);
@@ -321,7 +322,7 @@
 	for (i = 0; i < num_urbs; i++) {
 		ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL);
 		if (!ttusbir->urb[i]) {
-			err("Could not allocate memory for the URB\n");
+			dev_err(&intf->dev, "Could not allocate memory for the URB\n");
 			for (j = i - 1; j >= 0; j--)
 				kfree(ttusbir->urb[j]);
 			lirc_buffer_free(&ttusbir->rbuf);
diff --git a/drivers/staging/quatech_usb2/Kconfig b/drivers/staging/quatech_usb2/Kconfig
deleted file mode 100644
index 1494f42..0000000
--- a/drivers/staging/quatech_usb2/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-config USB_SERIAL_QUATECH_USB2
-	tristate "USB Quatech xSU2-[14]00 USB Serial Driver"
-	depends on USB_SERIAL
-	help
-	  Say Y here if you want to use a Quatech USB2.0 to serial adaptor. This
-	  driver supports the SSU2-100, DSU2-100, DSU2-400, QSU2-100, QSU2-400,
-	  ESU2-400 and ESU2-100 USB2.0 to RS232 / 485 / 422 serial adaptors.
-
-	  Some hardware has an incorrect product string and announces itself as
-	  ESU-100 (which uses the serqt driver) even though it is an ESU2-100.
-	  Check the label on the bottom of your device.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called quatech_usb2 .
-
diff --git a/drivers/staging/quatech_usb2/Makefile b/drivers/staging/quatech_usb2/Makefile
deleted file mode 100644
index bcd1f89..0000000
--- a/drivers/staging/quatech_usb2/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)		+= quatech_usb2.o
diff --git a/drivers/staging/quatech_usb2/TODO b/drivers/staging/quatech_usb2/TODO
deleted file mode 100644
index 67f61db..0000000
--- a/drivers/staging/quatech_usb2/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-Incomplete list of things that this driver does not yet implement completely or
-at all. some of these may not be possible to implement because the hardware
-support does not exist. Others may be possible, but the magic control codes to
-make them happen are unknown, and some may just need the driver support to
-implement them writing.
-
-* Mark/Space parity is not implemented (reported back correctly)
-* IXANY flow control mode is not implemented (flag ignored completely)
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
deleted file mode 100644
index bb977e0..0000000
--- a/drivers/staging/quatech_usb2/quatech_usb2.c
+++ /dev/null
@@ -1,1976 +0,0 @@
-/*
- * Driver for Quatech Inc USB2.0 to serial adaptors. Largely unrelated to the
- * serqt_usb driver, based on a re-write of the vendor supplied serqt_usb2 code,
- * which is unrelated to the serqt_usb2 in the staging kernel
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <linux/serial.h>
-#include <linux/usb.h>
-#include <linux/usb/serial.h>
-#include <linux/uaccess.h>
-
-static bool debug;
-
-/* Version Information */
-#define DRIVER_VERSION "v2.00"
-#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
-#define DRIVER_DESC "Quatech USB 2.0 to Serial Driver"
-
-/* vendor and device IDs */
-#define	USB_VENDOR_ID_QUATECH 0x061d	/* Quatech VID */
-#define QUATECH_SSU2_100 0xC120		/* RS232 single port */
-#define QUATECH_DSU2_100 0xC140		/* RS232 dual port */
-#define QUATECH_DSU2_400 0xC150		/* RS232/422/485 dual port */
-#define QUATECH_QSU2_100 0xC160		/* RS232 four port */
-#define QUATECH_QSU2_400 0xC170		/* RS232/422/485 four port */
-#define QUATECH_ESU2_100 0xC1A0		/* RS232 eight port */
-#define QUATECH_ESU2_400 0xC180		/* RS232/422/485 eight port */
-
-/* magic numbers go here, when we find out which ones are needed */
-
-#define QU2BOXPWRON 0x8000		/* magic number to turn FPGA power on */
-#define QU2BOX232 0x40			/* RS232 mode on MEI devices */
-#define QU2BOXSPD9600 0x60		/* set speed to 9600 baud */
-#define QT2_FIFO_DEPTH 1024			/* size of hardware fifos */
-#define QT2_TX_HEADER_LENGTH	5
-/* length of the header sent to the box with each write URB */
-
-/* directions for USB transfers */
-#define USBD_TRANSFER_DIRECTION_IN    0xc0
-#define USBD_TRANSFER_DIRECTION_OUT   0x40
-
-/* special Quatech command IDs. These are pushed down the
- USB control pipe to get the box on the end to do things */
-#define QT_SET_GET_DEVICE		0xc2
-#define QT_OPEN_CLOSE_CHANNEL		0xca
-/*#define QT_GET_SET_PREBUF_TRIG_LVL	0xcc
-#define QT_SET_ATF			0xcd*/
-#define QT2_GET_SET_REGISTER			0xc0
-#define QT2_GET_SET_UART			0xc1
-#define QT2_HW_FLOW_CONTROL_MASK		0xc5
-#define QT2_SW_FLOW_CONTROL_MASK		0xc6
-#define QT2_SW_FLOW_CONTROL_DISABLE		0xc7
-#define QT2_BREAK_CONTROL			0xc8
-#define QT2_STOP_RECEIVE			0xe0
-#define QT2_FLUSH_DEVICE			0xc4
-#define QT2_GET_SET_QMCR			0xe1
-
-/* sorts of flush we can do on */
-#define QT2_FLUSH_RX			0x00
-#define QT2_FLUSH_TX			0x01
-
-/* port setting constants, used to set up serial port speeds, flow
- * control and so on */
-#define QT2_SERIAL_MCR_DTR	0x01
-#define QT2_SERIAL_MCR_RTS	0x02
-#define QT2_SERIAL_MCR_LOOP	0x10
-
-#define QT2_SERIAL_MSR_CTS	0x10
-#define QT2_SERIAL_MSR_CD	0x80
-#define QT2_SERIAL_MSR_RI	0x40
-#define QT2_SERIAL_MSR_DSR	0x20
-#define QT2_SERIAL_MSR_MASK	0xf0
-
-#define QT2_SERIAL_8_DATA	0x03
-#define QT2_SERIAL_7_DATA	0x02
-#define QT2_SERIAL_6_DATA	0x01
-#define QT2_SERIAL_5_DATA	0x00
-
-#define QT2_SERIAL_ODD_PARITY	0x08
-#define QT2_SERIAL_EVEN_PARITY	0x18
-#define QT2_SERIAL_TWO_STOPB	0x04
-#define QT2_SERIAL_ONE_STOPB	0x00
-
-#define QT2_MAX_BAUD_RATE	921600
-#define QT2_MAX_BAUD_REMAINDER	4608
-
-#define QT2_SERIAL_LSR_OE	0x02
-#define QT2_SERIAL_LSR_PE	0x04
-#define QT2_SERIAL_LSR_FE	0x08
-#define QT2_SERIAL_LSR_BI	0x10
-
-/* value of Line Status Register when UART has completed
- * emptying data out on the line */
-#define QT2_LSR_TEMT     0x40
-
-/* register numbers on each UART, for use with  qt2_box_[get|set]_register*/
-#define  QT2_XMT_HOLD_REGISTER          0x00
-#define  QT2_XVR_BUFFER_REGISTER        0x00
-#define  QT2_FIFO_CONTROL_REGISTER      0x02
-#define  QT2_LINE_CONTROL_REGISTER      0x03
-#define  QT2_MODEM_CONTROL_REGISTER     0x04
-#define  QT2_LINE_STATUS_REGISTER       0x05
-#define  QT2_MODEM_STATUS_REGISTER      0x06
-
-/* handy macros for doing escape sequence parsing on data reads */
-#define THISCHAR	((unsigned char *)(urb->transfer_buffer))[i]
-#define NEXTCHAR	((unsigned char *)(urb->transfer_buffer))[i + 1]
-#define THIRDCHAR	((unsigned char *)(urb->transfer_buffer))[i + 2]
-#define FOURTHCHAR	((unsigned char *)(urb->transfer_buffer))[i + 3]
-#define FIFTHCHAR	((unsigned char *)(urb->transfer_buffer))[i + 4]
-
-static const struct usb_device_id quausb2_id_table[] = {
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_100)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_400)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_100)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_400)},
-	{}	/* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, quausb2_id_table);
-
-/* custom structures we need go here */
-static struct usb_driver quausb2_usb_driver = {
-	.name = "quatech-usb2-serial",
-	.probe = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-	.id_table = quausb2_id_table,
-};
-
-/**
- * quatech2_port: Structure in which to keep all the messy stuff that this
- * driver needs alongside the usb_serial_port structure
- * @read_urb_busy: Flag indicating that port->read_urb is in use
- * @close_pending: flag indicating that this port is in the process of
- * being closed (and so no new reads / writes should be started).
- * @shadowLSR: Last received state of the line status register, holds the
- * value of the line status flags from the port
- * @shadowMSR: Last received state of the modem status register, holds
- * the value of the modem status received from the port
- * @rcv_flush: Flag indicating that a receive flush has occurred on
- * the hardware.
- * @xmit_flush: Flag indicating that a transmit flush has been processed by
- * the hardware.
- * @tx_pending_bytes: Number of bytes waiting to be sent. This total
- * includes the size (excluding header) of URBs that have been submitted but
- * have not yet been sent to to the device, and bytes that have been sent out
- * of the port but not yet reported sent by the "xmit_empty" messages (which
- * indicate the number of bytes sent each time they are received, despite the
- * misleading name).
- * - Starts at zero when port is initialised.
- * - is incremented by the size of the data to be written (no headers)
- * each time a write urb is dispatched.
- * - is decremented each time a "transmit empty" message is received
- * by the driver in the data stream.
- * @lock: Mutex to lock access to this structure when we need to ensure that
- * races don't occur to access bits of it.
- * @open_count: The number of uses of the port currently having
- * it open, i.e. the reference count.
- */
-struct quatech2_port {
-	int	magic;
-	bool	read_urb_busy;
-	bool	close_pending;
-	__u8	shadowLSR;
-	__u8	shadowMSR;
-	bool	rcv_flush;
-	bool	xmit_flush;
-	int	tx_pending_bytes;
-	struct mutex modelock;
-	int	open_count;
-
-	char	active;		/* someone has this device open */
-	unsigned char		*xfer_to_tty_buffer;
-	wait_queue_head_t	wait;
-	__u8	shadowLCR;	/* last LCR value received */
-	__u8	shadowMCR;	/* last MCR value received */
-	char	RxHolding;
-	struct semaphore	pend_xmit_sem;	/* locks this structure */
-	spinlock_t lock;
-};
-
-/**
- * Structure to hold device-wide internal status information
- * @param ReadBulkStopped The last bulk read attempt ended in tears
- * @param open_ports The number of serial ports currently in use on the box
- * @param current_port Pointer to the serial port structure of the port which
- * the read stream is currently directed to. Escape sequences in the read
- * stream will change this around as data arrives from different ports on the
- * box
- * @buffer_size: The max size buffer each URB can take, used to set the size of
- * the buffers allocated for writing to each port on the device (we need to
- * store this because it is known only to the endpoint, but used each time a
- * port is opened and a new buffer is allocated.
- */
-struct quatech2_dev {
-	bool	ReadBulkStopped;
-	char	open_ports;
-	struct usb_serial_port *current_port;
-	int	buffer_size;
-};
-
-/* structure which holds line and modem status flags */
-struct qt2_status_data {
-	__u8 line_status;
-	__u8 modem_status;
-};
-
-/* Function prototypes */
-static int qt2_boxpoweron(struct usb_serial *serial);
-static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number,
-			__u8 QMCR_Value);
-static int port_paranoia_check(struct usb_serial_port *port,
-			const char *function);
-static int serial_paranoia_check(struct usb_serial *serial,
-			 const char *function);
-static inline struct quatech2_port *qt2_get_port_private(struct usb_serial_port
-			*port);
-static inline void qt2_set_port_private(struct usb_serial_port *port,
-			struct quatech2_port *data);
-static inline struct quatech2_dev *qt2_get_dev_private(struct usb_serial
-			*serial);
-static inline void qt2_set_dev_private(struct usb_serial *serial,
-			struct quatech2_dev *data);
-static int qt2_openboxchannel(struct usb_serial *serial, __u16
-			Uart_Number, struct qt2_status_data *pDeviceData);
-static int qt2_closeboxchannel(struct usb_serial *serial, __u16
-			Uart_Number);
-static int qt2_conf_uart(struct usb_serial *serial,  unsigned short Uart_Number,
-			 unsigned short divisor, unsigned char LCR);
-static void qt2_read_bulk_callback(struct urb *urb);
-static void qt2_write_bulk_callback(struct urb *urb);
-static void qt2_process_line_status(struct usb_serial_port *port,
-			      unsigned char LineStatus);
-static void qt2_process_modem_status(struct usb_serial_port *port,
-			       unsigned char ModemStatus);
-static void qt2_process_xmit_empty(struct usb_serial_port *port,
-	unsigned char fourth_char, unsigned char fifth_char);
-static void qt2_process_port_change(struct usb_serial_port *port,
-			      unsigned char New_Current_Port);
-static void qt2_process_rcv_flush(struct usb_serial_port *port);
-static void qt2_process_xmit_flush(struct usb_serial_port *port);
-static void qt2_process_rx_char(struct usb_serial_port *port,
-				unsigned char data);
-static int qt2_box_get_register(struct usb_serial *serial,
-		unsigned char uart_number, unsigned short register_num,
-		__u8 *pValue);
-static int qt2_box_set_register(struct usb_serial *serial,
-		unsigned short Uart_Number, unsigned short Register_Num,
-		unsigned short Value);
-static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
-		unsigned short default_divisor, unsigned char default_LCR);
-static int qt2_boxsethw_flowctl(struct usb_serial *serial,
-		unsigned int UartNumber, bool bSet);
-static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber,
-		unsigned char stop_char,  unsigned char start_char);
-static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber);
-static int qt2_boxstoprx(struct usb_serial *serial, unsigned short uart_number,
-			 unsigned short stop);
-
-/* implementation functions, roughly in order of use, are here */
-static int qt2_calc_num_ports(struct usb_serial *serial)
-{
-	int num_ports;
-	int flag_as_400;
-	switch (serial->dev->descriptor.idProduct) {
-	case QUATECH_SSU2_100:
-		num_ports = 1;
-		break;
-
-	case QUATECH_DSU2_400:
-		flag_as_400 = true;
-	case QUATECH_DSU2_100:
-		num_ports = 2;
-	break;
-
-	case QUATECH_QSU2_400:
-		flag_as_400 = true;
-	case QUATECH_QSU2_100:
-		num_ports = 4;
-	break;
-
-	case QUATECH_ESU2_400:
-		flag_as_400 = true;
-	case QUATECH_ESU2_100:
-		num_ports = 8;
-	break;
-	default:
-	num_ports = 1;
-	break;
-	}
-	return num_ports;
-}
-
-static int qt2_attach(struct usb_serial *serial)
-{
-	struct usb_serial_port *port;
-	struct quatech2_port *qt2_port;	/* port-specific private data pointer */
-	struct quatech2_dev  *qt2_dev;	/* dev-specific private data pointer */
-	int i;
-	/* stuff for storing endpoint addresses now */
-	struct usb_endpoint_descriptor *endpoint;
-	struct usb_host_interface *iface_desc;
-	struct usb_serial_port *port0;	/* first port structure on device */
-
-	/* check how many endpoints there are on the device, for
-	 * sanity's sake */
-	dbg("%s(): Endpoints: %d bulk in, %d bulk out, %d interrupt in",
-			__func__, serial->num_bulk_in,
-			serial->num_bulk_out, serial->num_interrupt_in);
-	if ((serial->num_bulk_in != 1) || (serial->num_bulk_out != 1)) {
-		dbg("Device has wrong number of bulk endpoints!");
-		return -ENODEV;
-	}
-	iface_desc = serial->interface->cur_altsetting;
-
-	/* Set up per-device private data, storing extra data alongside
-	 * struct usb_serial */
-	qt2_dev = kzalloc(sizeof(*qt2_dev), GFP_KERNEL);
-	if (!qt2_dev) {
-		dbg("%s: kmalloc for quatech2_dev failed!",
-		    __func__);
-		return -ENOMEM;
-	}
-	qt2_dev->open_ports = 0;	/* no ports open */
-	qt2_set_dev_private(serial, qt2_dev);	/* store private data */
-
-	/* Now setup per port private data, which replaces all the things
-	 * that quatech added to standard kernel structures in their driver */
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		qt2_port = kzalloc(sizeof(*qt2_port), GFP_KERNEL);
-		if (!qt2_port) {
-			dbg("%s: kmalloc for quatech2_port (%d) failed!.",
-			    __func__, i);
-			return -ENOMEM;
-		}
-		/* initialise stuff in the structure */
-		qt2_port->open_count = 0;	/* port is not open */
-		spin_lock_init(&qt2_port->lock);
-		mutex_init(&qt2_port->modelock);
-		qt2_set_port_private(port, qt2_port);
-	}
-
-	/* gain access to port[0]'s structure because we want to store
-	 * device-level stuff in it */
-	if (serial_paranoia_check(serial, __func__))
-		return -ENODEV;
-	port0 = serial->port[0]; /* get the first port's device structure */
-
-	/* print endpoint addresses so we can check them later
-	 * by hand */
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-		endpoint = &iface_desc->endpoint[i].desc;
-		if ((endpoint->bEndpointAddress & 0x80) &&
-			((endpoint->bmAttributes & 3) == 0x02)) {
-			/* we found a bulk in endpoint */
-			dbg("found bulk in at %#.2x",
-				endpoint->bEndpointAddress);
-		}
-
-		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
-			((endpoint->bmAttributes & 3) == 0x02)) {
-			/* we found a bulk out endpoint */
-			dbg("found bulk out at %#.2x",
-				endpoint->bEndpointAddress);
-			qt2_dev->buffer_size = endpoint->wMaxPacketSize;
-			/* max size of URB needs recording for the device */
-		}
-	}	/* end printing endpoint addresses */
-
-	/* switch on power to the hardware */
-	if (qt2_boxpoweron(serial) < 0) {
-		dbg("qt2_boxpoweron() failed");
-		goto startup_error;
-	}
-	/* set all ports to RS232 mode */
-	for (i = 0; i < serial->num_ports; ++i) {
-		if (qt2_boxsetQMCR(serial, i, QU2BOX232) < 0) {
-			dbg("qt2_boxsetQMCR() on port %d failed",
-				i);
-			goto startup_error;
-		}
-	}
-
-	return 0;
-
-startup_error:
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		qt2_port = qt2_get_port_private(port);
-		kfree(qt2_port);
-		qt2_set_port_private(port, NULL);
-	}
-	qt2_dev = qt2_get_dev_private(serial);
-	kfree(qt2_dev);
-	qt2_set_dev_private(serial, NULL);
-
-	dbg("Exit fail %s\n", __func__);
-	return -EIO;
-}
-
-static void qt2_release(struct usb_serial *serial)
-{
-	struct usb_serial_port *port;
-	struct quatech2_port *qt_port;
-	int i;
-
-	dbg("enterting %s", __func__);
-
-	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		if (!port)
-			continue;
-
-		qt_port = usb_get_serial_port_data(port);
-		kfree(qt_port);
-		usb_set_serial_port_data(port, NULL);
-	}
-}
-/* This function is called once per serial port on the device, when
- * that port is opened by a userspace application.
- * The tty_struct and the usb_serial_port belong to this port,
- * i.e. there are multiple ones for a multi-port device.
- * However the usb_serial_port structure has a back-pointer
- * to the parent usb_serial structure which belongs to the device,
- * so we can access either the device-wide information or
- * any other port's information (because there are also forward
- * pointers) via that pointer.
- * This is most helpful if the device shares resources (e.g. end
- * points) between different ports
- */
-int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
-{
-	struct usb_serial *serial;	/* device structure */
-	struct usb_serial_port *port0;	/* first port structure on device */
-	struct quatech2_port *port_extra;       /* extra data for this port */
-	struct quatech2_port *port0_extra;	/* extra data for first port */
-	struct quatech2_dev *dev_extra;		/* extra data for the device */
-	struct qt2_status_data ChannelData;
-	unsigned short default_divisor = QU2BOXSPD9600;
-	unsigned char  default_LCR = QT2_SERIAL_8_DATA;
-	int status;
-	int result;
-
-	if (port_paranoia_check(port, __func__))
-		return -ENODEV;
-
-	dbg("%s(): port %d", __func__, port->number);
-
-	serial = port->serial;	/* get the parent device structure */
-	if (serial_paranoia_check(serial, __func__)) {
-		dbg("usb_serial struct failed sanity check");
-		return -ENODEV;
-	}
-	dev_extra = qt2_get_dev_private(serial);
-	/* get the device private data */
-	if (dev_extra == NULL) {
-		dbg("device extra data pointer is null");
-		return -ENODEV;
-	}
-	port0 = serial->port[0]; /* get the first port's device structure */
-	if (port_paranoia_check(port0, __func__)) {
-		dbg("port0 usb_serial_port struct failed sanity check");
-		return -ENODEV;
-	}
-
-	port_extra = qt2_get_port_private(port);
-	port0_extra = qt2_get_port_private(port0);
-	if (port_extra == NULL || port0_extra == NULL) {
-		dbg("failed to get private data for port or port0");
-		return -ENODEV;
-	}
-
-	/* FIXME: are these needed?  Does it even do anything useful? */
-	/* get the modem and line status values from the UART */
-	status = qt2_openboxchannel(serial, port->number,
-			&ChannelData);
-	if (status < 0) {
-		dbg("qt2_openboxchannel on channel %d failed",
-		    port->number);
-		return status;
-	}
-	port_extra->shadowLSR = ChannelData.line_status &
-			(QT2_SERIAL_LSR_OE | QT2_SERIAL_LSR_PE |
-			QT2_SERIAL_LSR_FE | QT2_SERIAL_LSR_BI);
-	port_extra->shadowMSR = ChannelData.modem_status &
-			(QT2_SERIAL_MSR_CTS | QT2_SERIAL_MSR_DSR |
-			QT2_SERIAL_MSR_RI | QT2_SERIAL_MSR_CD);
-
-/*	port_extra->fifo_empty_flag = true;*/
-	dbg("qt2_openboxchannel on channel %d completed.",
-	    port->number);
-
-	/* Set Baud rate to default and turn off flow control here */
-	status = qt2_conf_uart(serial, port->number, default_divisor,
-				default_LCR);
-	if (status < 0) {
-		dbg("qt2_conf_uart() failed on channel %d",
-		    port->number);
-		return status;
-	}
-	dbg("qt2_conf_uart() completed on channel %d",
-		port->number);
-
-	/*
-	 * At this point we will need some end points to make further progress.
-	 * Handlily, the correct endpoint addresses have been filled out into
-	 * the usb_serial_port structure for us by the driver core, so we
-	 * already have access to them.
-	 * As there is only one bulk in and one bulk out end-point, these are in
-	 * port[0]'s structure, and the rest are uninitialised. Handily,
-	 * when we do a write to a port, we will use the same endpoint
-	 * regardless of the port, with a 5-byte header added on to
-	 * tell the box which port it should eventually come out of, so we only
-	 * need the one set of endpoints. We will have one URB per port for
-	 * writing, so that multiple ports can be writing at once.
-	 * Finally we need a bulk in URB to use for background reads from the
-	 * device, which will deal with uplink data from the box to host.
-	 */
-	dbg("port0 bulk in endpoint is %#.2x", port0->bulk_in_endpointAddress);
-	dbg("port0 bulk out endpoint is %#.2x",
-		port0->bulk_out_endpointAddress);
-
-	/* set up write_urb for bulk out transfers on this port. The USB
-	 * serial framework will have allocated a blank URB, buffer etc for
-	 * port0 when it put the endpoints there, but not for any of the other
-	 * ports on the device because there are no more endpoints. Thus we
-	 * have to allocate our own URBs for ports 1-7
-	 */
-	if (port->write_urb == NULL) {
-		dbg("port->write_urb == NULL, allocating one");
-		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!port->write_urb) {
-			err("Allocating write URB failed");
-			return -ENOMEM;
-		}
-		/* buffer same size as port0 */
-		port->bulk_out_size = dev_extra->buffer_size;
-		port->bulk_out_buffer = kmalloc(port->bulk_out_size,
-						GFP_KERNEL);
-		if (!port->bulk_out_buffer) {
-			err("Couldn't allocate bulk_out_buffer");
-			return -ENOMEM;
-		}
-	}
-	if (serial->dev == NULL)
-		dbg("serial->dev == NULL");
-	dbg("port->bulk_out_size is %d", port->bulk_out_size);
-
-	usb_fill_bulk_urb(port->write_urb, serial->dev,
-			usb_sndbulkpipe(serial->dev,
-			port0->bulk_out_endpointAddress),
-			port->bulk_out_buffer,
-			port->bulk_out_size,
-			qt2_write_bulk_callback,
-			port);
-	port_extra->tx_pending_bytes = 0;
-
-	if (dev_extra->open_ports == 0) {
-		/* this is first port to be opened, so need the read URB
-		 * initialised for bulk in transfers (this is shared amongst
-		 * all the ports on the device) */
-		usb_fill_bulk_urb(port0->read_urb, serial->dev,
-			usb_rcvbulkpipe(serial->dev,
-			port0->bulk_in_endpointAddress),
-			port0->bulk_in_buffer,
-			port0->bulk_in_size,
-			qt2_read_bulk_callback, serial);
-		dbg("port0 bulk in URB initialised");
-
-		/* submit URB, i.e. start reading from device (async) */
-		dev_extra->ReadBulkStopped = false;
-		port_extra->read_urb_busy = true;
-		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
-		if (result) {
-			dev_err(&port->dev,
-				 "%s(): Error %d submitting bulk in urb",
-				__func__, result);
-			port_extra->read_urb_busy = false;
-			dev_extra->ReadBulkStopped = true;
-		}
-
-		/* When the first port is opened, initialise the value of
-		 * current_port in dev_extra to this port, so it is set
-		 * to something. Once the box sends data it will send the
-		 * relevant escape sequences to get it to the right port anyway
-		 */
-		dev_extra->current_port = port;
-	}
-
-	/* initialize our wait queues */
-	init_waitqueue_head(&port_extra->wait);
-	/* increment the count of openings of this port by one */
-	port_extra->open_count++;
-
-	/* remember to store dev_extra, port_extra and port0_extra back again at
-	 * end !*/
-	qt2_set_port_private(port, port_extra);
-	qt2_set_port_private(serial->port[0], port0_extra);
-	qt2_set_dev_private(serial, dev_extra);
-
-	dev_extra->open_ports++; /* one more port opened */
-
-	return 0;
-}
-
-/* called when a port is closed by userspace. It won't be called, however,
- * until calls to chars_in_buffer() reveal that the port has completed
- * sending buffered data, and there is nothing else to do. Thus we don't have
- * to rely on forcing data through in this function. */
-/* Setting close_pending should keep new data from being written out,
- * once all the data in the enpoint buffers is moved out we won't get
- * any more. */
-/* BoxStopReceive would keep any more data from coming from a given
- * port, but isn't called by the vendor driver, although their comments
- * mention it. Should it be used here to stop the inbound data
- * flow?
- */
-static void qt2_close(struct usb_serial_port *port)
-{
-	/* time out value for flush loops */
-	unsigned long jift;
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	struct usb_serial *serial;	/* device structure */
-	struct quatech2_dev *dev_extra; /* extra data for the device */
-	__u8  lsr_value = 0;	/* value of Line Status Register */
-	int status;	/* result of last USB comms function */
-
-	dbg("%s(): port %d", __func__, port->number);
-	serial = port->serial;	/* get the parent device structure */
-	dev_extra = qt2_get_dev_private(serial);
-	/* get the device private data */
-	port_extra = qt2_get_port_private(port); /* port private data */
-
-	/* we can now (and only now) stop reading data */
-	port_extra->close_pending = true;
-	dbg("%s(): port_extra->close_pending = true", __func__);
-	/* although the USB side is now empty, the UART itself may
-	 * still be pushing characters out over the line, so we have to
-	 * wait testing the actual line status until the lines change
-	 * indicating that the data is done transferring. */
-	/* FIXME: slow this polling down so it doesn't run the USB bus flat out
-	 * if it actually has to spend any time in this loop (which it normally
-	 * doesn't because the buffer is nearly empty) */
-	jift = jiffies + (10 * HZ);	/* 10 sec timeout */
-	do {
-		status = qt2_box_get_register(serial, port->number,
-			QT2_LINE_STATUS_REGISTER, &lsr_value);
-		if (status < 0) {
-			dbg("%s(): qt2_box_get_register failed", __func__);
-			break;
-		}
-		if ((lsr_value & QT2_LSR_TEMT)) {
-			dbg("UART done sending");
-			break;
-		}
-		schedule();
-	} while (jiffies <= jift);
-
-	status = qt2_closeboxchannel(serial, port->number);
-	if (status < 0)
-		dbg("%s(): port %d qt2_box_open_close_channel failed",
-			__func__, port->number);
-	/* to avoid leaking URBs, we should now free the write_urb for this
-	 * port and set the pointer to null so that next time the port is opened
-	 * a new URB is allocated. This avoids leaking URBs when the device is
-	 * removed */
-	usb_free_urb(port->write_urb);
-	kfree(port->bulk_out_buffer);
-	port->bulk_out_buffer = NULL;
-	port->bulk_out_size = 0;
-
-	/* decrement the count of openings of this port by one */
-	port_extra->open_count--;
-	/* one less overall open as well */
-	dev_extra->open_ports--;
-	dbg("%s(): Exit, dev_extra->open_ports  = %d", __func__,
-		dev_extra->open_ports);
-}
-
-/**
- * qt2_write - write bytes from the tty layer out to the USB device.
- * @buf: The data to be written, size at least count.
- * @count: The number of bytes requested for transmission.
- * @return The number of bytes actually accepted for transmission to the device.
- */
-static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port,
-		const unsigned char *buf, int count)
-{
-	struct usb_serial *serial;	/* parent device struct */
-	__u8 header_array[5];	/* header used to direct writes to the correct
-	port on the device */
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	int result;
-
-	serial = port->serial; /* get the parent device of the port */
-	port_extra = qt2_get_port_private(port); /* port extra info */
-	if (serial == NULL)
-		return -ENODEV;
-	dbg("%s(): port %d, requested to write %d bytes, %d already pending",
-		__func__, port->number, count, port_extra->tx_pending_bytes);
-
-	if (count <= 0)	{
-		dbg("%s(): write request of <= 0 bytes", __func__);
-		return 0;	/* no bytes written */
-	}
-
-	/* check if the write urb is already in use, i.e. data already being
-	 * sent to this port */
-	if ((port->write_urb->status == -EINPROGRESS)) {
-		/* Fifo hasn't been emptied since last write to this port */
-		dbg("%s(): already writing, port->write_urb->status == "
-			"-EINPROGRESS", __func__);
-		/* schedule_work(&port->work); commented in vendor driver */
-		return 0;
-	} else if (port_extra->tx_pending_bytes >= QT2_FIFO_DEPTH) {
-		/* buffer is full (==). > should not occur, but would indicate
-		 * that an overflow had occurred */
-		dbg("%s(): port transmit buffer is full!", __func__);
-		/* schedule_work(&port->work); commented in vendor driver */
-		return 0;
-	}
-
-	/* We must fill the first 5 bytes of anything we sent with a transmit
-	 * header which directes the data to the correct port. The maximum
-	 * size we can send out in one URB is port->bulk_out_size, which caps
-	 * the number of bytes of real data we can send in each write. As the
-	 * semantics of write allow us to write less than we were give, we cap
-	 * the maximum we will ever write to the device as 5 bytes less than
-	 * one URB's worth, by reducing the value of the count argument
-	 * appropriately*/
-	if (count > port->bulk_out_size - QT2_TX_HEADER_LENGTH) {
-		count = port->bulk_out_size - QT2_TX_HEADER_LENGTH;
-		dbg("%s(): write request bigger than urb, only accepting "
-			"%d bytes", __func__, count);
-	}
-	/* we must also ensure that the FIFO at the other end can cope with the
-	 * URB we send it, otherwise it will have problems. As above, we can
-	 * restrict the write size by just shrinking count.*/
-	if (count > (QT2_FIFO_DEPTH - port_extra->tx_pending_bytes)) {
-		count = QT2_FIFO_DEPTH - port_extra->tx_pending_bytes;
-		dbg("%s(): not enough room in buffer, only accepting %d bytes",
-			__func__, count);
-	}
-	/* now build the header for transmission */
-	header_array[0] = 0x1b;
-	header_array[1] = 0x1b;
-	header_array[2] = (__u8)port->number;
-	header_array[3] = (__u8)count;
-	header_array[4] = (__u8)count >> 8;
-	/* copy header into URB */
-	memcpy(port->write_urb->transfer_buffer, header_array,
-		QT2_TX_HEADER_LENGTH);
-	/* and actual data to write */
-	memcpy(port->write_urb->transfer_buffer + 5, buf, count);
-
-	dbg("%s(): first data byte to send = %#.2x", __func__, *buf);
-
-	/* set up our urb */
-	usb_fill_bulk_urb(port->write_urb, serial->dev,
-			usb_sndbulkpipe(serial->dev,
-			port->bulk_out_endpointAddress),
-			port->write_urb->transfer_buffer, count + 5,
-			(qt2_write_bulk_callback), port);
-	/* send the data out the bulk port */
-	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-	if (result) {
-		/* error couldn't submit urb */
-		result = 0;	/* return 0 as nothing got written */
-		dbg("%s(): failed submitting write urb, error %d",
-			__func__, result);
-	} else {
-		port_extra->tx_pending_bytes += count;
-		result = count;	/* return number of bytes written, i.e. count */
-		dbg("%s(): submitted write urb, wrote %d bytes, "
-			"total pending bytes %d",
-			__func__, result, port_extra->tx_pending_bytes);
-	}
-	return result;
-}
-
-/* This is used by the next layer up to know how much space is available
- * in the buffer on the device. It is used on a device closure to avoid
- * calling close() until the buffer is reported to be empty.
- * The returned value must never go down by more than the number of bytes
- * written for correct behaviour further up the driver stack, i.e. if I call
- * it, then write 6 bytes, then call again I should get 6 less, or possibly
- * only 5 less if one was written in the meantime, etc. I should never get 7
- * less (or any bigger number) because I only wrote 6 bytes.
- */
-static int qt2_write_room(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-		/* parent usb_serial_port pointer */
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	int room = 0;
-	port_extra = qt2_get_port_private(port);
-
-	if (port_extra->close_pending == true) {
-		dbg("%s(): port_extra->close_pending == true", __func__);
-		return -ENODEV;
-	}
-	/* Q: how many bytes would a write() call actually succeed in writing
-	 * if it happened now?
-	 * A: one QT2_FIFO_DEPTH, less the number of bytes waiting to be sent
-	 * out of the port, unless this is more than the size of the
-	 * write_urb output buffer less the header, which is the maximum
-	 * size write we can do.
-
-	 * Most of the implementation of this is done when writes to the device
-	 * are started or terminate. When we send a write to the device, we
-	 * reduce the free space count by the size of the dispatched write.
-	 * When a "transmit empty" message comes back up the USB read stream,
-	 * we decrement the count by the number of bytes reported sent, thus
-	 * keeping track of the difference between sent and received bytes.
-	 */
-
-	room = (QT2_FIFO_DEPTH - port_extra->tx_pending_bytes);
-	/* space in FIFO */
-	if (room > port->bulk_out_size - QT2_TX_HEADER_LENGTH)
-		room = port->bulk_out_size - QT2_TX_HEADER_LENGTH;
-	/* if more than the URB can hold, then cap to that limit */
-
-	dbg("%s(): port %d: write room is %d", __func__, port->number, room);
-	return room;
-}
-
-static int qt2_chars_in_buffer(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	/* parent usb_serial_port pointer */
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	port_extra = qt2_get_port_private(port);
-
-	dbg("%s(): port %d: chars_in_buffer = %d", __func__,
-		port->number, port_extra->tx_pending_bytes);
-	return port_extra->tx_pending_bytes;
-}
-
-/* called when userspace does an ioctl() on the device. Note that
- * TIOCMGET and TIOCMSET are filtered off to their own methods before they get
- * here, so we don't have to handle them.
- */
-static int qt2_ioctl(struct tty_struct *tty,
-		     unsigned int cmd, unsigned long arg)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct usb_serial *serial = port->serial;
-	__u8 mcr_value;	/* Modem Control Register value */
-	__u8 msr_value; /* Modem Status Register value */
-	unsigned short prev_msr_value; /* Previous value of Modem Status
-	 * Register used to implement waiting for a line status change to
-	 * occur */
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	DECLARE_WAITQUEUE(wait, current);
-	/* Declare a wait queue named "wait" */
-
-	unsigned int value;
-	unsigned int UartNumber;
-
-	if (serial == NULL)
-		return -ENODEV;
-	UartNumber = tty->index - serial->minor;
-	port_extra = qt2_get_port_private(port);
-
-	dbg("%s(): port %d, UartNumber %d, tty =0x%p", __func__,
-	    port->number, UartNumber, tty);
-
-	if (cmd == TIOCMBIS || cmd == TIOCMBIC) {
-		if (qt2_box_get_register(port->serial, UartNumber,
-			QT2_MODEM_CONTROL_REGISTER, &mcr_value) < 0)
-			return -ESPIPE;
-		if (copy_from_user(&value, (unsigned int *)arg,
-			sizeof(value)))
-			return -EFAULT;
-
-		switch (cmd) {
-		case TIOCMBIS:
-			if (value & TIOCM_RTS)
-				mcr_value |= QT2_SERIAL_MCR_RTS;
-			if (value & TIOCM_DTR)
-				mcr_value |= QT2_SERIAL_MCR_DTR;
-			if (value & TIOCM_LOOP)
-				mcr_value |= QT2_SERIAL_MCR_LOOP;
-		break;
-		case TIOCMBIC:
-			if (value & TIOCM_RTS)
-				mcr_value &= ~QT2_SERIAL_MCR_RTS;
-			if (value & TIOCM_DTR)
-				mcr_value &= ~QT2_SERIAL_MCR_DTR;
-			if (value & TIOCM_LOOP)
-				mcr_value &= ~QT2_SERIAL_MCR_LOOP;
-		break;
-		default:
-		break;
-		}	/* end of local switch on cmd */
-		if (qt2_box_set_register(port->serial,  UartNumber,
-		    QT2_MODEM_CONTROL_REGISTER, mcr_value) < 0) {
-			return -ESPIPE;
-		} else {
-			port_extra->shadowMCR = mcr_value;
-			return 0;
-		}
-	} else if (cmd == TIOCMIWAIT) {
-		dbg("%s() port %d, cmd == TIOCMIWAIT enter",
-			__func__, port->number);
-		prev_msr_value = port_extra->shadowMSR  & QT2_SERIAL_MSR_MASK;
-		barrier();
-		__set_current_state(TASK_INTERRUPTIBLE);
-		while (1) {
-			add_wait_queue(&port_extra->wait, &wait);
-			schedule();
-			dbg("%s(): port %d, cmd == TIOCMIWAIT here\n",
-				__func__, port->number);
-			remove_wait_queue(&port_extra->wait, &wait);
-			/* see if a signal woke us up */
-			if (signal_pending(current))
-				return -ERESTARTSYS;
-			set_current_state(TASK_INTERRUPTIBLE);
-			msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK;
-			if (msr_value == prev_msr_value) {
-				__set_current_state(TASK_RUNNING);
-				return -EIO;  /* no change - error */
-			}
-			if ((arg & TIOCM_RNG &&
-				((prev_msr_value & QT2_SERIAL_MSR_RI) ==
-					(msr_value & QT2_SERIAL_MSR_RI))) ||
-				(arg & TIOCM_DSR &&
-				((prev_msr_value & QT2_SERIAL_MSR_DSR) ==
-					(msr_value & QT2_SERIAL_MSR_DSR))) ||
-				(arg & TIOCM_CD &&
-				((prev_msr_value & QT2_SERIAL_MSR_CD) ==
-					(msr_value & QT2_SERIAL_MSR_CD))) ||
-				(arg & TIOCM_CTS &&
-				((prev_msr_value & QT2_SERIAL_MSR_CTS) ==
-					(msr_value & QT2_SERIAL_MSR_CTS)))) {
-				__set_current_state(TASK_RUNNING);
-				return 0;
-			}
-		} /* end inifinite while */
-		/* FIXME: This while loop needs a way to break out if the device
-		 * is disconnected while a process is waiting for the MSR to
-		 * change, because once it's disconnected, it isn't going to
-		 * change state ... */
-	} else {
-		/* any other ioctls we don't know about come here */
-		dbg("%s(): No ioctl for that one. port = %d", __func__,
-			port->number);
-		return -ENOIOCTLCMD;
-	}
-}
-
-/* Called when the user wishes to change the port settings using the termios
- * userspace interface */
-static void qt2_set_termios(struct tty_struct *tty,
-	struct usb_serial_port *port, struct ktermios *old_termios)
-{
-	struct usb_serial *serial; /* parent serial device */
-	int baud, divisor, remainder;
-	unsigned char LCR_change_to = 0;
-	int status;
-	__u16 UartNumber;
-
-	dbg("%s(): port %d", __func__, port->number);
-
-	serial = port->serial;
-
-	UartNumber = port->number;
-
-	if (old_termios && !tty_termios_hw_change(old_termios, tty->termios))
-		return;
-
-	switch (tty->termios->c_cflag) {
-	case CS5:
-		LCR_change_to |= QT2_SERIAL_5_DATA;
-		break;
-	case CS6:
-		LCR_change_to |= QT2_SERIAL_6_DATA;
-		break;
-	case CS7:
-		LCR_change_to |= QT2_SERIAL_7_DATA;
-		break;
-	default:
-	case CS8:
-		LCR_change_to |= QT2_SERIAL_8_DATA;
-		break;
-	}
-
-	/* Parity stuff */
-	if (tty->termios->c_cflag & PARENB) {
-		if (tty->termios->c_cflag & PARODD)
-			LCR_change_to |= QT2_SERIAL_ODD_PARITY;
-		else
-			LCR_change_to |= QT2_SERIAL_EVEN_PARITY;
-	}
-	/* Because LCR_change_to is initialised to zero, we don't have to worry
-	 * about the case where PARENB is not set or clearing bits, because by
-	 * default all of them are cleared, turning parity off.
-	 * as we don't support mark/space parity, we should clear the
-	 * mark/space parity bit in c_cflag, so the caller can tell we have
-	 * ignored the request */
-	tty->termios->c_cflag &= ~CMSPAR;
-
-	if (tty->termios->c_cflag & CSTOPB)
-		LCR_change_to |= QT2_SERIAL_TWO_STOPB;
-	else
-		LCR_change_to |= QT2_SERIAL_ONE_STOPB;
-
-	/* Thats the LCR stuff, next we need to work out the divisor as the
-	 * LCR and the divisor are set together */
-	baud = tty_get_baud_rate(tty);
-	if (!baud) {
-		/* pick a default, any default... */
-		baud = 9600;
-	}
-	dbg("%s(): got baud = %d", __func__, baud);
-
-	divisor = QT2_MAX_BAUD_RATE / baud;
-	remainder = QT2_MAX_BAUD_RATE % baud;
-	/* Round to nearest divisor */
-	if (((remainder * 2) >= baud) && (baud != 110))
-		divisor++;
-	dbg("%s(): setting divisor = %d, QT2_MAX_BAUD_RATE = %d , LCR = %#.2x",
-	      __func__, divisor, QT2_MAX_BAUD_RATE, LCR_change_to);
-
-	status = qt2_boxsetuart(serial, UartNumber, (unsigned short) divisor,
-			    LCR_change_to);
-	if (status < 0)	{
-		dbg("qt2_boxsetuart() failed");
-		return;
-	} else {
-		/* now encode the baud rate we actually set, which may be
-		 * different to the request */
-		baud = QT2_MAX_BAUD_RATE / divisor;
-		tty_encode_baud_rate(tty, baud, baud);
-	}
-
-	/* Now determine flow control */
-	if (tty->termios->c_cflag & CRTSCTS) {
-		dbg("%s(): Enabling HW flow control port %d", __func__,
-		      port->number);
-		/* Enable  RTS/CTS flow control */
-		status = qt2_boxsethw_flowctl(serial, UartNumber, true);
-		if (status < 0) {
-			dbg("qt2_boxsethw_flowctl() failed");
-			return;
-		}
-	} else {
-		/* Disable RTS/CTS flow control */
-		dbg("%s(): disabling HW flow control port %d", __func__,
-			port->number);
-		status = qt2_boxsethw_flowctl(serial, UartNumber, false);
-		if (status < 0)	{
-			dbg("qt2_boxsethw_flowctl failed");
-			return;
-		}
-	}
-	/* if we are implementing XON/XOFF, set the start and stop character
-	 * in the device */
-	if (I_IXOFF(tty) || I_IXON(tty)) {
-		unsigned char stop_char  = STOP_CHAR(tty);
-		unsigned char start_char = START_CHAR(tty);
-		status = qt2_boxsetsw_flowctl(serial, UartNumber, stop_char,
-				start_char);
-		if (status < 0)
-			dbg("qt2_boxsetsw_flowctl (enabled) failed");
-	} else {
-		/* disable SW flow control */
-		status = qt2_boxunsetsw_flowctl(serial, UartNumber);
-		if (status < 0)
-			dbg("qt2_boxunsetsw_flowctl (disabling) failed");
-	}
-}
-
-static int qt2_tiocmget(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct usb_serial *serial = port->serial;
-
-	__u8 mcr_value;	/* Modem Control Register value */
-	__u8 msr_value;	/* Modem Status Register value */
-	unsigned int result = 0;
-	int status;
-	unsigned int UartNumber;
-
-	if (serial == NULL)
-		return -ENODEV;
-
-	dbg("%s(): port %d, tty =0x%p", __func__, port->number, tty);
-	UartNumber = tty->index - serial->minor;
-	dbg("UartNumber is %d", UartNumber);
-
-	status = qt2_box_get_register(port->serial, UartNumber,
-			QT2_MODEM_CONTROL_REGISTER,	&mcr_value);
-	if (status >= 0) {
-		status = qt2_box_get_register(port->serial,  UartNumber,
-				QT2_MODEM_STATUS_REGISTER, &msr_value);
-	}
-	if (status >= 0) {
-		result = ((mcr_value & QT2_SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
-				/*DTR set */
-			| ((mcr_value & QT2_SERIAL_MCR_RTS)  ? TIOCM_RTS : 0)
-				/*RTS set */
-			| ((msr_value & QT2_SERIAL_MSR_CTS)  ? TIOCM_CTS : 0)
-				/* CTS set */
-			| ((msr_value & QT2_SERIAL_MSR_CD)  ? TIOCM_CAR : 0)
-				/*Carrier detect set */
-			| ((msr_value & QT2_SERIAL_MSR_RI)  ? TIOCM_RI : 0)
-				/* Ring indicator set */
-			| ((msr_value & QT2_SERIAL_MSR_DSR)  ? TIOCM_DSR : 0);
-				/* DSR set */
-		return result;
-	} else {
-		return -ESPIPE;
-	}
-}
-
-static int qt2_tiocmset(struct tty_struct *tty,
-		       unsigned int set, unsigned int clear)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct usb_serial *serial = port->serial;
-	__u8 mcr_value;	/* Modem Control Register value */
-	int status;
-	unsigned int UartNumber;
-
-	if (serial == NULL)
-		return -ENODEV;
-
-	UartNumber = tty->index - serial->minor;
-	dbg("%s(): port %d, UartNumber %d", __func__, port->number, UartNumber);
-
-	status = qt2_box_get_register(port->serial, UartNumber,
-			QT2_MODEM_CONTROL_REGISTER, &mcr_value);
-	if (status < 0)
-		return -ESPIPE;
-
-	/* Turn off RTS, DTR and loopback, then only turn on what was asked
-	 * for */
-	mcr_value &= ~(QT2_SERIAL_MCR_RTS | QT2_SERIAL_MCR_DTR |
-			QT2_SERIAL_MCR_LOOP);
-	if (set & TIOCM_RTS)
-		mcr_value |= QT2_SERIAL_MCR_RTS;
-	if (set & TIOCM_DTR)
-		mcr_value |= QT2_SERIAL_MCR_DTR;
-	if (set & TIOCM_LOOP)
-		mcr_value |= QT2_SERIAL_MCR_LOOP;
-
-	status = qt2_box_set_register(port->serial, UartNumber,
-			QT2_MODEM_CONTROL_REGISTER, mcr_value);
-	if (status < 0)
-		return -ESPIPE;
-	else
-		return 0;
-}
-
-/** qt2_break - Turn BREAK on and off on the UARTs
- */
-static void qt2_break(struct tty_struct *tty, int break_state)
-{
-	struct usb_serial_port *port = tty->driver_data; /* parent port */
-	struct usb_serial *serial = port->serial;	/* parent device */
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	__u16 break_value;
-	unsigned int result;
-
-	port_extra = qt2_get_port_private(port);
-	if (!serial) {
-		dbg("%s(): port %d: no serial object", __func__, port->number);
-		return;
-	}
-
-	if (break_state == -1)
-		break_value = 1;
-	else
-		break_value = 0;
-	dbg("%s(): port %d, break_value %d", __func__, port->number,
-		break_value);
-
-	mutex_lock(&port_extra->modelock);
-	if (!port_extra->open_count) {
-		dbg("%s(): port not open", __func__);
-		goto exit;
-	}
-
-	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				QT2_BREAK_CONTROL, 0x40, break_value,
-				port->number, NULL, 0, 300);
-exit:
-	mutex_unlock(&port_extra->modelock);
-	dbg("%s(): exit port %d", __func__, port->number);
-
-}
-/**
- * qt2_throttle: - stop reading new data from the port
- */
-static void qt2_throttle(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct usb_serial *serial = port->serial;
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	dbg("%s(): port %d", __func__, port->number);
-
-	port_extra = qt2_get_port_private(port);
-	if (!serial) {
-		dbg("%s(): enter port %d no serial object", __func__,
-		      port->number);
-		return;
-	}
-
-	mutex_lock(&port_extra->modelock);	/* lock structure */
-	if (!port_extra->open_count) {
-		dbg("%s(): port not open", __func__);
-		goto exit;
-	}
-	/* Send command to box to stop receiving stuff. This will stop this
-	 * particular UART from filling the endpoint - in the multiport case the
-	 * FPGA UART will handle any flow control implemented, but for the single
-	 * port it's handed differently and we just quit submitting urbs
-	 */
-	if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100)
-		qt2_boxstoprx(serial, port->number, 1);
-
-	port->throttled = 1;
-exit:
-	mutex_unlock(&port_extra->modelock);
-	dbg("%s(): port %d: setting port->throttled", __func__, port->number);
-	return;
-}
-
-/**
- * qt2_unthrottle: - start receiving data through the port again after being
- * throttled
- */
-static void qt2_unthrottle(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct usb_serial *serial = port->serial;
-	struct quatech2_port *port_extra;	/* extra data for this port */
-	struct usb_serial_port *port0;	/* first port structure on device */
-	struct quatech2_dev *dev_extra;		/* extra data for the device */
-
-	if (!serial) {
-		dbg("%s() enter port %d no serial object!", __func__,
-			port->number);
-		return;
-	}
-	dbg("%s(): enter port %d", __func__, port->number);
-	dev_extra = qt2_get_dev_private(serial);
-	port_extra = qt2_get_port_private(port);
-	port0 = serial->port[0]; /* get the first port's device structure */
-
-	mutex_lock(&port_extra->modelock);
-	if (!port_extra->open_count) {
-		dbg("%s(): port %d not open", __func__, port->number);
-		goto exit;
-	}
-
-	if (port->throttled != 0) {
-		dbg("%s(): port %d: unsetting port->throttled", __func__,
-		    port->number);
-		port->throttled = 0;
-		/* Send command to box to start receiving stuff */
-		if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100) {
-			qt2_boxstoprx(serial,  port->number, 0);
-		} else if (dev_extra->ReadBulkStopped == true) {
-			usb_fill_bulk_urb(port0->read_urb, serial->dev,
-				usb_rcvbulkpipe(serial->dev,
-				port0->bulk_in_endpointAddress),
-				port0->bulk_in_buffer,
-				port0->bulk_in_size,
-				qt2_read_bulk_callback,
-				serial);
-		}
-	}
-exit:
-	mutex_unlock(&port_extra->modelock);
-	dbg("%s(): exit port %d", __func__, port->number);
-	return;
-}
-
-/* internal, private helper functions for the driver */
-
-/* Power up the FPGA in the box to get it working */
-static int qt2_boxpoweron(struct usb_serial *serial)
-{
-	int result;
-	__u8  Direcion;
-	unsigned int pipe;
-	Direcion = USBD_TRANSFER_DIRECTION_OUT;
-	pipe = usb_rcvctrlpipe(serial->dev, 0);
-	result = usb_control_msg(serial->dev, pipe, QT_SET_GET_DEVICE,
-				Direcion, QU2BOXPWRON, 0x00, NULL, 0x00,
-				5000);
-	return result;
-}
-
-/*
- * qt2_boxsetQMCR Issue a QT2_GET_SET_QMCR vendor-spcific request on the
- * default control pipe. If successful return the number of bytes written,
- * otherwise return a negative error number of the problem.
- */
-static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number,
-			  __u8 QMCR_Value)
-{
-	int result;
-	__u16 PortSettings;
-
-	PortSettings = (__u16)(QMCR_Value);
-
-	dbg("%s(): Port = %d, PortSettings = 0x%x", __func__,
-			Uart_Number, PortSettings);
-
-	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				QT2_GET_SET_QMCR, 0x40, PortSettings,
-				(__u16)Uart_Number, NULL, 0, 5000);
-	return result;
-}
-
-static int port_paranoia_check(struct usb_serial_port *port,
-			       const char *function)
-{
-	if (!port) {
-		dbg("%s - port == NULL", function);
-		return -1;
-	}
-	if (!port->serial) {
-		dbg("%s - port->serial == NULL\n", function);
-		return -1;
-	}
-	return 0;
-}
-
-static int serial_paranoia_check(struct usb_serial *serial,
-				 const char *function)
-{
-	if (!serial) {
-		dbg("%s - serial == NULL\n", function);
-		return -1;
-	}
-
-	if (!serial->type) {
-		dbg("%s - serial->type == NULL!", function);
-		return -1;
-	}
-
-	return 0;
-}
-
-static inline struct quatech2_port *qt2_get_port_private(struct usb_serial_port
-		*port)
-{
-	return (struct quatech2_port *)usb_get_serial_port_data(port);
-}
-
-static inline void qt2_set_port_private(struct usb_serial_port *port,
-		struct quatech2_port *data)
-{
-	usb_set_serial_port_data(port, (void *)data);
-}
-
-static inline struct quatech2_dev *qt2_get_dev_private(struct usb_serial
-		*serial)
-{
-	return (struct quatech2_dev *)usb_get_serial_data(serial);
-}
-static inline void qt2_set_dev_private(struct usb_serial *serial,
-		struct quatech2_dev *data)
-{
-	usb_set_serial_data(serial, (void *)data);
-}
-
-static int qt2_openboxchannel(struct usb_serial *serial, __u16
-		Uart_Number, struct qt2_status_data *status)
-{
-	int result;
-	__u16 length;
-	__u8  Direcion;
-	unsigned int pipe;
-	length = sizeof(struct qt2_status_data);
-	Direcion = USBD_TRANSFER_DIRECTION_IN;
-	pipe = usb_rcvctrlpipe(serial->dev, 0);
-	result = usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
-			Direcion, 0x00, Uart_Number, status, length, 5000);
-	return result;
-}
-static int qt2_closeboxchannel(struct usb_serial *serial, __u16 Uart_Number)
-{
-	int result;
-	__u8  direcion;
-	unsigned int pipe;
-	direcion = USBD_TRANSFER_DIRECTION_OUT;
-	pipe = usb_sndctrlpipe(serial->dev, 0);
-	result = usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
-		  direcion, 0, Uart_Number, NULL, 0, 5000);
-	return result;
-}
-
-/* qt2_conf_uart Issue a SET_UART vendor-spcific request on the default
- * control pipe. If successful sets baud rate divisor and LCR value
- */
-static int qt2_conf_uart(struct usb_serial *serial,  unsigned short Uart_Number,
-		      unsigned short divisor, unsigned char LCR)
-{
-	int result;
-	unsigned short UartNumandLCR;
-
-	UartNumandLCR = (LCR << 8) + Uart_Number;
-
-	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				QT2_GET_SET_UART, 0x40, divisor, UartNumandLCR,
-				NULL, 0, 300);
-	return result;
-}
-
-/** @brief Callback for asynchronous submission of read URBs on bulk in
- * endpoints
- *
- * Registered in qt2_open_port(), used to deal with incomming data
- * from the box.
- */
-static void qt2_read_bulk_callback(struct urb *urb)
-{
-	/* Get the device pointer (struct usb_serial) back out of the URB */
-	struct usb_serial *serial = urb->context;
-	/* get the extra struct for the device */
-	struct quatech2_dev *dev_extra = qt2_get_dev_private(serial);
-	/* Get first port structure from the device */
-	struct usb_serial_port *port0 = serial->port[0];
-	/* Get the currently active port structure from serial struct */
-	struct usb_serial_port *active = dev_extra->current_port;
-	/* get the extra struct for port 0 */
-	struct quatech2_port *port0_extra = qt2_get_port_private(port0);
-	/* and for the currently active port */
-	struct quatech2_port *active_extra = qt2_get_port_private(active);
-	/* When we finally get to doing some tty stuff, we will need this */
-	struct tty_struct *tty_st;
-	unsigned int RxCount;	/* the length of the data to process */
-	unsigned int i;	/* loop counter over the data to process */
-	int result;	/* return value cache variable */
-	bool escapeflag;	/* flag set to true if this loop iteration is
-				 * parsing an escape sequence, rather than
-				 * ordinary data */
-	dbg("%s(): callback running, active port is %d", __func__,
-		active->number);
-
-	if (urb->status) {
-		/* read didn't go well */
-		dev_extra->ReadBulkStopped = true;
-		dbg("%s(): nonzero bulk read status received: %d",
-			__func__, urb->status);
-		return;
-	}
-
-	/* inline port_sofrint() here */
-	if (port_paranoia_check(port0, __func__) != 0) {
-		dbg("%s - port_paranoia_check on port0 failed, exiting\n",
-__func__);
-		return;
-	}
-	if (port_paranoia_check(active, __func__) != 0) {
-		dbg("%s - port_paranoia_check on current_port "
-			"failed, exiting", __func__);
-		return;
-	}
-
-/* This single callback function has to do for all the ports on
- * the device. Data being read up the USB can contain certain
- * escape sequences which are used to communicate out-of-band
- * information from the serial port in-band over the USB.
- * These escapes include sending modem and flow control line
- * status, and switching the port. The concept of a "Current Port"
- * is used, which is where data is going until a port change
- * escape seqence is received. This Current Port is kept between
- * callbacks so that when this function enters we know which the
- * currently active port is and can get to work right away without
- * the box having to send repeat escape sequences (anyway, how
- * would it know to do so?).
- */
-
-	if (active_extra->close_pending == true) {
-		/* We are closing , stop reading */
-		dbg("%s - (active->close_pending == true", __func__);
-		if (dev_extra->open_ports <= 0) {
-			/* If this is the only port left open - stop the
-			 * bulk read */
-			dev_extra->ReadBulkStopped = true;
-			dbg("%s - (ReadBulkStopped == true;", __func__);
-			return;
-		}
-	}
-
-	/*
-	 * RxHolding is asserted by throttle, if we assert it, we're not
-	 * receiving any more characters and let the box handle the flow
-	 * control
-	 */
-	if ((port0_extra->RxHolding == true) &&
-		    (serial->dev->descriptor.idProduct == QUATECH_SSU2_100)) {
-		/* single port device, input is already stopped, so we don't
-		 * need any more input data */
-		dev_extra->ReadBulkStopped = true;
-		return;
-	}
-	/* finally, we are in a situation where we might consider the data
-	 * that is contained within the URB, and what to do about it.
-	 * This is likely to involved communicating up to the TTY layer, so
-	 * we will need to get hold of the tty for the port we are currently
-	 * dealing with */
-
-	/* active is a usb_serial_port. It has a member port which is a
-	 * tty_port. From this we get a tty_struct pointer which is what we
-	 * actually wanted, and keep it on tty_st */
-	tty_st = tty_port_tty_get(&active->port);
-	if (!tty_st) {
-		dbg("%s - bad tty pointer - exiting", __func__);
-		return;
-	}
-	RxCount = urb->actual_length;	/* grab length of data handy */
-
-	if (RxCount) {
-		/* skip all this if no data to process */
-		for (i = 0; i < RxCount ; ++i) {
-			/* Look ahead code here -works on several bytes at onc*/
-			if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b)
-				&& (NEXTCHAR == 0x1b)) {
-				/* we are in an escape sequence, type
-				 * determined by the 3rd char */
-				escapeflag = false;
-				switch (THIRDCHAR) {
-				case 0x00:
-					/* Line status change 4th byte must
-					 * follow */
-					if (i > (RxCount - 4)) {
-						dbg("Illegal escape sequences "
-						"in received data");
-						break;
-					}
-					qt2_process_line_status(active,
-						FOURTHCHAR);
-					i += 3;
-					escapeflag = true;
-					break;
-				case 0x01:
-					/* Modem status status change 4th byte
-					 * must follow */
-					if (i > (RxCount - 4)) {
-						dbg("Illegal escape sequences "
-						"in received data");
-						break;
-					}
-					qt2_process_modem_status(active,
-						FOURTHCHAR);
-					i += 3;
-					escapeflag = true;
-					break;
-				case 0x02:
-					/* xmit hold empty 4th byte
-					 * must follow */
-					if (i > (RxCount - 4)) {
-						dbg("Illegal escape sequences "
-						"in received data");
-						break;
-					}
-					qt2_process_xmit_empty(active,
-						FOURTHCHAR, FIFTHCHAR);
-					i += 4;
-					escapeflag = true;
-					break;
-				case 0x03:
-					/* Port number change 4th byte
-					 * must follow */
-					if (i > (RxCount - 4)) {
-						dbg("Illegal escape sequences "
-						"in received data");
-						break;
-					}
-					/* Port change. If port open push
-					 * current data up to tty layer */
-					if (active_extra->open_count > 0)
-						tty_flip_buffer_push(tty_st);
-
-					dbg("Port Change: new port = %d",
-						FOURTHCHAR);
-					qt2_process_port_change(active,
-						FOURTHCHAR);
-					i += 3;
-					escapeflag = true;
-					/* having changed port, the pointers for
-					 * the currently active port are all out
-					 * of date and need updating */
-					active = dev_extra->current_port;
-					active_extra =
-						qt2_get_port_private(active);
-					tty_st = tty_port_tty_get(
-						&active->port);
-					break;
-				case 0x04:
-					/* Recv flush 3rd byte must
-					 * follow */
-					if (i > (RxCount - 3)) {
-						dbg("Illegal escape sequences "
-							"in received data");
-						break;
-					}
-					qt2_process_rcv_flush(active);
-					i += 2;
-					escapeflag = true;
-					break;
-				case 0x05:
-					/* xmit flush 3rd byte must follow */
-					if (i > (RxCount - 3)) {
-						dbg("Illegal escape sequences "
-						"in received data");
-						break;
-					}
-					qt2_process_xmit_flush(active);
-					i += 2;
-					escapeflag = true;
-					break;
-				case 0xff:
-					dbg("No status sequence");
-					qt2_process_rx_char(active, THISCHAR);
-					qt2_process_rx_char(active, NEXTCHAR);
-					i += 2;
-					break;
-				default:
-					qt2_process_rx_char(active, THISCHAR);
-					i += 1;
-					break;
-				} /*end switch*/
-				if (escapeflag == true)
-					continue;
-				/* if we did an escape char, we don't need
-				 * to mess around pushing data through the
-				 * tty layer, and can go round again */
-			} /*endif*/
-			if (tty_st && urb->actual_length) {
-				tty_buffer_request_room(tty_st, 1);
-				tty_insert_flip_string(tty_st, &(
-						(unsigned char *)
-						(urb->transfer_buffer)
-					)[i], 1);
-			}
-		} /*endfor*/
-		tty_flip_buffer_push(tty_st);
-	} /*endif*/
-
-	/* at this point we have complete dealing with the data for this
-	 * callback. All we have to do now is to start the async read process
-	 * back off again. */
-
-	usb_fill_bulk_urb(port0->read_urb, serial->dev,
-		usb_rcvbulkpipe(serial->dev, port0->bulk_in_endpointAddress),
-		port0->bulk_in_buffer, port0->bulk_in_size,
-		qt2_read_bulk_callback, serial);
-	result = usb_submit_urb(port0->read_urb, GFP_ATOMIC);
-	if (result) {
-		dbg("%s(): failed resubmitting read urb, error %d",
-			__func__, result);
-	} else {
-		dbg("%s() successfully resubmitted read urb", __func__);
-		if (tty_st && RxCount) {
-			/* if some inbound data was processed, then
-			 * we need to push that through the tty layer
-			 */
-			tty_flip_buffer_push(tty_st);
-			tty_schedule_flip(tty_st);
-		}
-	}
-
-	/* cribbed from serqt_usb2 driver, but not sure which work needs
-	 * scheduling - port0 or currently active port? */
-	/* schedule_work(&port->work); */
-	dbg("%s() completed", __func__);
-	return;
-}
-
-/** @brief Callback for asynchronous submission of write URBs on bulk in
- * endpoints
- *
- * Registered in qt2_write(), used to deal with outgoing data
- * to the box.
- */
-static void qt2_write_bulk_callback(struct urb *urb)
-{
-	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-	struct usb_serial *serial = port->serial;
-	dbg("%s(): port %d", __func__, port->number);
-	if (!serial) {
-		dbg("%s(): bad serial pointer, exiting", __func__);
-		return;
-	}
-	if (urb->status) {
-		dbg("%s(): nonzero write bulk status received: %d",
-			__func__, urb->status);
-		return;
-	}
-	/* FIXME What is supposed to be going on here?
-	 * does this actually do anything useful, and should it?
-	 */
-	/*port_softint((void *) serial); commented in vendor driver */
-	schedule_work(&port->work);
-	dbg("%s(): port %d exit", __func__, port->number);
-	return;
-}
-
-static void qt2_process_line_status(struct usb_serial_port *port,
-	unsigned char LineStatus)
-{
-	/* obtain the private structure for the port */
-	struct quatech2_port *port_extra = qt2_get_port_private(port);
-	port_extra->shadowLSR = LineStatus & (QT2_SERIAL_LSR_OE |
-		QT2_SERIAL_LSR_PE | QT2_SERIAL_LSR_FE | QT2_SERIAL_LSR_BI);
-}
-static void qt2_process_modem_status(struct usb_serial_port *port,
-	unsigned char ModemStatus)
-{
-	/* obtain the private structure for the port */
-	struct quatech2_port *port_extra = qt2_get_port_private(port);
-	port_extra->shadowMSR = ModemStatus;
-	wake_up_interruptible(&port_extra->wait);
-	/* this wakes up the otherwise indefinitely waiting code for
-	 * the TIOCMIWAIT ioctl, so that it can notice that
-	 * port_extra->shadowMSR has changed and the ioctl needs to return.
-	 */
-}
-
-static void qt2_process_xmit_empty(struct usb_serial_port *port,
-	unsigned char fourth_char, unsigned char fifth_char)
-{
-	int byte_count;
-	/* obtain the private structure for the port */
-	struct quatech2_port *port_extra = qt2_get_port_private(port);
-
-	byte_count = (int)(fifth_char * 16);
-	byte_count +=  (int)fourth_char;
-	/* byte_count indicates how many bytes the device has written out. This
-	 * message appears to occur regularly, and is used in the vendor driver
-	 * to keep track of the fill state of the port transmit buffer */
-	port_extra->tx_pending_bytes -= byte_count;
-	/* reduce the stored data queue length by the known number of bytes
-	 * sent */
-	dbg("port %d: %d bytes reported sent, %d still pending", port->number,
-			byte_count, port_extra->tx_pending_bytes);
-
-	/*port_extra->xmit_fifo_room_bytes = FIFO_DEPTH; ???*/
-}
-
-static void qt2_process_port_change(struct usb_serial_port *port,
-	unsigned char New_Current_Port)
-{
-	/* obtain the parent usb serial device structure */
-	struct usb_serial *serial = port->serial;
-	/* obtain the private structure for the device */
-	struct quatech2_dev *dev_extra = qt2_get_dev_private(serial);
-	dev_extra->current_port = serial->port[New_Current_Port];
-	/* what should I do with this? commented out in upstream
-	 * driver */
-	/*schedule_work(&port->work);*/
-}
-
-static void qt2_process_rcv_flush(struct usb_serial_port *port)
-{
-	/* obtain the private structure for the port */
-	struct quatech2_port *port_extra = qt2_get_port_private(port);
-	port_extra->rcv_flush = true;
-}
-static void qt2_process_xmit_flush(struct usb_serial_port *port)
-{
-	/* obtain the private structure for the port */
-	struct quatech2_port *port_extra = qt2_get_port_private(port);
-	port_extra->xmit_flush = true;
-}
-
-static void qt2_process_rx_char(struct usb_serial_port *port,
-	unsigned char data)
-{
-	/* get the tty_struct for this port */
-	struct tty_struct *tty = tty_port_tty_get(&(port->port));
-	/* get the URB with the data in to push */
-	struct urb *urb = port->serial->port[0]->read_urb;
-
-	if (tty && urb->actual_length) {
-		tty_buffer_request_room(tty, 1);
-		tty_insert_flip_string(tty, &data, 1);
-		/* should this be commented out here? */
-		/*tty_flip_buffer_push(tty);*/
-	}
-}
-
-/** @brief Retrieve the value of a register from the device
- *
- * Issues a GET_REGISTER vendor-spcific request over the USB control
- * pipe to obtain a value back from a specific register on a specific
- * UART
- * @param serial Serial device handle to access the device through
- * @param uart_number Which UART the value is wanted from
- * @param register_num Which register to read the value from
- * @param pValue Pointer to somewhere to put the retrieved value
- */
-static int qt2_box_get_register(struct usb_serial *serial,
-		unsigned char uart_number, unsigned short register_num,
-		__u8 *pValue)
-{
-	int result;
-	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-			QT2_GET_SET_REGISTER, 0xC0, register_num,
-			uart_number, (void *)pValue, sizeof(*pValue), 300);
-	return result;
-}
-
-/** qt2_box_set_register
- * Issue a SET_REGISTER vendor-specific request on the default control pipe
- */
-static int qt2_box_set_register(struct usb_serial *serial,
-		unsigned short Uart_Number, unsigned short Register_Num,
-		unsigned short Value)
-{
-	int result;
-	unsigned short reg_and_byte;
-
-	reg_and_byte = Value;
-	reg_and_byte = reg_and_byte << 8;
-	reg_and_byte = reg_and_byte + Register_Num;
-
-	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			QT2_GET_SET_REGISTER, 0x40, reg_and_byte,
-			Uart_Number, NULL, 0, 300);
-	return result;
-}
-
-/** qt2_boxsetuart - Issue a SET_UART vendor-spcific request on the default
- * control pipe. If successful sets baud rate divisor and LCR value.
- */
-static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
-		unsigned short default_divisor, unsigned char default_LCR)
-{
-	unsigned short UartNumandLCR;
-
-	UartNumandLCR = (default_LCR << 8) + Uart_Number;
-
-	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			QT2_GET_SET_UART, 0x40, default_divisor, UartNumandLCR,
-			NULL, 0, 300);
-}
-
-/** qt2_boxsethw_flowctl - Turn hardware (RTS/CTS) flow control on and off for
- * a hardware UART.
- */
-static int qt2_boxsethw_flowctl(struct usb_serial *serial,
-		unsigned int UartNumber, bool bSet)
-{
-	__u8 MCR_Value = 0;
-	__u8 MSR_Value = 0;
-	__u16 MOUT_Value = 0;
-
-	if (bSet == true) {
-		MCR_Value =  QT2_SERIAL_MCR_RTS;
-		/* flow control, box will clear RTS line to prevent remote
-		 * device from transmitting more chars */
-	} else {
-		/* no flow control to remote device */
-		MCR_Value =  0;
-	}
-	MOUT_Value = MCR_Value << 8;
-
-	if (bSet == true) {
-		MSR_Value = QT2_SERIAL_MSR_CTS;
-		/* flow control on, box will inhibit tx data if CTS line is
-		 * asserted */
-	} else {
-		/* Box will not inhibit tx data due to CTS line */
-		MSR_Value = 0;
-	}
-	MOUT_Value |= MSR_Value;
-	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			QT2_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value, UartNumber,
-			NULL, 0, 300);
-}
-
-/** qt2_boxsetsw_flowctl - Turn software (XON/XOFF) flow control on for
- * a hardware UART, and set the XON and XOFF characters.
- */
-static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber,
-			unsigned char stop_char,  unsigned char start_char)
-{
-	__u16 nSWflowout;
-
-	nSWflowout = start_char << 8;
-	nSWflowout = (unsigned short)stop_char;
-	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			QT2_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout, UartNumber,
-			NULL, 0, 300);
-}
-
-/** qt2_boxunsetsw_flowctl - Turn software (XON/XOFF) flow control off for
- * a hardware UART.
- */
-static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber)
-{
-	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-			QT2_SW_FLOW_CONTROL_DISABLE, 0x40, 0, UartNumber, NULL,
-			0, 300);
-}
-
-/**
- * qt2_boxstoprx - Start and stop reception of data by the FPGA UART in
- * response to requests from the tty layer
- * @serial: pointer to the usb_serial structure for the parent device
- * @uart_number: which UART on the device we are addressing
- * @stop: Whether to start or stop data reception. Set to 1 to stop data being
- * received, and to 0 to start it being received.
- */
-static int qt2_boxstoprx(struct usb_serial *serial, unsigned short uart_number,
-		unsigned short stop)
-{
-	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-		QT2_STOP_RECEIVE, 0x40, stop, uart_number, NULL, 0, 300);
-}
-
-
-/*
- * last things in file: stuff to register this driver into the generic
- * USB serial framework.
- */
-
-static struct usb_serial_driver quatech2_device = {
-	.driver = {
-		.owner = THIS_MODULE,
-		.name = "quatech_usb2",
-	},
-	.description = DRIVER_DESC,
-	.id_table = quausb2_id_table,
-	.num_ports = 8,
-	.open = qt2_open,
-	.close = qt2_close,
-	.write = qt2_write,
-	.write_room = qt2_write_room,
-	.chars_in_buffer = qt2_chars_in_buffer,
-	.throttle = qt2_throttle,
-	.unthrottle = qt2_unthrottle,
-	.calc_num_ports = qt2_calc_num_ports,
-	.ioctl = qt2_ioctl,
-	.set_termios = qt2_set_termios,
-	.break_ctl = qt2_break,
-	.tiocmget = qt2_tiocmget,
-	.tiocmset = qt2_tiocmset,
-	.attach = qt2_attach,
-	.release = qt2_release,
-	.read_bulk_callback = qt2_read_bulk_callback,
-	.write_bulk_callback = qt2_write_bulk_callback,
-};
-
-static struct usb_serial_driver * const serial_drivers[] = {
-	&quatech2_device, NULL
-};
-
-module_usb_serial_driver(quausb2_usb_driver, serial_drivers);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index ae1d815..43045db 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -41,13 +41,6 @@
 #define QUATECH_HSU200B	0xC0B1	/* HSU200B */
 #define QUATECH_HSU200C	0xC0B2	/* HSU200C */
 #define QUATECH_HSU200D	0xC0B3	/* HSU200D */
-#define QUATECH_SSU100_2  0xC120	/* SSU100_2 */
-#define QUATECH_DSU100_2  0xC140	/* DSU100_2 */
-#define QUATECH_DSU400_2  0xC150	/* DSU400_2 */
-#define QUATECH_QSU100_2  0xC160	/* QSU100_2 */
-#define QUATECH_QSU400_2  0xC170	/* QSU400_2 */
-#define QUATECH_ESU400_2  0xC180	/* ESU400_2 */
-#define QUATECH_ESU100_2  0xC1A0	/* ESU100_2 */
 
 #define QT_SET_GET_DEVICE           0xc2
 #define QT_OPEN_CLOSE_CHANNEL       0xca
@@ -125,7 +118,7 @@
 #define MODEM_CTRL          0x40
 #define RS232_MODE          0x00
 
-static const struct usb_device_id serqt_id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU200)},
@@ -143,17 +136,9 @@
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200B)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200C)},
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_HSU200D)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100_2)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100_2)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU400_2)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU100_2)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU400_2)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU400_2)},
-	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU100_2)},
 	{}			/* Terminating entry */
 };
-
-MODULE_DEVICE_TABLE(usb, serqt_id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 struct qt_get_device_data {
 	__u8 porta;
@@ -195,13 +180,6 @@
 	char closePending;
 };
 
-static struct usb_driver serqt_usb_driver = {
-	.name = "quatech-usb-serial",
-	.probe = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-	.id_table = serqt_id_table,
-};
-
 static int port_paranoia_check(struct usb_serial_port *port,
 			       const char *function)
 {
@@ -304,8 +282,6 @@
 
 	quatech_port = urb->context;
 
-	dbg("%s - port %d\n", __func__, quatech_port->port_num);
-
 	tty = tty_port_tty_get(&quatech_port->port->port);
 
 	if (tty)
@@ -351,7 +327,6 @@
 	/* index = MINOR(port->tty->device) - serial->minor; */
 	index = tty->index - serial->minor;
 
-	dbg("%s - port %d\n", __func__, port->number);
 	dbg("%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding);
 
 	if (port_paranoia_check(port, __func__) != 0) {
@@ -726,8 +701,6 @@
 	int i;
 	int status;
 
-	dbg("enterting %s", __func__);
-
 	/* Now setup per port private data */
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
@@ -855,8 +828,6 @@
 	struct quatech_port *qt_port;
 	int i;
 
-	dbg("enterting %s", __func__);
-
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
 		if (!port)
@@ -882,8 +853,6 @@
 	if (port_paranoia_check(port, __func__))
 		return -ENODEV;
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	serial = port->serial;
 
 	if (serial_paranoia_check(serial, __func__))
@@ -1006,8 +975,6 @@
 
 	serial = get_usb_serial(port, __func__);
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	if (serial->num_bulk_out) {
 		if (port->write_urb->status == -EINPROGRESS)
 			chars = port->write_urb->transfer_buffer_length;
@@ -1054,8 +1021,6 @@
 	unsigned int index;
 	status = 0;
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	tty = tty_port_tty_get(&port->port);
 	index = tty->index - serial->minor;
 
@@ -1109,8 +1074,6 @@
 	if (serial == NULL)
 		return -ENODEV;
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	if (count == 0) {
 		dbg("%s - write request of 0 bytes\n", __func__);
 		return 0;
@@ -1173,8 +1136,6 @@
 
 	mutex_lock(&qt_port->lock);
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	if (serial->num_bulk_out) {
 		if (port->write_urb->status != -EINPROGRESS)
 			retval = port->bulk_out_size;
@@ -1241,8 +1202,6 @@
 	int baud, divisor, remainder;
 	int status;
 
-	dbg("%s", __func__);
-
 	index = tty->index - port->serial->minor;
 
 	switch (cflag) {
@@ -1365,8 +1324,6 @@
 
 	mutex_lock(&qt_port->lock);
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	result =
 	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			    QT_BREAK_CONTROL, 0x40, onoff, index, NULL, 0, 300);
@@ -1385,8 +1342,6 @@
 	int status;
 	unsigned int index;
 
-	dbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
-
 	index = tty->index - serial->minor;
 	status =
 	    BoxGetRegister(port->serial, index, MODEM_CONTROL_REGISTER, &mcr);
@@ -1426,8 +1381,6 @@
 	int status;
 	unsigned int index;
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	index = tty->index - serial->minor;
 	status =
 	    BoxGetRegister(port->serial, index, MODEM_CONTROL_REGISTER, &mcr);
@@ -1461,18 +1414,11 @@
 	struct quatech_port *qt_port = qt_get_port_private(port);
 	int retval = -ENODEV;
 
-	dbg("In %s\n", __func__);
-
 	if (!serial)
 		return -ENODEV;
 
 	mutex_lock(&qt_port->lock);
-
-	dbg("%s - port %d\n", __func__, port->number);
-	dbg("%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding);
-
 	retval = qt_real_tiocmget(tty, port, serial);
-
 	mutex_unlock(&qt_port->lock);
 	return retval;
 }
@@ -1486,18 +1432,11 @@
 	struct quatech_port *qt_port = qt_get_port_private(port);
 	int retval = -ENODEV;
 
-	dbg("In %s\n", __func__);
-
 	if (!serial)
 		return -ENODEV;
 
 	mutex_lock(&qt_port->lock);
-
-	dbg("%s - port %d\n", __func__, port->number);
-	dbg("%s - qt_port->RxHolding = %d\n", __func__, qt_port->RxHolding);
-
 	retval = qt_real_tiocmset(tty, port, serial, set);
-
 	mutex_unlock(&qt_port->lock);
 	return retval;
 }
@@ -1508,8 +1447,6 @@
 	struct usb_serial *serial = get_usb_serial(port, __func__);
 	struct quatech_port *qt_port;
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	if (!serial)
 		return;
 
@@ -1519,7 +1456,6 @@
 
 	/* pass on to the driver specific version of this function */
 	qt_port->RxHolding = 1;
-	dbg("%s - port->RxHolding = 1\n", __func__);
 
 	mutex_unlock(&qt_port->lock);
 	return;
@@ -1539,8 +1475,6 @@
 
 	mutex_lock(&qt_port->lock);
 
-	dbg("%s - port %d\n", __func__, port->number);
-
 	if (qt_port->RxHolding == 1) {
 		dbg("%s -qt_port->RxHolding == 1\n", __func__);
 
@@ -1559,8 +1493,9 @@
 					  qt_read_bulk_callback, port);
 			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 			if (result)
-				err("%s - failed restarting read urb, error %d",
-				    __func__, result);
+				dev_err(&port->dev,
+					"%s - failed restarting read urb, error %d\n",
+					__func__, result);
 		}
 	}
 	mutex_unlock(&qt_port->lock);
@@ -1589,7 +1524,7 @@
 		   .name = "serqt",
 		   },
 	.description = DRIVER_DESC,
-	.id_table = serqt_id_table,
+	.id_table = id_table,
 	.num_ports = 8,
 	.open = qt_open,
 	.close = qt_close,
@@ -1612,7 +1547,7 @@
 	&quatech_device, NULL
 };
 
-module_usb_serial_driver(serqt_usb_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 76316a3..a7773a3 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -133,6 +133,8 @@
 
 source "drivers/usb/musb/Kconfig"
 
+source "drivers/usb/chipidea/Kconfig"
+
 source "drivers/usb/renesas_usbhs/Kconfig"
 
 source "drivers/usb/class/Kconfig"
@@ -177,6 +179,8 @@
 
 source "drivers/usb/misc/Kconfig"
 
+source "drivers/usb/phy/Kconfig"
+
 source "drivers/usb/atm/Kconfig"
 
 source "drivers/usb/gadget/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 53a7bc0..c691eea 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -46,12 +46,14 @@
 obj-$(CONFIG_USB_SERIAL)	+= serial/
 
 obj-$(CONFIG_USB)		+= misc/
+obj-$(CONFIG_USB)		+= phy/
 obj-$(CONFIG_EARLY_PRINTK_DBGP)	+= early/
 
 obj-$(CONFIG_USB_ATM)		+= atm/
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= atm/
 
 obj-$(CONFIG_USB_MUSB_HDRC)	+= musb/
+obj-$(CONFIG_USB_CHIPIDEA)	+= chipidea/
 obj-$(CONFIG_USB_RENESAS_USBHS)	+= renesas_usbhs/
 obj-$(CONFIG_USB_GADGET)	+= gadget/
 
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 98b89fe..b7eb86a 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -674,7 +674,7 @@
 	}
 
 	ret = offd;
-	dbg("cm %#x", cm);
+	usb_dbg(instance->usbatm, "cm %#x\n", cm);
 fail:
 	mutex_unlock(&instance->cm_serialize);
 err:
@@ -733,7 +733,7 @@
 {
 	int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
 	if (ret < 0) {		/* firmware not loaded */
-		dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret);
+		usb_dbg(instance->usbatm, "cxacru_adsl_start: CARD_GET_STATUS returned %d\n", ret);
 		return ret;
 	}
 	return 0;
@@ -758,7 +758,7 @@
 	int ret;
 	int start_polling = 1;
 
-	dbg("cxacru_atm_start");
+	dev_dbg(&intf->dev, "%s\n", __func__);
 
 	/* Read MAC address */
 	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0,
@@ -962,13 +962,13 @@
 			ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
 					   buf, offb, NULL, CMD_TIMEOUT);
 			if (ret < 0) {
-				dbg("sending fw %#x failed", fw);
+				dev_dbg(&usb_dev->dev, "sending fw %#x failed\n", fw);
 				goto cleanup;
 			}
 			offb = 0;
 		}
 	} while (offd < size);
-	dbg("sent fw %#x", fw);
+	dev_dbg(&usb_dev->dev, "sent fw %#x\n", fw);
 
 	ret = 0;
 
@@ -988,7 +988,7 @@
 			       usb_dev->descriptor.idProduct };
 	__le32 val;
 
-	dbg("cxacru_upload_firmware");
+	usb_dbg(usbatm, "%s\n", __func__);
 
 	/* FirmwarePllFClkValue */
 	val = cpu_to_le32(instance->modem_type->pll_f_clk);
@@ -1074,7 +1074,7 @@
 	char buf[16];
 
 	sprintf(buf, "cxacru-%s.bin", phase);
-	dbg("cxacru_find_firmware: looking for %s", buf);
+	usb_dbg(usbatm, "cxacru_find_firmware: looking for %s\n", buf);
 
 	if (request_firmware(fw_p, buf, dev)) {
 		usb_dbg(usbatm, "no stage %s firmware found\n", phase);
@@ -1115,9 +1115,9 @@
 
 	ret = cxacru_card_status(instance);
 	if (ret)
-		dbg("modem initialisation failed");
+		usb_dbg(usbatm_instance, "modem initialisation failed\n");
 	else
-		dbg("done setting up the modem");
+		usb_dbg(usbatm_instance, "done setting up the modem\n");
 
 	return ret;
 }
@@ -1133,7 +1133,7 @@
 	/* instance init */
 	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 	if (!instance) {
-		dbg("cxacru_bind: no memory for instance data");
+		usb_dbg(usbatm_instance, "cxacru_bind: no memory for instance data\n");
 		return -ENOMEM;
 	}
 
@@ -1149,31 +1149,31 @@
 
 	instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL);
 	if (!instance->rcv_buf) {
-		dbg("cxacru_bind: no memory for rcv_buf");
+		usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_buf\n");
 		ret = -ENOMEM;
 		goto fail;
 	}
 	instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL);
 	if (!instance->snd_buf) {
-		dbg("cxacru_bind: no memory for snd_buf");
+		usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_buf\n");
 		ret = -ENOMEM;
 		goto fail;
 	}
 	instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!instance->rcv_urb) {
-		dbg("cxacru_bind: no memory for rcv_urb");
+		usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_urb\n");
 		ret = -ENOMEM;
 		goto fail;
 	}
 	instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!instance->snd_urb) {
-		dbg("cxacru_bind: no memory for snd_urb");
+		usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_urb\n");
 		ret = -ENOMEM;
 		goto fail;
 	}
 
 	if (!cmd_ep) {
-		dbg("cxacru_bind: no command endpoint");
+		usb_dbg(usbatm_instance, "cxacru_bind: no command endpoint\n");
 		ret = -ENODEV;
 		goto fail;
 	}
@@ -1227,10 +1227,10 @@
 	struct cxacru_data *instance = usbatm_instance->driver_data;
 	int is_polling = 1;
 
-	dbg("cxacru_unbind entered");
+	usb_dbg(usbatm_instance, "cxacru_unbind entered\n");
 
 	if (!instance) {
-		dbg("cxacru_unbind: NULL instance!");
+		usb_dbg(usbatm_instance, "cxacru_unbind: NULL instance!\n");
 		return;
 	}
 
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 98dd9e4..975e9c6 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -170,7 +170,7 @@
 			 "%sabling SW buffering: usb_control_msg returned %d\n",
 			 state ? "En" : "Dis", ret);
 	else
-		dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis");
+		usb_dbg(usbatm, "speedtch_set_swbuff: %sbled SW buffering\n", state ? "En" : "Dis");
 }
 
 static void speedtch_test_sequence(struct speedtch_instance_data *instance)
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 01ea5d7..d7e422d 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -1357,10 +1357,8 @@
 		/* release the dsp firmware as it is not needed until
 		 * the next failure
 		 */
-		if (sc->dsp_firm) {
-			release_firmware(sc->dsp_firm);
-			sc->dsp_firm = NULL;
-		}
+		release_firmware(sc->dsp_firm);
+		sc->dsp_firm = NULL;
 	}
 
 	/* always update it as atm layer could not be init when we switch to
@@ -1496,10 +1494,8 @@
 		/* release the dsp firmware as it is not needed until
 		 * the next failure
 		 */
-		if (sc->dsp_firm) {
-			release_firmware(sc->dsp_firm);
-			sc->dsp_firm = NULL;
-		}
+		release_firmware(sc->dsp_firm);
+		sc->dsp_firm = NULL;
 	}
 
 	/* always update it as atm layer could not be init when we switch to
@@ -2240,8 +2236,7 @@
 	/* flush the work item, when no one can schedule it */
 	flush_work_sync(&sc->task);
 
-	if (sc->dsp_firm)
-		release_firmware(sc->dsp_firm);
+	release_firmware(sc->dsp_firm);
 	uea_leaves(INS_TO_USBDEV(sc));
 }
 
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index d3448ca..ee62b35 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -86,7 +86,7 @@
 #ifdef VERBOSE_DEBUG
 static int usbatm_print_packet(const unsigned char *data, int len);
 #define PACKETDEBUG(arg...)	usbatm_print_packet(arg)
-#define vdbg(arg...)		dbg(arg)
+#define vdbg(arg...)		dev_dbg(arg)
 #else
 #define PACKETDEBUG(arg...)
 #define vdbg(arg...)
@@ -714,7 +714,7 @@
 {
 	struct usbatm_data *instance = container_of(kref, struct usbatm_data, refcount);
 
-	dbg("%s", __func__);
+	usb_dbg(instance, "%s\n", __func__);
 
 	tasklet_kill(&instance->rx_channel.tasklet);
 	tasklet_kill(&instance->tx_channel.tasklet);
@@ -724,14 +724,14 @@
 
 static void usbatm_get_instance(struct usbatm_data *instance)
 {
-	dbg("%s", __func__);
+	usb_dbg(instance, "%s\n", __func__);
 
 	kref_get(&instance->refcount);
 }
 
 static void usbatm_put_instance(struct usbatm_data *instance)
 {
-	dbg("%s", __func__);
+	usb_dbg(instance, "%s\n", __func__);
 
 	kref_put(&instance->refcount, usbatm_destroy_instance);
 }
@@ -745,11 +745,10 @@
 {
 	struct usbatm_data *instance = atm_dev->dev_data;
 
-	dbg("%s", __func__);
-
 	if (!instance)
 		return;
 
+	usb_dbg(instance, "%s\n", __func__);
 	atm_dev->dev_data = NULL; /* catch bugs */
 	usbatm_put_instance(instance);	/* taken in usbatm_atm_init */
 }
@@ -759,10 +758,8 @@
 	struct usbatm_data *instance = atm_dev->dev_data;
 	int left = *pos;
 
-	if (!instance) {
-		dbg("%s: NULL instance!", __func__);
+	if (!instance)
 		return -ENODEV;
-	}
 
 	if (!left--)
 		return sprintf(page, "%s\n", instance->description);
@@ -804,10 +801,8 @@
 	int vci = vcc->vci;
 	short vpi = vcc->vpi;
 
-	if (!instance) {
-		dbg("%s: NULL data!", __func__);
+	if (!instance)
 		return -ENODEV;
-	}
 
 	atm_dbg(instance, "%s: vpi %hd, vci %d\n", __func__, vpi, vci);
 
@@ -884,10 +879,8 @@
 	struct usbatm_data *instance = vcc->dev->dev_data;
 	struct usbatm_vcc_data *vcc_data = vcc->dev_data;
 
-	if (!instance || !vcc_data) {
-		dbg("%s: NULL data!", __func__);
+	if (!instance || !vcc_data)
 		return;
-	}
 
 	atm_dbg(instance, "%s entered\n", __func__);
 
@@ -929,10 +922,8 @@
 {
 	struct usbatm_data *instance = atm_dev->dev_data;
 
-	if (!instance || instance->disconnected) {
-		dbg("%s: %s!", __func__, instance ? "disconnected" : "NULL instance");
+	if (!instance || instance->disconnected)
 		return -ENODEV;
-	}
 
 	switch (cmd) {
 	case ATM_QUERYLOOP:
@@ -1336,8 +1327,6 @@
 
 static int __init usbatm_usb_init(void)
 {
-	dbg("%s: driver version %s", __func__, DRIVER_VERSION);
-
 	if (sizeof(struct usbatm_control) > FIELD_SIZEOF(struct sk_buff, cb)) {
 		printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name);
 		return -EIO;
@@ -1357,7 +1346,6 @@
 
 static void __exit usbatm_usb_exit(void)
 {
-	dbg("%s", __func__);
 }
 module_exit(usbatm_usb_exit);
 
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 48ee0c5..14ec9f0 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -187,8 +187,6 @@
 {
 	int i;
 
-	dbg("xusbatm_init");
-
 	if (!num_vendor ||
 	    num_vendor != num_product ||
 	    num_vendor != num_rx_endpoint ||
@@ -221,8 +219,6 @@
 
 static void __exit xusbatm_exit(void)
 {
-	dbg("xusbatm_exit entered");
-
 	usb_deregister(&xusbatm_usb_driver);
 }
 module_exit(xusbatm_exit);
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
new file mode 100644
index 0000000..fd36dc8
--- /dev/null
+++ b/drivers/usb/chipidea/Kconfig
@@ -0,0 +1,32 @@
+config USB_CHIPIDEA
+	tristate "ChipIdea Highspeed Dual Role Controller"
+	depends on USB
+	help
+          Say Y here if your system has a dual role high speed USB
+          controller based on ChipIdea silicon IP. Currently, only the
+	  peripheral mode is supported.
+
+	  When compiled dynamically, the module will be called ci-hdrc.ko.
+
+if USB_CHIPIDEA
+
+config USB_CHIPIDEA_UDC
+	bool "ChipIdea device controller"
+	depends on USB_GADGET
+	select USB_GADGET_DUALSPEED
+	help
+	  Say Y here to enable device controller functionality of the
+	  ChipIdea driver.
+
+config USB_CHIPIDEA_HOST
+	bool "ChipIdea host controller"
+	help
+	  Say Y here to enable host controller functionality of the
+	  ChipIdea driver.
+
+config USB_CHIPIDEA_DEBUG
+	bool "ChipIdea driver debug"
+	help
+	  Say Y here to enable debugging output of the ChipIdea driver.
+
+endif
diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile
new file mode 100644
index 0000000..cc34937
--- /dev/null
+++ b/drivers/usb/chipidea/Makefile
@@ -0,0 +1,14 @@
+obj-$(CONFIG_USB_CHIPIDEA)		+= ci_hdrc.o
+
+ci_hdrc-y				:= core.o
+ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
+ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
+ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG)	+= debug.o
+
+ifneq ($(CONFIG_PCI),)
+	obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_pci.o
+endif
+
+ifneq ($(CONFIG_ARCH_MSM),)
+	obj-$(CONFIG_USB_CHIPIDEA)	+= ci13xxx_msm.o
+endif
diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
new file mode 100644
index 0000000..050de85
--- /dev/null
+++ b/drivers/usb/chipidea/bits.h
@@ -0,0 +1,90 @@
+/*
+ * bits.h - register bits of the ChipIdea USB IP core
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_BITS_H
+#define __DRIVERS_USB_CHIPIDEA_BITS_H
+
+#include <linux/usb/ehci_def.h>
+
+/* HCCPARAMS */
+#define HCCPARAMS_LEN         BIT(17)
+
+/* DCCPARAMS */
+#define DCCPARAMS_DEN         (0x1F << 0)
+#define DCCPARAMS_DC          BIT(7)
+#define DCCPARAMS_HC          BIT(8)
+
+/* TESTMODE */
+#define TESTMODE_FORCE        BIT(0)
+
+/* USBCMD */
+#define USBCMD_RS             BIT(0)
+#define USBCMD_RST            BIT(1)
+#define USBCMD_SUTW           BIT(13)
+#define USBCMD_ATDTW          BIT(14)
+
+/* USBSTS & USBINTR */
+#define USBi_UI               BIT(0)
+#define USBi_UEI              BIT(1)
+#define USBi_PCI              BIT(2)
+#define USBi_URI              BIT(6)
+#define USBi_SLI              BIT(8)
+
+/* DEVICEADDR */
+#define DEVICEADDR_USBADRA    BIT(24)
+#define DEVICEADDR_USBADR     (0x7FUL << 25)
+
+/* PORTSC */
+#define PORTSC_FPR            BIT(6)
+#define PORTSC_SUSP           BIT(7)
+#define PORTSC_HSP            BIT(9)
+#define PORTSC_PTC            (0x0FUL << 16)
+
+/* DEVLC */
+#define DEVLC_PSPD            (0x03UL << 25)
+#define    DEVLC_PSPD_HS      (0x02UL << 25)
+
+/* OTGSC */
+#define OTGSC_IDPU	      BIT(5)
+#define OTGSC_ID	      BIT(8)
+#define OTGSC_AVV	      BIT(9)
+#define OTGSC_ASV	      BIT(10)
+#define OTGSC_BSV	      BIT(11)
+#define OTGSC_BSE	      BIT(12)
+#define OTGSC_IDIS	      BIT(16)
+#define OTGSC_AVVIS	      BIT(17)
+#define OTGSC_ASVIS	      BIT(18)
+#define OTGSC_BSVIS	      BIT(19)
+#define OTGSC_BSEIS	      BIT(20)
+#define OTGSC_IDIE	      BIT(24)
+#define OTGSC_AVVIE	      BIT(25)
+#define OTGSC_ASVIE	      BIT(26)
+#define OTGSC_BSVIE	      BIT(27)
+#define OTGSC_BSEIE	      BIT(28)
+
+/* USBMODE */
+#define USBMODE_CM            (0x03UL <<  0)
+#define USBMODE_CM_DC         (0x02UL <<  0)
+#define USBMODE_SLOM          BIT(3)
+#define USBMODE_CI_SDIS       BIT(4)
+
+/* ENDPTCTRL */
+#define ENDPTCTRL_RXS         BIT(0)
+#define ENDPTCTRL_RXT         (0x03UL <<  2)
+#define ENDPTCTRL_RXR         BIT(6)         /* reserved for port 0 */
+#define ENDPTCTRL_RXE         BIT(7)
+#define ENDPTCTRL_TXS         BIT(16)
+#define ENDPTCTRL_TXT         (0x03UL << 18)
+#define ENDPTCTRL_TXR         BIT(22)        /* reserved for port 0 */
+#define ENDPTCTRL_TXE         BIT(23)
+
+#endif /* __DRIVERS_USB_CHIPIDEA_BITS_H */
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
new file mode 100644
index 0000000..50911f8
--- /dev/null
+++ b/drivers/usb/chipidea/ci.h
@@ -0,0 +1,313 @@
+/*
+ * ci.h - common structures, functions, and macros of the ChipIdea driver
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_CI_H
+#define __DRIVERS_USB_CHIPIDEA_CI_H
+
+#include <linux/list.h>
+#include <linux/irqreturn.h>
+#include <linux/usb.h>
+#include <linux/usb/gadget.h>
+
+/******************************************************************************
+ * DEFINE
+ *****************************************************************************/
+#define CI13XXX_PAGE_SIZE  4096ul /* page size for TD's */
+#define ENDPT_MAX          32
+
+/******************************************************************************
+ * STRUCTURES
+ *****************************************************************************/
+/**
+ * struct ci13xxx_ep - endpoint representation
+ * @ep: endpoint structure for gadget drivers
+ * @dir: endpoint direction (TX/RX)
+ * @num: endpoint number
+ * @type: endpoint type
+ * @name: string description of the endpoint
+ * @qh: queue head for this endpoint
+ * @wedge: is the endpoint wedged
+ * @udc: pointer to the controller
+ * @lock: pointer to controller's spinlock
+ * @td_pool: pointer to controller's TD pool
+ */
+struct ci13xxx_ep {
+	struct usb_ep				ep;
+	u8					dir;
+	u8					num;
+	u8					type;
+	char					name[16];
+	struct {
+		struct list_head	queue;
+		struct ci13xxx_qh	*ptr;
+		dma_addr_t		dma;
+	}					qh;
+	int					wedge;
+
+	/* global resources */
+	struct ci13xxx				*udc;
+	spinlock_t				*lock;
+	struct dma_pool				*td_pool;
+};
+
+enum ci_role {
+	CI_ROLE_HOST = 0,
+	CI_ROLE_GADGET,
+	CI_ROLE_END,
+};
+
+/**
+ * struct ci_role_driver - host/gadget role driver
+ * start: start this role
+ * stop: stop this role
+ * irq: irq handler for this role
+ * name: role name string (host/gadget)
+ */
+struct ci_role_driver {
+	int		(*start)(struct ci13xxx *);
+	void		(*stop)(struct ci13xxx *);
+	irqreturn_t	(*irq)(struct ci13xxx *);
+	const char	*name;
+};
+
+/**
+ * struct hw_bank - hardware register mapping representation
+ * @lpm: set if the device is LPM capable
+ * @phys: physical address of the controller's registers
+ * @abs: absolute address of the beginning of register window
+ * @cap: capability registers
+ * @op: operational registers
+ * @size: size of the register window
+ * @regmap: register lookup table
+ */
+struct hw_bank {
+	unsigned	lpm;
+	resource_size_t	phys;
+	void __iomem	*abs;
+	void __iomem	*cap;
+	void __iomem	*op;
+	size_t		size;
+	void __iomem	**regmap;
+};
+
+/**
+ * struct ci13xxx - chipidea device representation
+ * @dev: pointer to parent device
+ * @lock: access synchronization
+ * @hw_bank: hardware register mapping
+ * @irq: IRQ number
+ * @roles: array of supported roles for this controller
+ * @role: current role
+ * @is_otg: if the device is otg-capable
+ * @work: work for role changing
+ * @wq: workqueue thread
+ * @qh_pool: allocation pool for queue heads
+ * @td_pool: allocation pool for transfer descriptors
+ * @gadget: device side representation for peripheral controller
+ * @driver: gadget driver
+ * @hw_ep_max: total number of endpoints supported by hardware
+ * @ci13xxx_ep: array of endpoints
+ * @ep0_dir: ep0 direction
+ * @ep0out: pointer to ep0 OUT endpoint
+ * @ep0in: pointer to ep0 IN endpoint
+ * @status: ep0 status request
+ * @setaddr: if we should set the address on status completion
+ * @address: usb address received from the host
+ * @remote_wakeup: host-enabled remote wakeup
+ * @suspended: suspended by host
+ * @test_mode: the selected test mode
+ * @udc_driver: platform specific information supplied by parent device
+ * @vbus_active: is VBUS active
+ * @transceiver: pointer to USB PHY, if any
+ * @hcd: pointer to usb_hcd for ehci host driver
+ */
+struct ci13xxx {
+	struct device			*dev;
+	spinlock_t			lock;
+	struct hw_bank			hw_bank;
+	int				irq;
+	struct ci_role_driver		*roles[CI_ROLE_END];
+	enum ci_role			role;
+	bool				is_otg;
+	struct work_struct		work;
+	struct workqueue_struct		*wq;
+
+	struct dma_pool			*qh_pool;
+	struct dma_pool			*td_pool;
+
+	struct usb_gadget		gadget;
+	struct usb_gadget_driver	*driver;
+	unsigned			hw_ep_max;
+	struct ci13xxx_ep		ci13xxx_ep[ENDPT_MAX];
+	u32				ep0_dir;
+	struct ci13xxx_ep		*ep0out, *ep0in;
+
+	struct usb_request		*status;
+	bool				setaddr;
+	u8				address;
+	u8				remote_wakeup;
+	u8				suspended;
+	u8				test_mode;
+
+	struct ci13xxx_udc_driver	*udc_driver;
+	int				vbus_active;
+	struct usb_phy			*transceiver;
+	struct usb_hcd			*hcd;
+};
+
+static inline struct ci_role_driver *ci_role(struct ci13xxx *ci)
+{
+	BUG_ON(ci->role >= CI_ROLE_END || !ci->roles[ci->role]);
+	return ci->roles[ci->role];
+}
+
+static inline int ci_role_start(struct ci13xxx *ci, enum ci_role role)
+{
+	int ret;
+
+	if (role >= CI_ROLE_END)
+		return -EINVAL;
+
+	if (!ci->roles[role])
+		return -ENXIO;
+
+	ret = ci->roles[role]->start(ci);
+	if (!ret)
+		ci->role = role;
+	return ret;
+}
+
+static inline void ci_role_stop(struct ci13xxx *ci)
+{
+	enum ci_role role = ci->role;
+
+	if (role == CI_ROLE_END)
+		return;
+
+	ci->role = CI_ROLE_END;
+
+	ci->roles[role]->stop(ci);
+}
+
+/******************************************************************************
+ * REGISTERS
+ *****************************************************************************/
+/* register size */
+#define REG_BITS   (32)
+
+/* register indices */
+enum ci13xxx_regs {
+	CAP_CAPLENGTH,
+	CAP_HCCPARAMS,
+	CAP_DCCPARAMS,
+	CAP_TESTMODE,
+	CAP_LAST = CAP_TESTMODE,
+	OP_USBCMD,
+	OP_USBSTS,
+	OP_USBINTR,
+	OP_DEVICEADDR,
+	OP_ENDPTLISTADDR,
+	OP_PORTSC,
+	OP_DEVLC,
+	OP_OTGSC,
+	OP_USBMODE,
+	OP_ENDPTSETUPSTAT,
+	OP_ENDPTPRIME,
+	OP_ENDPTFLUSH,
+	OP_ENDPTSTAT,
+	OP_ENDPTCOMPLETE,
+	OP_ENDPTCTRL,
+	/* endptctrl1..15 follow */
+	OP_LAST = OP_ENDPTCTRL + ENDPT_MAX / 2,
+};
+
+/**
+ * ffs_nr: find first (least significant) bit set
+ * @x: the word to search
+ *
+ * This function returns bit number (instead of position)
+ */
+static inline int ffs_nr(u32 x)
+{
+	int n = ffs(x);
+
+	return n ? n-1 : 32;
+}
+
+/**
+ * hw_read: reads from a hw register
+ * @reg:  register index
+ * @mask: bitfield mask
+ *
+ * This function returns register contents
+ */
+static inline u32 hw_read(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask)
+{
+	return ioread32(udc->hw_bank.regmap[reg]) & mask;
+}
+
+/**
+ * hw_write: writes to a hw register
+ * @reg:  register index
+ * @mask: bitfield mask
+ * @data: new value
+ */
+static inline void hw_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
+			    u32 mask, u32 data)
+{
+	if (~mask)
+		data = (ioread32(udc->hw_bank.regmap[reg]) & ~mask)
+			| (data & mask);
+
+	iowrite32(data, udc->hw_bank.regmap[reg]);
+}
+
+/**
+ * hw_test_and_clear: tests & clears a hw register
+ * @reg:  register index
+ * @mask: bitfield mask
+ *
+ * This function returns register contents
+ */
+static inline u32 hw_test_and_clear(struct ci13xxx *udc, enum ci13xxx_regs reg,
+				    u32 mask)
+{
+	u32 val = ioread32(udc->hw_bank.regmap[reg]) & mask;
+
+	iowrite32(val, udc->hw_bank.regmap[reg]);
+	return val;
+}
+
+/**
+ * hw_test_and_write: tests & writes a hw register
+ * @reg:  register index
+ * @mask: bitfield mask
+ * @data: new value
+ *
+ * This function returns register contents
+ */
+static inline u32 hw_test_and_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
+				    u32 mask, u32 data)
+{
+	u32 val = hw_read(udc, reg, ~0);
+
+	hw_write(udc, reg, mask, data);
+	return (val & mask) >> ffs_nr(mask);
+}
+
+int hw_device_reset(struct ci13xxx *ci, u32 mode);
+
+int hw_port_test_set(struct ci13xxx *ci, u8 mode);
+
+u8 hw_port_test_get(struct ci13xxx *ci);
+
+#endif	/* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/chipidea/ci13xxx_msm.c
similarity index 69%
rename from drivers/usb/gadget/ci13xxx_msm.c
rename to drivers/usb/chipidea/ci13xxx_msm.c
index d07e44c..958069e 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/chipidea/ci13xxx_msm.c
@@ -10,15 +10,12 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/msm_hsusb_hw.h>
 #include <linux/usb/ulpi.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/chipidea.h>
 
-#include "ci13xxx_udc.c"
+#include "ci.h"
 
-#define MSM_USB_BASE	(udc->regs)
-
-static irqreturn_t msm_udc_irq(int irq, void *data)
-{
-	return udc_irq();
-}
+#define MSM_USB_BASE	(udc->hw_bank.abs)
 
 static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event)
 {
@@ -60,53 +57,40 @@
 
 static int ci13xxx_msm_probe(struct platform_device *pdev)
 {
-	struct resource *res;
-	void __iomem *regs;
-	int irq;
+	struct platform_device *plat_ci;
 	int ret;
 
 	dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n");
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to get platform resource mem\n");
-		return -ENXIO;
-	}
-
-	regs = ioremap(res->start, resource_size(res));
-	if (!regs) {
-		dev_err(&pdev->dev, "ioremap failed\n");
+	plat_ci = platform_device_alloc("ci_hdrc", -1);
+	if (!plat_ci) {
+		dev_err(&pdev->dev, "can't allocate ci_hdrc platform device\n");
 		return -ENOMEM;
 	}
 
-	ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "udc_probe failed\n");
-		goto iounmap;
+	ret = platform_device_add_resources(plat_ci, pdev->resource,
+					    pdev->num_resources);
+	if (ret) {
+		dev_err(&pdev->dev, "can't add resources to platform device\n");
+		goto put_platform;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "IRQ not found\n");
-		ret = -ENXIO;
-		goto udc_remove;
-	}
+	ret = platform_device_add_data(plat_ci, &ci13xxx_msm_udc_driver,
+				       sizeof(ci13xxx_msm_udc_driver));
+	if (ret)
+		goto put_platform;
 
-	ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "request_irq failed\n");
-		goto udc_remove;
-	}
+	ret = platform_device_add(plat_ci);
+	if (ret)
+		goto put_platform;
 
 	pm_runtime_no_callbacks(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
 	return 0;
 
-udc_remove:
-	udc_remove();
-iounmap:
-	iounmap(regs);
+put_platform:
+	platform_device_put(plat_ci);
 
 	return ret;
 }
diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c
new file mode 100644
index 0000000..e3dab27
--- /dev/null
+++ b/drivers/usb/chipidea/ci13xxx_pci.c
@@ -0,0 +1,180 @@
+/*
+ * ci13xxx_pci.c - MIPS USB IP core family device controller
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/chipidea.h>
+
+/* driver name */
+#define UDC_DRIVER_NAME   "ci13xxx_pci"
+
+/******************************************************************************
+ * PCI block
+ *****************************************************************************/
+struct ci13xxx_udc_driver pci_driver = {
+	.name		= UDC_DRIVER_NAME,
+	.capoffset	= DEF_CAPOFFSET,
+};
+
+struct ci13xxx_udc_driver langwell_pci_driver = {
+	.name		= UDC_DRIVER_NAME,
+	.capoffset	= 0,
+};
+
+struct ci13xxx_udc_driver penwell_pci_driver = {
+	.name		= UDC_DRIVER_NAME,
+	.capoffset	= 0,
+	.power_budget	= 200,
+};
+
+/**
+ * ci13xxx_pci_probe: PCI probe
+ * @pdev: USB device controller being probed
+ * @id:   PCI hotplug ID connecting controller to UDC framework
+ *
+ * This function returns an error code
+ * Allocates basic PCI resources for this USB device controller, and then
+ * invokes the udc_probe() method to start the UDC associated with it
+ */
+static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
+				       const struct pci_device_id *id)
+{
+	struct ci13xxx_udc_driver *driver = (void *)id->driver_data;
+	struct platform_device *plat_ci;
+	struct resource res[3];
+	int retval = 0, nres = 2;
+
+	if (!driver) {
+		dev_err(&pdev->dev, "device doesn't provide driver data\n");
+		return -ENODEV;
+	}
+
+	retval = pci_enable_device(pdev);
+	if (retval)
+		goto done;
+
+	if (!pdev->irq) {
+		dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!");
+		retval = -ENODEV;
+		goto disable_device;
+	}
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	plat_ci = platform_device_alloc("ci_hdrc", -1);
+	if (!plat_ci) {
+		dev_err(&pdev->dev, "can't allocate ci_hdrc platform device\n");
+		retval = -ENOMEM;
+		goto disable_device;
+	}
+
+	memset(res, 0, sizeof(res));
+	res[0].start	= pci_resource_start(pdev, 0);
+	res[0].end	= pci_resource_end(pdev, 0);
+	res[0].flags	= IORESOURCE_MEM;
+	res[1].start	= pdev->irq;
+	res[1].flags	= IORESOURCE_IRQ;
+
+	retval = platform_device_add_resources(plat_ci, res, nres);
+	if (retval) {
+		dev_err(&pdev->dev, "can't add resources to platform device\n");
+		goto put_platform;
+	}
+
+	retval = platform_device_add_data(plat_ci, driver, sizeof(*driver));
+	if (retval)
+		goto put_platform;
+
+	dma_set_coherent_mask(&plat_ci->dev, pdev->dev.coherent_dma_mask);
+	plat_ci->dev.dma_mask = pdev->dev.dma_mask;
+	plat_ci->dev.dma_parms = pdev->dev.dma_parms;
+	plat_ci->dev.parent = &pdev->dev;
+
+	pci_set_drvdata(pdev, plat_ci);
+
+	retval = platform_device_add(plat_ci);
+	if (retval)
+		goto put_platform;
+
+	return 0;
+
+ put_platform:
+	pci_set_drvdata(pdev, NULL);
+	platform_device_put(plat_ci);
+ disable_device:
+	pci_disable_device(pdev);
+ done:
+	return retval;
+}
+
+/**
+ * ci13xxx_pci_remove: PCI remove
+ * @pdev: USB Device Controller being removed
+ *
+ * Reverses the effect of ci13xxx_pci_probe(),
+ * first invoking the udc_remove() and then releases
+ * all PCI resources allocated for this USB device controller
+ */
+static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
+{
+	struct platform_device *plat_ci = pci_get_drvdata(pdev);
+
+	platform_device_unregister(plat_ci);
+	pci_set_drvdata(pdev, NULL);
+	pci_disable_device(pdev);
+}
+
+/**
+ * PCI device table
+ * PCI device structure
+ *
+ * Check "pci.h" for details
+ */
+static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = {
+	{
+		PCI_DEVICE(0x153F, 0x1004),
+		.driver_data = (kernel_ulong_t)&pci_driver,
+	},
+	{
+		PCI_DEVICE(0x153F, 0x1006),
+		.driver_data = (kernel_ulong_t)&pci_driver,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811),
+		.driver_data = (kernel_ulong_t)&langwell_pci_driver,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829),
+		.driver_data = (kernel_ulong_t)&penwell_pci_driver,
+	},
+	{ 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table);
+
+static struct pci_driver ci13xxx_pci_driver = {
+	.name         =	UDC_DRIVER_NAME,
+	.id_table     =	ci13xxx_pci_id_table,
+	.probe        =	ci13xxx_pci_probe,
+	.remove       =	__devexit_p(ci13xxx_pci_remove),
+};
+
+module_pci_driver(ci13xxx_pci_driver);
+
+MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
+MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("June 2008");
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
new file mode 100644
index 0000000..15e03b3
--- /dev/null
+++ b/drivers/usb/chipidea/core.c
@@ -0,0 +1,474 @@
+/*
+ * core.c - ChipIdea USB IP core family device controller
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Description: ChipIdea USB IP core family device controller
+ *
+ * This driver is composed of several blocks:
+ * - HW:     hardware interface
+ * - DBG:    debug facilities (optional)
+ * - UTIL:   utilities
+ * - ISR:    interrupts handling
+ * - ENDPT:  endpoint operations (Gadget API)
+ * - GADGET: gadget operations (Gadget API)
+ * - BUS:    bus glue code, bus abstraction layer
+ *
+ * Compile Options
+ * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities
+ * - STALL_IN:  non-empty bulk-in pipes cannot be halted
+ *              if defined mass storage compliance succeeds but with warnings
+ *              => case 4: Hi >  Dn
+ *              => case 5: Hi >  Di
+ *              => case 8: Hi <> Do
+ *              if undefined usbtest 13 fails
+ * - TRACE:     enable function tracing (depends on DEBUG)
+ *
+ * Main Features
+ * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
+ * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
+ * - Normal & LPM support
+ *
+ * USBTEST Report
+ * - OK: 0-12, 13 (STALL_IN defined) & 14
+ * - Not Supported: 15 & 16 (ISO)
+ *
+ * TODO List
+ * - OTG
+ * - Isochronous & Interrupt Traffic
+ * - Handle requests which spawns into several TDs
+ * - GET_STATUS(device) - always reports 0
+ * - Gadget API (majority of optional features)
+ * - Suspend & Remote Wakeup
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/chipidea.h>
+
+#include "ci.h"
+#include "udc.h"
+#include "bits.h"
+#include "host.h"
+#include "debug.h"
+
+/* Controller register map */
+static uintptr_t ci_regs_nolpm[] = {
+	[CAP_CAPLENGTH]		= 0x000UL,
+	[CAP_HCCPARAMS]		= 0x008UL,
+	[CAP_DCCPARAMS]		= 0x024UL,
+	[CAP_TESTMODE]		= 0x038UL,
+	[OP_USBCMD]		= 0x000UL,
+	[OP_USBSTS]		= 0x004UL,
+	[OP_USBINTR]		= 0x008UL,
+	[OP_DEVICEADDR]		= 0x014UL,
+	[OP_ENDPTLISTADDR]	= 0x018UL,
+	[OP_PORTSC]		= 0x044UL,
+	[OP_DEVLC]		= 0x084UL,
+	[OP_OTGSC]		= 0x064UL,
+	[OP_USBMODE]		= 0x068UL,
+	[OP_ENDPTSETUPSTAT]	= 0x06CUL,
+	[OP_ENDPTPRIME]		= 0x070UL,
+	[OP_ENDPTFLUSH]		= 0x074UL,
+	[OP_ENDPTSTAT]		= 0x078UL,
+	[OP_ENDPTCOMPLETE]	= 0x07CUL,
+	[OP_ENDPTCTRL]		= 0x080UL,
+};
+
+static uintptr_t ci_regs_lpm[] = {
+	[CAP_CAPLENGTH]		= 0x000UL,
+	[CAP_HCCPARAMS]		= 0x008UL,
+	[CAP_DCCPARAMS]		= 0x024UL,
+	[CAP_TESTMODE]		= 0x0FCUL,
+	[OP_USBCMD]		= 0x000UL,
+	[OP_USBSTS]		= 0x004UL,
+	[OP_USBINTR]		= 0x008UL,
+	[OP_DEVICEADDR]		= 0x014UL,
+	[OP_ENDPTLISTADDR]	= 0x018UL,
+	[OP_PORTSC]		= 0x044UL,
+	[OP_DEVLC]		= 0x084UL,
+	[OP_OTGSC]		= 0x0C4UL,
+	[OP_USBMODE]		= 0x0C8UL,
+	[OP_ENDPTSETUPSTAT]	= 0x0D8UL,
+	[OP_ENDPTPRIME]		= 0x0DCUL,
+	[OP_ENDPTFLUSH]		= 0x0E0UL,
+	[OP_ENDPTSTAT]		= 0x0E4UL,
+	[OP_ENDPTCOMPLETE]	= 0x0E8UL,
+	[OP_ENDPTCTRL]		= 0x0ECUL,
+};
+
+static int hw_alloc_regmap(struct ci13xxx *ci, bool is_lpm)
+{
+	int i;
+
+	kfree(ci->hw_bank.regmap);
+
+	ci->hw_bank.regmap = kzalloc((OP_LAST + 1) * sizeof(void *),
+				     GFP_KERNEL);
+	if (!ci->hw_bank.regmap)
+		return -ENOMEM;
+
+	for (i = 0; i < OP_ENDPTCTRL; i++)
+		ci->hw_bank.regmap[i] =
+			(i <= CAP_LAST ? ci->hw_bank.cap : ci->hw_bank.op) +
+			(is_lpm ? ci_regs_lpm[i] : ci_regs_nolpm[i]);
+
+	for (; i <= OP_LAST; i++)
+		ci->hw_bank.regmap[i] = ci->hw_bank.op +
+			4 * (i - OP_ENDPTCTRL) +
+			(is_lpm
+			 ? ci_regs_lpm[OP_ENDPTCTRL]
+			 : ci_regs_nolpm[OP_ENDPTCTRL]);
+
+	return 0;
+}
+
+/**
+ * hw_port_test_set: writes port test mode (execute without interruption)
+ * @mode: new value
+ *
+ * This function returns an error code
+ */
+int hw_port_test_set(struct ci13xxx *ci, u8 mode)
+{
+	const u8 TEST_MODE_MAX = 7;
+
+	if (mode > TEST_MODE_MAX)
+		return -EINVAL;
+
+	hw_write(ci, OP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
+	return 0;
+}
+
+/**
+ * hw_port_test_get: reads port test mode value
+ *
+ * This function returns port test mode value
+ */
+u8 hw_port_test_get(struct ci13xxx *ci)
+{
+	return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
+}
+
+static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
+{
+	u32 reg;
+
+	/* bank is a module variable */
+	ci->hw_bank.abs = base;
+
+	ci->hw_bank.cap = ci->hw_bank.abs;
+	ci->hw_bank.cap += ci->udc_driver->capoffset;
+	ci->hw_bank.op = ci->hw_bank.cap + ioread8(ci->hw_bank.cap);
+
+	hw_alloc_regmap(ci, false);
+	reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) >>
+		ffs_nr(HCCPARAMS_LEN);
+	ci->hw_bank.lpm  = reg;
+	hw_alloc_regmap(ci, !!reg);
+	ci->hw_bank.size = ci->hw_bank.op - ci->hw_bank.abs;
+	ci->hw_bank.size += OP_LAST;
+	ci->hw_bank.size /= sizeof(u32);
+
+	reg = hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DEN) >>
+		ffs_nr(DCCPARAMS_DEN);
+	ci->hw_ep_max = reg * 2;   /* cache hw ENDPT_MAX */
+
+	if (ci->hw_ep_max > ENDPT_MAX)
+		return -ENODEV;
+
+	dev_dbg(ci->dev, "ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n",
+		ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);
+
+	/* setup lock mode ? */
+
+	/* ENDPTSETUPSTAT is '0' by default */
+
+	/* HCSPARAMS.bf.ppc SHOULD BE zero for device */
+
+	return 0;
+}
+
+/**
+ * hw_device_reset: resets chip (execute without interruption)
+ * @ci: the controller
+  *
+ * This function returns an error code
+ */
+int hw_device_reset(struct ci13xxx *ci, u32 mode)
+{
+	/* should flush & stop before reset */
+	hw_write(ci, OP_ENDPTFLUSH, ~0, ~0);
+	hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
+
+	hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST);
+	while (hw_read(ci, OP_USBCMD, USBCMD_RST))
+		udelay(10);		/* not RTOS friendly */
+
+
+	if (ci->udc_driver->notify_event)
+		ci->udc_driver->notify_event(ci,
+			CI13XXX_CONTROLLER_RESET_EVENT);
+
+	if (ci->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
+		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
+
+	/* USBMODE should be configured step by step */
+	hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
+	hw_write(ci, OP_USBMODE, USBMODE_CM, mode);
+	/* HW >= 2.3 */
+	hw_write(ci, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);
+
+	if (hw_read(ci, OP_USBMODE, USBMODE_CM) != mode) {
+		pr_err("cannot enter in %s mode", ci_role(ci)->name);
+		pr_err("lpm = %i", ci->hw_bank.lpm);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/**
+ * ci_otg_role - pick role based on ID pin state
+ * @ci: the controller
+ */
+static enum ci_role ci_otg_role(struct ci13xxx *ci)
+{
+	u32 sts = hw_read(ci, OP_OTGSC, ~0);
+	enum ci_role role = sts & OTGSC_ID
+		? CI_ROLE_GADGET
+		: CI_ROLE_HOST;
+
+	return role;
+}
+
+/**
+ * ci_role_work - perform role changing based on ID pin
+ * @work: work struct
+ */
+static void ci_role_work(struct work_struct *work)
+{
+	struct ci13xxx *ci = container_of(work, struct ci13xxx, work);
+	enum ci_role role = ci_otg_role(ci);
+
+	hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS);
+
+	if (role != ci->role) {
+		dev_dbg(ci->dev, "switching from %s to %s\n",
+			ci_role(ci)->name, ci->roles[role]->name);
+
+		ci_role_stop(ci);
+		ci_role_start(ci, role);
+	}
+}
+
+static ssize_t show_role(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct ci13xxx *ci = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", ci_role(ci)->name);
+}
+
+static ssize_t store_role(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct ci13xxx *ci = dev_get_drvdata(dev);
+	enum ci_role role;
+	int ret;
+
+	for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++)
+		if (ci->roles[role] && !strcmp(buf, ci->roles[role]->name))
+			break;
+
+	if (role == CI_ROLE_END || role == ci->role)
+		return -EINVAL;
+
+	ci_role_stop(ci);
+	ret = ci_role_start(ci, role);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(role, S_IRUSR | S_IWUSR, show_role, store_role);
+
+static irqreturn_t ci_irq(int irq, void *data)
+{
+	struct ci13xxx *ci = data;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (ci->is_otg) {
+		u32 sts = hw_read(ci, OP_OTGSC, ~0);
+
+		if (sts & OTGSC_IDIS) {
+			queue_work(ci->wq, &ci->work);
+			ret = IRQ_HANDLED;
+		}
+	}
+
+	return ci->role == CI_ROLE_END ? ret : ci_role(ci)->irq(ci);
+}
+
+static int __devinit ci_hdrc_probe(struct platform_device *pdev)
+{
+	struct device	*dev = &pdev->dev;
+	struct ci13xxx	*ci;
+	struct resource	*res;
+	void __iomem	*base;
+	int		ret;
+
+	if (!dev->platform_data) {
+		dev_err(dev, "platform data missing\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "missing resource\n");
+		return -ENODEV;
+	}
+
+	base = devm_request_and_ioremap(dev, res);
+	if (!res) {
+		dev_err(dev, "can't request and ioremap resource\n");
+		return -ENOMEM;
+	}
+
+	ci = devm_kzalloc(dev, sizeof(*ci), GFP_KERNEL);
+	if (!ci) {
+		dev_err(dev, "can't allocate device\n");
+		return -ENOMEM;
+	}
+
+	ci->dev = dev;
+	ci->udc_driver = dev->platform_data;
+
+	ret = hw_device_init(ci, base);
+	if (ret < 0) {
+		dev_err(dev, "can't initialize hardware\n");
+		return -ENODEV;
+	}
+
+	ci->hw_bank.phys = res->start;
+
+	ci->irq = platform_get_irq(pdev, 0);
+	if (ci->irq < 0) {
+		dev_err(dev, "missing IRQ\n");
+		return -ENODEV;
+	}
+
+	INIT_WORK(&ci->work, ci_role_work);
+	ci->wq = create_singlethread_workqueue("ci_otg");
+	if (!ci->wq) {
+		dev_err(dev, "can't create workqueue\n");
+		return -ENODEV;
+	}
+
+	/* initialize role(s) before the interrupt is requested */
+	ret = ci_hdrc_host_init(ci);
+	if (ret)
+		dev_info(dev, "doesn't support host\n");
+
+	ret = ci_hdrc_gadget_init(ci);
+	if (ret)
+		dev_info(dev, "doesn't support gadget\n");
+
+	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
+		dev_err(dev, "no supported roles\n");
+		ret = -ENODEV;
+		goto rm_wq;
+	}
+
+	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
+		ci->is_otg = true;
+		ci->role = ci_otg_role(ci);
+	} else {
+		ci->role = ci->roles[CI_ROLE_HOST]
+			? CI_ROLE_HOST
+			: CI_ROLE_GADGET;
+	}
+
+	ret = ci_role_start(ci, ci->role);
+	if (ret) {
+		dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
+		ret = -ENODEV;
+		goto rm_wq;
+	}
+
+	platform_set_drvdata(pdev, ci);
+	ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->udc_driver->name,
+			  ci);
+	if (ret)
+		goto stop;
+
+	ret = device_create_file(dev, &dev_attr_role);
+	if (ret)
+		goto rm_attr;
+
+	if (ci->is_otg)
+		hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);
+
+	return ret;
+
+rm_attr:
+	device_remove_file(dev, &dev_attr_role);
+stop:
+	ci_role_stop(ci);
+rm_wq:
+	flush_workqueue(ci->wq);
+	destroy_workqueue(ci->wq);
+
+	return ret;
+}
+
+static int __devexit ci_hdrc_remove(struct platform_device *pdev)
+{
+	struct ci13xxx *ci = platform_get_drvdata(pdev);
+
+	flush_workqueue(ci->wq);
+	destroy_workqueue(ci->wq);
+	device_remove_file(ci->dev, &dev_attr_role);
+	free_irq(ci->irq, ci);
+	ci_role_stop(ci);
+
+	return 0;
+}
+
+static struct platform_driver ci_hdrc_driver = {
+	.probe	= ci_hdrc_probe,
+	.remove	= __devexit_p(ci_hdrc_remove),
+	.driver	= {
+		.name	= "ci_hdrc",
+	},
+};
+
+module_platform_driver(ci_hdrc_driver);
+
+MODULE_ALIAS("platform:ci_hdrc");
+MODULE_ALIAS("platform:ci13xxx");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("David Lopo <dlopo@chipidea.mips.com>");
+MODULE_DESCRIPTION("ChipIdea HDRC Driver");
diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c
new file mode 100644
index 0000000..c4b3e15
--- /dev/null
+++ b/drivers/usb/chipidea/debug.c
@@ -0,0 +1,804 @@
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/chipidea.h>
+
+#include "ci.h"
+#include "udc.h"
+#include "bits.h"
+#include "debug.h"
+
+/* Interrupt statistics */
+#define ISR_MASK   0x1F
+static struct isr_statistics {
+	u32 test;
+	u32 ui;
+	u32 uei;
+	u32 pci;
+	u32 uri;
+	u32 sli;
+	u32 none;
+	struct {
+		u32 cnt;
+		u32 buf[ISR_MASK+1];
+		u32 idx;
+	} hndl;
+} isr_statistics;
+
+void dbg_interrupt(u32 intmask)
+{
+	if (!intmask) {
+		isr_statistics.none++;
+		return;
+	}
+
+	isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intmask;
+	isr_statistics.hndl.idx &= ISR_MASK;
+	isr_statistics.hndl.cnt++;
+
+	if (USBi_URI & intmask)
+		isr_statistics.uri++;
+	if (USBi_PCI & intmask)
+		isr_statistics.pci++;
+	if (USBi_UEI & intmask)
+		isr_statistics.uei++;
+	if (USBi_UI  & intmask)
+		isr_statistics.ui++;
+	if (USBi_SLI & intmask)
+		isr_statistics.sli++;
+}
+
+/**
+ * hw_register_read: reads all device registers (execute without interruption)
+ * @buf:  destination buffer
+ * @size: buffer size
+ *
+ * This function returns number of registers read
+ */
+static size_t hw_register_read(struct ci13xxx *udc, u32 *buf, size_t size)
+{
+	unsigned i;
+
+	if (size > udc->hw_bank.size)
+		size = udc->hw_bank.size;
+
+	for (i = 0; i < size; i++)
+		buf[i] = hw_read(udc, i * sizeof(u32), ~0);
+
+	return size;
+}
+
+/**
+ * hw_register_write: writes to register
+ * @addr: register address
+ * @data: register value
+ *
+ * This function returns an error code
+ */
+static int hw_register_write(struct ci13xxx *udc, u16 addr, u32 data)
+{
+	/* align */
+	addr /= sizeof(u32);
+
+	if (addr >= udc->hw_bank.size)
+		return -EINVAL;
+
+	/* align */
+	addr *= sizeof(u32);
+
+	hw_write(udc, addr, ~0, data);
+	return 0;
+}
+
+/**
+ * hw_intr_clear: disables interrupt & clears interrupt status (execute without
+ *                interruption)
+ * @n: interrupt bit
+ *
+ * This function returns an error code
+ */
+static int hw_intr_clear(struct ci13xxx *udc, int n)
+{
+	if (n >= REG_BITS)
+		return -EINVAL;
+
+	hw_write(udc, OP_USBINTR, BIT(n), 0);
+	hw_write(udc, OP_USBSTS,  BIT(n), BIT(n));
+	return 0;
+}
+
+/**
+ * hw_intr_force: enables interrupt & forces interrupt status (execute without
+ *                interruption)
+ * @n: interrupt bit
+ *
+ * This function returns an error code
+ */
+static int hw_intr_force(struct ci13xxx *udc, int n)
+{
+	if (n >= REG_BITS)
+		return -EINVAL;
+
+	hw_write(udc, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
+	hw_write(udc, OP_USBINTR,  BIT(n), BIT(n));
+	hw_write(udc, OP_USBSTS,   BIT(n), BIT(n));
+	hw_write(udc, CAP_TESTMODE, TESTMODE_FORCE, 0);
+	return 0;
+}
+
+/**
+ * show_device: prints information about device capabilities and status
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_device(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	struct usb_gadget *gadget = &udc->gadget;
+	int n = 0;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	n += scnprintf(buf + n, PAGE_SIZE - n, "speed             = %d\n",
+		       gadget->speed);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed         = %d\n",
+		       gadget->max_speed);
+	/* TODO: Scheduled for removal in 3.8. */
+	n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed      = %d\n",
+		       gadget_is_dualspeed(gadget));
+	n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg            = %d\n",
+		       gadget->is_otg);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral   = %d\n",
+		       gadget->is_a_peripheral);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable      = %d\n",
+		       gadget->b_hnp_enable);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support     = %d\n",
+		       gadget->a_hnp_support);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
+		       gadget->a_alt_hnp_support);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "name              = %s\n",
+		       (gadget->name ? gadget->name : ""));
+
+	return n;
+}
+static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
+
+/**
+ * show_driver: prints information about attached gadget (if any)
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	struct usb_gadget_driver *driver = udc->driver;
+	int n = 0;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(dev, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	if (driver == NULL)
+		return scnprintf(buf, PAGE_SIZE,
+				 "There is no gadget attached!\n");
+
+	n += scnprintf(buf + n, PAGE_SIZE - n, "function  = %s\n",
+		       (driver->function ? driver->function : ""));
+	n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
+		       driver->max_speed);
+
+	return n;
+}
+static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
+
+/* Maximum event message length */
+#define DBG_DATA_MSG   64UL
+
+/* Maximum event messages */
+#define DBG_DATA_MAX   128UL
+
+/* Event buffer descriptor */
+static struct {
+	char     (buf[DBG_DATA_MAX])[DBG_DATA_MSG];   /* buffer */
+	unsigned idx;   /* index */
+	unsigned tty;   /* print to console? */
+	rwlock_t lck;   /* lock */
+} dbg_data = {
+	.idx = 0,
+	.tty = 0,
+	.lck = __RW_LOCK_UNLOCKED(lck)
+};
+
+/**
+ * dbg_dec: decrements debug event index
+ * @idx: buffer index
+ */
+static void dbg_dec(unsigned *idx)
+{
+	*idx = (*idx - 1) & (DBG_DATA_MAX-1);
+}
+
+/**
+ * dbg_inc: increments debug event index
+ * @idx: buffer index
+ */
+static void dbg_inc(unsigned *idx)
+{
+	*idx = (*idx + 1) & (DBG_DATA_MAX-1);
+}
+
+/**
+ * dbg_print:  prints the common part of the event
+ * @addr:   endpoint address
+ * @name:   event name
+ * @status: status
+ * @extra:  extra information
+ */
+static void dbg_print(u8 addr, const char *name, int status, const char *extra)
+{
+	struct timeval tval;
+	unsigned int stamp;
+	unsigned long flags;
+
+	write_lock_irqsave(&dbg_data.lck, flags);
+
+	do_gettimeofday(&tval);
+	stamp = tval.tv_sec & 0xFFFF;	/* 2^32 = 4294967296. Limit to 4096s */
+	stamp = stamp * 1000000 + tval.tv_usec;
+
+	scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
+		  "%04X\t? %02X %-7.7s %4i ?\t%s\n",
+		  stamp, addr, name, status, extra);
+
+	dbg_inc(&dbg_data.idx);
+
+	write_unlock_irqrestore(&dbg_data.lck, flags);
+
+	if (dbg_data.tty != 0)
+		pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
+			  stamp, addr, name, status, extra);
+}
+
+/**
+ * dbg_done: prints a DONE event
+ * @addr:   endpoint address
+ * @td:     transfer descriptor
+ * @status: status
+ */
+void dbg_done(u8 addr, const u32 token, int status)
+{
+	char msg[DBG_DATA_MSG];
+
+	scnprintf(msg, sizeof(msg), "%d %02X",
+		  (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
+		  (int)(token & TD_STATUS)      >> ffs_nr(TD_STATUS));
+	dbg_print(addr, "DONE", status, msg);
+}
+
+/**
+ * dbg_event: prints a generic event
+ * @addr:   endpoint address
+ * @name:   event name
+ * @status: status
+ */
+void dbg_event(u8 addr, const char *name, int status)
+{
+	if (name != NULL)
+		dbg_print(addr, name, status, "");
+}
+
+/*
+ * dbg_queue: prints a QUEUE event
+ * @addr:   endpoint address
+ * @req:    USB request
+ * @status: status
+ */
+void dbg_queue(u8 addr, const struct usb_request *req, int status)
+{
+	char msg[DBG_DATA_MSG];
+
+	if (req != NULL) {
+		scnprintf(msg, sizeof(msg),
+			  "%d %d", !req->no_interrupt, req->length);
+		dbg_print(addr, "QUEUE", status, msg);
+	}
+}
+
+/**
+ * dbg_setup: prints a SETUP event
+ * @addr: endpoint address
+ * @req:  setup request
+ */
+void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
+{
+	char msg[DBG_DATA_MSG];
+
+	if (req != NULL) {
+		scnprintf(msg, sizeof(msg),
+			  "%02X %02X %04X %04X %d", req->bRequestType,
+			  req->bRequest, le16_to_cpu(req->wValue),
+			  le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
+		dbg_print(addr, "SETUP", 0, msg);
+	}
+}
+
+/**
+ * show_events: displays the event buffer
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_events(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	unsigned long flags;
+	unsigned i, j, n = 0;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(dev->parent, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	read_lock_irqsave(&dbg_data.lck, flags);
+
+	i = dbg_data.idx;
+	for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
+		n += strlen(dbg_data.buf[i]);
+		if (n >= PAGE_SIZE) {
+			n -= strlen(dbg_data.buf[i]);
+			break;
+		}
+	}
+	for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
+		j += scnprintf(buf + j, PAGE_SIZE - j,
+			       "%s", dbg_data.buf[i]);
+
+	read_unlock_irqrestore(&dbg_data.lck, flags);
+
+	return n;
+}
+
+/**
+ * store_events: configure if events are going to be also printed to console
+ *
+ * Check "device.h" for details
+ */
+static ssize_t store_events(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned tty;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(dev, "[%s] EINVAL\n", __func__);
+		goto done;
+	}
+
+	if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
+		dev_err(dev, "<1|0>: enable|disable console log\n");
+		goto done;
+	}
+
+	dbg_data.tty = tty;
+	dev_info(dev, "tty = %u", dbg_data.tty);
+
+ done:
+	return count;
+}
+static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
+
+/**
+ * show_inters: interrupt status, enable status and historic
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	u32 intr;
+	unsigned i, j, n = 0;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/*n += scnprintf(buf + n, PAGE_SIZE - n,
+		       "status = %08x\n", hw_read_intr_status(udc));
+	n += scnprintf(buf + n, PAGE_SIZE - n,
+	"enable = %08x\n", hw_read_intr_enable(udc));*/
+
+	n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
+		       isr_statistics.test);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "? ui  = %d\n",
+		       isr_statistics.ui);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
+		       isr_statistics.uei);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
+		       isr_statistics.pci);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
+		       isr_statistics.uri);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
+		       isr_statistics.sli);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
+		       isr_statistics.none);
+	n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
+		       isr_statistics.hndl.cnt);
+
+	for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
+		i   &= ISR_MASK;
+		intr = isr_statistics.hndl.buf[i];
+
+		if (USBi_UI  & intr)
+			n += scnprintf(buf + n, PAGE_SIZE - n, "ui  ");
+		intr &= ~USBi_UI;
+		if (USBi_UEI & intr)
+			n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
+		intr &= ~USBi_UEI;
+		if (USBi_PCI & intr)
+			n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
+		intr &= ~USBi_PCI;
+		if (USBi_URI & intr)
+			n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
+		intr &= ~USBi_URI;
+		if (USBi_SLI & intr)
+			n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
+		intr &= ~USBi_SLI;
+		if (intr)
+			n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
+		if (isr_statistics.hndl.buf[i])
+			n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return n;
+}
+
+/**
+ * store_inters: enable & force or disable an individual interrutps
+ *                   (to be used for test purposes only)
+ *
+ * Check "device.h" for details
+ */
+static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	unsigned en, bit;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "EINVAL\n");
+		goto done;
+	}
+
+	if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
+		dev_err(udc->dev, "<1|0> <bit>: enable|disable interrupt\n");
+		goto done;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (en) {
+		if (hw_intr_force(udc, bit))
+			dev_err(dev, "invalid bit number\n");
+		else
+			isr_statistics.test++;
+	} else {
+		if (hw_intr_clear(udc, bit))
+			dev_err(dev, "invalid bit number\n");
+	}
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+ done:
+	return count;
+}
+static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
+
+/**
+ * show_port_test: reads port test mode
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_port_test(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	unsigned mode;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "EINVAL\n");
+		return 0;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	mode = hw_port_test_get(udc);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
+}
+
+/**
+ * store_port_test: writes port test mode
+ *
+ * Check "device.h" for details
+ */
+static ssize_t store_port_test(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	unsigned mode;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		goto done;
+	}
+
+	if (sscanf(buf, "%u", &mode) != 1) {
+		dev_err(udc->dev, "<mode>: set port test mode");
+		goto done;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (hw_port_test_set(udc, mode))
+		dev_err(udc->dev, "invalid mode\n");
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+ done:
+	return count;
+}
+static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
+		   show_port_test, store_port_test);
+
+/**
+ * show_qheads: DMA contents of all queue heads
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	unsigned i, j, n = 0;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	for (i = 0; i < udc->hw_ep_max/2; i++) {
+		struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
+		struct ci13xxx_ep *mEpTx =
+			&udc->ci13xxx_ep[i + udc->hw_ep_max/2];
+		n += scnprintf(buf + n, PAGE_SIZE - n,
+			       "EP=%02i: RX=%08X TX=%08X\n",
+			       i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
+		for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
+			n += scnprintf(buf + n, PAGE_SIZE - n,
+				       " %04X:    %08X    %08X\n", j,
+				       *((u32 *)mEpRx->qh.ptr + j),
+				       *((u32 *)mEpTx->qh.ptr + j));
+		}
+	}
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return n;
+}
+static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
+
+/**
+ * show_registers: dumps all registers
+ *
+ * Check "device.h" for details
+ */
+#define DUMP_ENTRIES	512
+static ssize_t show_registers(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	u32 *dump;
+	unsigned i, k, n = 0;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
+	if (!dump) {
+		dev_err(udc->dev, "%s: out of memory\n", __func__);
+		return 0;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	k = hw_register_read(udc, dump, DUMP_ENTRIES);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	for (i = 0; i < k; i++) {
+		n += scnprintf(buf + n, PAGE_SIZE - n,
+			       "reg[0x%04X] = 0x%08X\n",
+			       i * (unsigned)sizeof(u32), dump[i]);
+	}
+	kfree(dump);
+
+	return n;
+}
+
+/**
+ * store_registers: writes value to register address
+ *
+ * Check "device.h" for details
+ */
+static ssize_t store_registers(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long addr, data, flags;
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		goto done;
+	}
+
+	if (sscanf(buf, "%li %li", &addr, &data) != 2) {
+		dev_err(udc->dev,
+			"<addr> <data>: write data to register address\n");
+		goto done;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (hw_register_write(udc, addr, data))
+		dev_err(udc->dev, "invalid address range\n");
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+ done:
+	return count;
+}
+static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
+		   show_registers, store_registers);
+
+/**
+ * show_requests: DMA contents of all requests currently queued (all endpts)
+ *
+ * Check "device.h" for details
+ */
+static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
+	unsigned long flags;
+	struct list_head   *ptr = NULL;
+	struct ci13xxx_req *req = NULL;
+	unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
+
+	if (attr == NULL || buf == NULL) {
+		dev_err(udc->dev, "[%s] EINVAL\n", __func__);
+		return 0;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	for (i = 0; i < udc->hw_ep_max; i++)
+		list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
+		{
+			req = list_entry(ptr, struct ci13xxx_req, queue);
+
+			n += scnprintf(buf + n, PAGE_SIZE - n,
+					"EP=%02i: TD=%08X %s\n",
+					i % udc->hw_ep_max/2, (u32)req->dma,
+					((i < udc->hw_ep_max/2) ? "RX" : "TX"));
+
+			for (j = 0; j < qSize; j++)
+				n += scnprintf(buf + n, PAGE_SIZE - n,
+						" %04X:    %08X\n", j,
+						*((u32 *)req->ptr + j));
+		}
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return n;
+}
+static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
+
+/**
+ * dbg_create_files: initializes the attribute interface
+ * @dev: device
+ *
+ * This function returns an error code
+ */
+int dbg_create_files(struct device *dev)
+{
+	int retval = 0;
+
+	if (dev == NULL)
+		return -EINVAL;
+	retval = device_create_file(dev, &dev_attr_device);
+	if (retval)
+		goto done;
+	retval = device_create_file(dev, &dev_attr_driver);
+	if (retval)
+		goto rm_device;
+	retval = device_create_file(dev, &dev_attr_events);
+	if (retval)
+		goto rm_driver;
+	retval = device_create_file(dev, &dev_attr_inters);
+	if (retval)
+		goto rm_events;
+	retval = device_create_file(dev, &dev_attr_port_test);
+	if (retval)
+		goto rm_inters;
+	retval = device_create_file(dev, &dev_attr_qheads);
+	if (retval)
+		goto rm_port_test;
+	retval = device_create_file(dev, &dev_attr_registers);
+	if (retval)
+		goto rm_qheads;
+	retval = device_create_file(dev, &dev_attr_requests);
+	if (retval)
+		goto rm_registers;
+	return 0;
+
+ rm_registers:
+	device_remove_file(dev, &dev_attr_registers);
+ rm_qheads:
+	device_remove_file(dev, &dev_attr_qheads);
+ rm_port_test:
+	device_remove_file(dev, &dev_attr_port_test);
+ rm_inters:
+	device_remove_file(dev, &dev_attr_inters);
+ rm_events:
+	device_remove_file(dev, &dev_attr_events);
+ rm_driver:
+	device_remove_file(dev, &dev_attr_driver);
+ rm_device:
+	device_remove_file(dev, &dev_attr_device);
+ done:
+	return retval;
+}
+
+/**
+ * dbg_remove_files: destroys the attribute interface
+ * @dev: device
+ *
+ * This function returns an error code
+ */
+int dbg_remove_files(struct device *dev)
+{
+	if (dev == NULL)
+		return -EINVAL;
+	device_remove_file(dev, &dev_attr_requests);
+	device_remove_file(dev, &dev_attr_registers);
+	device_remove_file(dev, &dev_attr_qheads);
+	device_remove_file(dev, &dev_attr_port_test);
+	device_remove_file(dev, &dev_attr_inters);
+	device_remove_file(dev, &dev_attr_events);
+	device_remove_file(dev, &dev_attr_driver);
+	device_remove_file(dev, &dev_attr_device);
+	return 0;
+}
diff --git a/drivers/usb/chipidea/debug.h b/drivers/usb/chipidea/debug.h
new file mode 100644
index 0000000..80d9686
--- /dev/null
+++ b/drivers/usb/chipidea/debug.h
@@ -0,0 +1,56 @@
+/*
+ * debug.h - ChipIdea USB driver debug interfaces
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_DEBUG_H
+#define __DRIVERS_USB_CHIPIDEA_DEBUG_H
+
+#ifdef CONFIG_USB_CHIPIDEA_DEBUG
+void dbg_interrupt(u32 intmask);
+void dbg_done(u8 addr, const u32 token, int status);
+void dbg_event(u8 addr, const char *name, int status);
+void dbg_queue(u8 addr, const struct usb_request *req, int status);
+void dbg_setup(u8 addr, const struct usb_ctrlrequest *req);
+int dbg_create_files(struct device *dev);
+int dbg_remove_files(struct device *dev);
+#else
+static inline void dbg_interrupt(u32 intmask)
+{
+}
+
+static inline void dbg_done(u8 addr, const u32 token, int status)
+{
+}
+
+static inline void dbg_event(u8 addr, const char *name, int status)
+{
+}
+
+static inline void dbg_queue(u8 addr, const struct usb_request *req, int status)
+{
+}
+
+static inline void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
+{
+}
+
+static inline int dbg_create_files(struct device *dev)
+{
+	return 0;
+}
+
+static inline int dbg_remove_files(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+#endif /* __DRIVERS_USB_CHIPIDEA_DEBUG_H */
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
new file mode 100644
index 0000000..9eacd21
--- /dev/null
+++ b/drivers/usb/chipidea/host.c
@@ -0,0 +1,160 @@
+/*
+ * host.c - ChipIdea USB host controller driver
+ *
+ * Copyright (c) 2012 Intel Corporation
+ *
+ * Author: Alexander Shishkin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/chipidea.h>
+
+#define CHIPIDEA_EHCI
+#include "../host/ehci-hcd.c"
+
+#include "ci.h"
+#include "bits.h"
+#include "host.h"
+
+static int ci_ehci_setup(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int ret;
+
+	hcd->has_tt = 1;
+
+	ret = ehci_setup(hcd);
+	if (ret)
+		return ret;
+
+	ehci_port_power(ehci, 0);
+
+	return ret;
+}
+
+static const struct hc_driver ci_ehci_hc_driver = {
+	.description	= "ehci_hcd",
+	.product_desc	= "ChipIdea HDRC EHCI",
+	.hcd_priv_size	= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq	= ehci_irq,
+	.flags	= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset		= ci_ehci_setup,
+	.start		= ehci_run,
+	.stop		= ehci_stop,
+	.shutdown	= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number = ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static irqreturn_t host_irq(struct ci13xxx *ci)
+{
+	return usb_hcd_irq(ci->irq, ci->hcd);
+}
+
+static int host_start(struct ci13xxx *ci)
+{
+	struct usb_hcd *hcd;
+	struct ehci_hcd *ehci;
+	int ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	hcd = usb_create_hcd(&ci_ehci_hc_driver, ci->dev, dev_name(ci->dev));
+	if (!hcd)
+		return -ENOMEM;
+
+	dev_set_drvdata(ci->dev, ci);
+	hcd->rsrc_start = ci->hw_bank.phys;
+	hcd->rsrc_len = ci->hw_bank.size;
+	hcd->regs = ci->hw_bank.abs;
+	hcd->has_tt = 1;
+
+	hcd->power_budget = ci->udc_driver->power_budget;
+
+	ehci = hcd_to_ehci(hcd);
+	ehci->caps = ci->hw_bank.cap;
+	ehci->has_hostpc = ci->hw_bank.lpm;
+
+	ret = usb_add_hcd(hcd, 0, 0);
+	if (ret)
+		usb_put_hcd(hcd);
+	else
+		ci->hcd = hcd;
+
+	return ret;
+}
+
+static void host_stop(struct ci13xxx *ci)
+{
+	struct usb_hcd *hcd = ci->hcd;
+
+	usb_remove_hcd(hcd);
+	usb_put_hcd(hcd);
+}
+
+int ci_hdrc_host_init(struct ci13xxx *ci)
+{
+	struct ci_role_driver *rdrv;
+
+	if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_HC))
+		return -ENXIO;
+
+	rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
+	if (!rdrv)
+		return -ENOMEM;
+
+	rdrv->start	= host_start;
+	rdrv->stop	= host_stop;
+	rdrv->irq	= host_irq;
+	rdrv->name	= "host";
+	ci->roles[CI_ROLE_HOST] = rdrv;
+
+	return 0;
+}
diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h
new file mode 100644
index 0000000..761fb1f
--- /dev/null
+++ b/drivers/usb/chipidea/host.h
@@ -0,0 +1,17 @@
+#ifndef __DRIVERS_USB_CHIPIDEA_HOST_H
+#define __DRIVERS_USB_CHIPIDEA_HOST_H
+
+#ifdef CONFIG_USB_CHIPIDEA_HOST
+
+int ci_hdrc_host_init(struct ci13xxx *ci);
+
+#else
+
+static inline int ci_hdrc_host_init(struct ci13xxx *ci)
+{
+	return -ENXIO;
+}
+
+#endif
+
+#endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
new file mode 100644
index 0000000..51f9694
--- /dev/null
+++ b/drivers/usb/chipidea/udc.c
@@ -0,0 +1,1809 @@
+/*
+ * udc.c - ChipIdea UDC driver
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/chipidea.h>
+
+#include "ci.h"
+#include "udc.h"
+#include "bits.h"
+#include "debug.h"
+
+/* control endpoint description */
+static const struct usb_endpoint_descriptor
+ctrl_endpt_out_desc = {
+	.bLength         = USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType = USB_DT_ENDPOINT,
+
+	.bEndpointAddress = USB_DIR_OUT,
+	.bmAttributes    = USB_ENDPOINT_XFER_CONTROL,
+	.wMaxPacketSize  = cpu_to_le16(CTRL_PAYLOAD_MAX),
+};
+
+static const struct usb_endpoint_descriptor
+ctrl_endpt_in_desc = {
+	.bLength         = USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType = USB_DT_ENDPOINT,
+
+	.bEndpointAddress = USB_DIR_IN,
+	.bmAttributes    = USB_ENDPOINT_XFER_CONTROL,
+	.wMaxPacketSize  = cpu_to_le16(CTRL_PAYLOAD_MAX),
+};
+
+/**
+ * hw_ep_bit: calculates the bit number
+ * @num: endpoint number
+ * @dir: endpoint direction
+ *
+ * This function returns bit number
+ */
+static inline int hw_ep_bit(int num, int dir)
+{
+	return num + (dir ? 16 : 0);
+}
+
+static inline int ep_to_bit(struct ci13xxx *udc, int n)
+{
+	int fill = 16 - udc->hw_ep_max / 2;
+
+	if (n >= udc->hw_ep_max / 2)
+		n += fill;
+
+	return n;
+}
+
+/**
+ * hw_device_state: enables/disables interrupts & starts/stops device (execute
+ *                  without interruption)
+ * @dma: 0 => disable, !0 => enable and set dma engine
+ *
+ * This function returns an error code
+ */
+static int hw_device_state(struct ci13xxx *udc, u32 dma)
+{
+	if (dma) {
+		hw_write(udc, OP_ENDPTLISTADDR, ~0, dma);
+		/* interrupt, error, port change, reset, sleep/suspend */
+		hw_write(udc, OP_USBINTR, ~0,
+			     USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
+		hw_write(udc, OP_USBCMD, USBCMD_RS, USBCMD_RS);
+	} else {
+		hw_write(udc, OP_USBCMD, USBCMD_RS, 0);
+		hw_write(udc, OP_USBINTR, ~0, 0);
+	}
+	return 0;
+}
+
+/**
+ * hw_ep_flush: flush endpoint fifo (execute without interruption)
+ * @num: endpoint number
+ * @dir: endpoint direction
+ *
+ * This function returns an error code
+ */
+static int hw_ep_flush(struct ci13xxx *udc, int num, int dir)
+{
+	int n = hw_ep_bit(num, dir);
+
+	do {
+		/* flush any pending transfer */
+		hw_write(udc, OP_ENDPTFLUSH, BIT(n), BIT(n));
+		while (hw_read(udc, OP_ENDPTFLUSH, BIT(n)))
+			cpu_relax();
+	} while (hw_read(udc, OP_ENDPTSTAT, BIT(n)));
+
+	return 0;
+}
+
+/**
+ * hw_ep_disable: disables endpoint (execute without interruption)
+ * @num: endpoint number
+ * @dir: endpoint direction
+ *
+ * This function returns an error code
+ */
+static int hw_ep_disable(struct ci13xxx *udc, int num, int dir)
+{
+	hw_ep_flush(udc, num, dir);
+	hw_write(udc, OP_ENDPTCTRL + num,
+		 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
+	return 0;
+}
+
+/**
+ * hw_ep_enable: enables endpoint (execute without interruption)
+ * @num:  endpoint number
+ * @dir:  endpoint direction
+ * @type: endpoint type
+ *
+ * This function returns an error code
+ */
+static int hw_ep_enable(struct ci13xxx *udc, int num, int dir, int type)
+{
+	u32 mask, data;
+
+	if (dir) {
+		mask  = ENDPTCTRL_TXT;  /* type    */
+		data  = type << ffs_nr(mask);
+
+		mask |= ENDPTCTRL_TXS;  /* unstall */
+		mask |= ENDPTCTRL_TXR;  /* reset data toggle */
+		data |= ENDPTCTRL_TXR;
+		mask |= ENDPTCTRL_TXE;  /* enable  */
+		data |= ENDPTCTRL_TXE;
+	} else {
+		mask  = ENDPTCTRL_RXT;  /* type    */
+		data  = type << ffs_nr(mask);
+
+		mask |= ENDPTCTRL_RXS;  /* unstall */
+		mask |= ENDPTCTRL_RXR;  /* reset data toggle */
+		data |= ENDPTCTRL_RXR;
+		mask |= ENDPTCTRL_RXE;  /* enable  */
+		data |= ENDPTCTRL_RXE;
+	}
+	hw_write(udc, OP_ENDPTCTRL + num, mask, data);
+	return 0;
+}
+
+/**
+ * hw_ep_get_halt: return endpoint halt status
+ * @num: endpoint number
+ * @dir: endpoint direction
+ *
+ * This function returns 1 if endpoint halted
+ */
+static int hw_ep_get_halt(struct ci13xxx *udc, int num, int dir)
+{
+	u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
+
+	return hw_read(udc, OP_ENDPTCTRL + num, mask) ? 1 : 0;
+}
+
+/**
+ * hw_test_and_clear_setup_status: test & clear setup status (execute without
+ *                                 interruption)
+ * @n: endpoint number
+ *
+ * This function returns setup status
+ */
+static int hw_test_and_clear_setup_status(struct ci13xxx *udc, int n)
+{
+	n = ep_to_bit(udc, n);
+	return hw_test_and_clear(udc, OP_ENDPTSETUPSTAT, BIT(n));
+}
+
+/**
+ * hw_ep_prime: primes endpoint (execute without interruption)
+ * @num:     endpoint number
+ * @dir:     endpoint direction
+ * @is_ctrl: true if control endpoint
+ *
+ * This function returns an error code
+ */
+static int hw_ep_prime(struct ci13xxx *udc, int num, int dir, int is_ctrl)
+{
+	int n = hw_ep_bit(num, dir);
+
+	if (is_ctrl && dir == RX && hw_read(udc, OP_ENDPTSETUPSTAT, BIT(num)))
+		return -EAGAIN;
+
+	hw_write(udc, OP_ENDPTPRIME, BIT(n), BIT(n));
+
+	while (hw_read(udc, OP_ENDPTPRIME, BIT(n)))
+		cpu_relax();
+	if (is_ctrl && dir == RX && hw_read(udc, OP_ENDPTSETUPSTAT, BIT(num)))
+		return -EAGAIN;
+
+	/* status shoult be tested according with manual but it doesn't work */
+	return 0;
+}
+
+/**
+ * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
+ *                 without interruption)
+ * @num:   endpoint number
+ * @dir:   endpoint direction
+ * @value: true => stall, false => unstall
+ *
+ * This function returns an error code
+ */
+static int hw_ep_set_halt(struct ci13xxx *udc, int num, int dir, int value)
+{
+	if (value != 0 && value != 1)
+		return -EINVAL;
+
+	do {
+		enum ci13xxx_regs reg = OP_ENDPTCTRL + num;
+		u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
+		u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
+
+		/* data toggle - reserved for EP0 but it's in ESS */
+		hw_write(udc, reg, mask_xs|mask_xr,
+			  value ? mask_xs : mask_xr);
+	} while (value != hw_ep_get_halt(udc, num, dir));
+
+	return 0;
+}
+
+/**
+ * hw_is_port_high_speed: test if port is high speed
+ *
+ * This function returns true if high speed port
+ */
+static int hw_port_is_high_speed(struct ci13xxx *udc)
+{
+	return udc->hw_bank.lpm ? hw_read(udc, OP_DEVLC, DEVLC_PSPD) :
+		hw_read(udc, OP_PORTSC, PORTSC_HSP);
+}
+
+/**
+ * hw_read_intr_enable: returns interrupt enable register
+ *
+ * This function returns register data
+ */
+static u32 hw_read_intr_enable(struct ci13xxx *udc)
+{
+	return hw_read(udc, OP_USBINTR, ~0);
+}
+
+/**
+ * hw_read_intr_status: returns interrupt status register
+ *
+ * This function returns register data
+ */
+static u32 hw_read_intr_status(struct ci13xxx *udc)
+{
+	return hw_read(udc, OP_USBSTS, ~0);
+}
+
+/**
+ * hw_test_and_clear_complete: test & clear complete status (execute without
+ *                             interruption)
+ * @n: endpoint number
+ *
+ * This function returns complete status
+ */
+static int hw_test_and_clear_complete(struct ci13xxx *udc, int n)
+{
+	n = ep_to_bit(udc, n);
+	return hw_test_and_clear(udc, OP_ENDPTCOMPLETE, BIT(n));
+}
+
+/**
+ * hw_test_and_clear_intr_active: test & clear active interrupts (execute
+ *                                without interruption)
+ *
+ * This function returns active interrutps
+ */
+static u32 hw_test_and_clear_intr_active(struct ci13xxx *udc)
+{
+	u32 reg = hw_read_intr_status(udc) & hw_read_intr_enable(udc);
+
+	hw_write(udc, OP_USBSTS, ~0, reg);
+	return reg;
+}
+
+/**
+ * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
+ *                                interruption)
+ *
+ * This function returns guard value
+ */
+static int hw_test_and_clear_setup_guard(struct ci13xxx *udc)
+{
+	return hw_test_and_write(udc, OP_USBCMD, USBCMD_SUTW, 0);
+}
+
+/**
+ * hw_test_and_set_setup_guard: test & set setup guard (execute without
+ *                              interruption)
+ *
+ * This function returns guard value
+ */
+static int hw_test_and_set_setup_guard(struct ci13xxx *udc)
+{
+	return hw_test_and_write(udc, OP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
+}
+
+/**
+ * hw_usb_set_address: configures USB address (execute without interruption)
+ * @value: new USB address
+ *
+ * This function explicitly sets the address, without the "USBADRA" (advance)
+ * feature, which is not supported by older versions of the controller.
+ */
+static void hw_usb_set_address(struct ci13xxx *udc, u8 value)
+{
+	hw_write(udc, OP_DEVICEADDR, DEVICEADDR_USBADR,
+		 value << ffs_nr(DEVICEADDR_USBADR));
+}
+
+/**
+ * hw_usb_reset: restart device after a bus reset (execute without
+ *               interruption)
+ *
+ * This function returns an error code
+ */
+static int hw_usb_reset(struct ci13xxx *udc)
+{
+	hw_usb_set_address(udc, 0);
+
+	/* ESS flushes only at end?!? */
+	hw_write(udc, OP_ENDPTFLUSH,    ~0, ~0);
+
+	/* clear setup token semaphores */
+	hw_write(udc, OP_ENDPTSETUPSTAT, 0,  0);
+
+	/* clear complete status */
+	hw_write(udc, OP_ENDPTCOMPLETE,  0,  0);
+
+	/* wait until all bits cleared */
+	while (hw_read(udc, OP_ENDPTPRIME, ~0))
+		udelay(10);             /* not RTOS friendly */
+
+	/* reset all endpoints ? */
+
+	/* reset internal status and wait for further instructions
+	   no need to verify the port reset status (ESS does it) */
+
+	return 0;
+}
+
+/******************************************************************************
+ * UTIL block
+ *****************************************************************************/
+/**
+ * _usb_addr: calculates endpoint address from direction & number
+ * @ep:  endpoint
+ */
+static inline u8 _usb_addr(struct ci13xxx_ep *ep)
+{
+	return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
+}
+
+/**
+ * _hardware_queue: configures a request at hardware level
+ * @gadget: gadget
+ * @mEp:    endpoint
+ *
+ * This function returns an error code
+ */
+static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
+{
+	struct ci13xxx *udc = mEp->udc;
+	unsigned i;
+	int ret = 0;
+	unsigned length = mReq->req.length;
+
+	/* don't queue twice */
+	if (mReq->req.status == -EALREADY)
+		return -EALREADY;
+
+	mReq->req.status = -EALREADY;
+
+	if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
+		mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
+					   &mReq->zdma);
+		if (mReq->zptr == NULL)
+			return -ENOMEM;
+
+		memset(mReq->zptr, 0, sizeof(*mReq->zptr));
+		mReq->zptr->next    = TD_TERMINATE;
+		mReq->zptr->token   = TD_STATUS_ACTIVE;
+		if (!mReq->req.no_interrupt)
+			mReq->zptr->token   |= TD_IOC;
+	}
+	ret = usb_gadget_map_request(&udc->gadget, &mReq->req, mEp->dir);
+	if (ret)
+		return ret;
+
+	/*
+	 * TD configuration
+	 * TODO - handle requests which spawns into several TDs
+	 */
+	memset(mReq->ptr, 0, sizeof(*mReq->ptr));
+	mReq->ptr->token    = length << ffs_nr(TD_TOTAL_BYTES);
+	mReq->ptr->token   &= TD_TOTAL_BYTES;
+	mReq->ptr->token   |= TD_STATUS_ACTIVE;
+	if (mReq->zptr) {
+		mReq->ptr->next    = mReq->zdma;
+	} else {
+		mReq->ptr->next    = TD_TERMINATE;
+		if (!mReq->req.no_interrupt)
+			mReq->ptr->token  |= TD_IOC;
+	}
+	mReq->ptr->page[0]  = mReq->req.dma;
+	for (i = 1; i < 5; i++)
+		mReq->ptr->page[i] =
+			(mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
+
+	if (!list_empty(&mEp->qh.queue)) {
+		struct ci13xxx_req *mReqPrev;
+		int n = hw_ep_bit(mEp->num, mEp->dir);
+		int tmp_stat;
+
+		mReqPrev = list_entry(mEp->qh.queue.prev,
+				struct ci13xxx_req, queue);
+		if (mReqPrev->zptr)
+			mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
+		else
+			mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
+		wmb();
+		if (hw_read(udc, OP_ENDPTPRIME, BIT(n)))
+			goto done;
+		do {
+			hw_write(udc, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
+			tmp_stat = hw_read(udc, OP_ENDPTSTAT, BIT(n));
+		} while (!hw_read(udc, OP_USBCMD, USBCMD_ATDTW));
+		hw_write(udc, OP_USBCMD, USBCMD_ATDTW, 0);
+		if (tmp_stat)
+			goto done;
+	}
+
+	/*  QH configuration */
+	mEp->qh.ptr->td.next   = mReq->dma;    /* TERMINATE = 0 */
+	mEp->qh.ptr->td.token &= ~TD_STATUS;   /* clear status */
+	mEp->qh.ptr->cap |=  QH_ZLT;
+
+	wmb();   /* synchronize before ep prime */
+
+	ret = hw_ep_prime(udc, mEp->num, mEp->dir,
+			   mEp->type == USB_ENDPOINT_XFER_CONTROL);
+done:
+	return ret;
+}
+
+/**
+ * _hardware_dequeue: handles a request at hardware level
+ * @gadget: gadget
+ * @mEp:    endpoint
+ *
+ * This function returns an error code
+ */
+static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
+{
+	if (mReq->req.status != -EALREADY)
+		return -EINVAL;
+
+	if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
+		return -EBUSY;
+
+	if (mReq->zptr) {
+		if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
+			return -EBUSY;
+		dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
+		mReq->zptr = NULL;
+	}
+
+	mReq->req.status = 0;
+
+	usb_gadget_unmap_request(&mEp->udc->gadget, &mReq->req, mEp->dir);
+
+	mReq->req.status = mReq->ptr->token & TD_STATUS;
+	if ((TD_STATUS_HALTED & mReq->req.status) != 0)
+		mReq->req.status = -1;
+	else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
+		mReq->req.status = -1;
+	else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
+		mReq->req.status = -1;
+
+	mReq->req.actual   = mReq->ptr->token & TD_TOTAL_BYTES;
+	mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
+	mReq->req.actual   = mReq->req.length - mReq->req.actual;
+	mReq->req.actual   = mReq->req.status ? 0 : mReq->req.actual;
+
+	return mReq->req.actual;
+}
+
+/**
+ * _ep_nuke: dequeues all endpoint requests
+ * @mEp: endpoint
+ *
+ * This function returns an error code
+ * Caller must hold lock
+ */
+static int _ep_nuke(struct ci13xxx_ep *mEp)
+__releases(mEp->lock)
+__acquires(mEp->lock)
+{
+	if (mEp == NULL)
+		return -EINVAL;
+
+	hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
+
+	while (!list_empty(&mEp->qh.queue)) {
+
+		/* pop oldest request */
+		struct ci13xxx_req *mReq = \
+			list_entry(mEp->qh.queue.next,
+				   struct ci13xxx_req, queue);
+		list_del_init(&mReq->queue);
+		mReq->req.status = -ESHUTDOWN;
+
+		if (mReq->req.complete != NULL) {
+			spin_unlock(mEp->lock);
+			mReq->req.complete(&mEp->ep, &mReq->req);
+			spin_lock(mEp->lock);
+		}
+	}
+	return 0;
+}
+
+/**
+ * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
+ * @gadget: gadget
+ *
+ * This function returns an error code
+ */
+static int _gadget_stop_activity(struct usb_gadget *gadget)
+{
+	struct usb_ep *ep;
+	struct ci13xxx    *udc = container_of(gadget, struct ci13xxx, gadget);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	udc->remote_wakeup = 0;
+	udc->suspended = 0;
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	/* flush all endpoints */
+	gadget_for_each_ep(ep, gadget) {
+		usb_ep_fifo_flush(ep);
+	}
+	usb_ep_fifo_flush(&udc->ep0out->ep);
+	usb_ep_fifo_flush(&udc->ep0in->ep);
+
+	if (udc->driver)
+		udc->driver->disconnect(gadget);
+
+	/* make sure to disable all endpoints */
+	gadget_for_each_ep(ep, gadget) {
+		usb_ep_disable(ep);
+	}
+
+	if (udc->status != NULL) {
+		usb_ep_free_request(&udc->ep0in->ep, udc->status);
+		udc->status = NULL;
+	}
+
+	return 0;
+}
+
+/******************************************************************************
+ * ISR block
+ *****************************************************************************/
+/**
+ * isr_reset_handler: USB reset interrupt handler
+ * @udc: UDC device
+ *
+ * This function resets USB engine after a bus reset occurred
+ */
+static void isr_reset_handler(struct ci13xxx *udc)
+__releases(udc->lock)
+__acquires(udc->lock)
+{
+	int retval;
+
+	dbg_event(0xFF, "BUS RST", 0);
+
+	spin_unlock(&udc->lock);
+	retval = _gadget_stop_activity(&udc->gadget);
+	if (retval)
+		goto done;
+
+	retval = hw_usb_reset(udc);
+	if (retval)
+		goto done;
+
+	udc->status = usb_ep_alloc_request(&udc->ep0in->ep, GFP_ATOMIC);
+	if (udc->status == NULL)
+		retval = -ENOMEM;
+
+done:
+	spin_lock(&udc->lock);
+
+	if (retval)
+		dev_err(udc->dev, "error: %i\n", retval);
+}
+
+/**
+ * isr_get_status_complete: get_status request complete function
+ * @ep:  endpoint
+ * @req: request handled
+ *
+ * Caller must release lock
+ */
+static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	if (ep == NULL || req == NULL)
+		return;
+
+	kfree(req->buf);
+	usb_ep_free_request(ep, req);
+}
+
+/**
+ * isr_get_status_response: get_status request response
+ * @udc: udc struct
+ * @setup: setup request packet
+ *
+ * This function returns an error code
+ */
+static int isr_get_status_response(struct ci13xxx *udc,
+				   struct usb_ctrlrequest *setup)
+__releases(mEp->lock)
+__acquires(mEp->lock)
+{
+	struct ci13xxx_ep *mEp = udc->ep0in;
+	struct usb_request *req = NULL;
+	gfp_t gfp_flags = GFP_ATOMIC;
+	int dir, num, retval;
+
+	if (mEp == NULL || setup == NULL)
+		return -EINVAL;
+
+	spin_unlock(mEp->lock);
+	req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
+	spin_lock(mEp->lock);
+	if (req == NULL)
+		return -ENOMEM;
+
+	req->complete = isr_get_status_complete;
+	req->length   = 2;
+	req->buf      = kzalloc(req->length, gfp_flags);
+	if (req->buf == NULL) {
+		retval = -ENOMEM;
+		goto err_free_req;
+	}
+
+	if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
+		/* Assume that device is bus powered for now. */
+		*(u16 *)req->buf = udc->remote_wakeup << 1;
+		retval = 0;
+	} else if ((setup->bRequestType & USB_RECIP_MASK) \
+		   == USB_RECIP_ENDPOINT) {
+		dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
+			TX : RX;
+		num =  le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
+		*(u16 *)req->buf = hw_ep_get_halt(udc, num, dir);
+	}
+	/* else do nothing; reserved for future use */
+
+	spin_unlock(mEp->lock);
+	retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
+	spin_lock(mEp->lock);
+	if (retval)
+		goto err_free_buf;
+
+	return 0;
+
+ err_free_buf:
+	kfree(req->buf);
+ err_free_req:
+	spin_unlock(mEp->lock);
+	usb_ep_free_request(&mEp->ep, req);
+	spin_lock(mEp->lock);
+	return retval;
+}
+
+/**
+ * isr_setup_status_complete: setup_status request complete function
+ * @ep:  endpoint
+ * @req: request handled
+ *
+ * Caller must release lock. Put the port in test mode if test mode
+ * feature is selected.
+ */
+static void
+isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	struct ci13xxx *udc = req->context;
+	unsigned long flags;
+
+	if (udc->setaddr) {
+		hw_usb_set_address(udc, udc->address);
+		udc->setaddr = false;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (udc->test_mode)
+		hw_port_test_set(udc, udc->test_mode);
+	spin_unlock_irqrestore(&udc->lock, flags);
+}
+
+/**
+ * isr_setup_status_phase: queues the status phase of a setup transation
+ * @udc: udc struct
+ *
+ * This function returns an error code
+ */
+static int isr_setup_status_phase(struct ci13xxx *udc)
+__releases(mEp->lock)
+__acquires(mEp->lock)
+{
+	int retval;
+	struct ci13xxx_ep *mEp;
+
+	mEp = (udc->ep0_dir == TX) ? udc->ep0out : udc->ep0in;
+	udc->status->context = udc;
+	udc->status->complete = isr_setup_status_complete;
+
+	spin_unlock(mEp->lock);
+	retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
+	spin_lock(mEp->lock);
+
+	return retval;
+}
+
+/**
+ * isr_tr_complete_low: transaction complete low level handler
+ * @mEp: endpoint
+ *
+ * This function returns an error code
+ * Caller must hold lock
+ */
+static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
+__releases(mEp->lock)
+__acquires(mEp->lock)
+{
+	struct ci13xxx_req *mReq, *mReqTemp;
+	struct ci13xxx_ep *mEpTemp = mEp;
+	int uninitialized_var(retval);
+
+	if (list_empty(&mEp->qh.queue))
+		return -EINVAL;
+
+	list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
+			queue) {
+		retval = _hardware_dequeue(mEp, mReq);
+		if (retval < 0)
+			break;
+		list_del_init(&mReq->queue);
+		dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
+		if (mReq->req.complete != NULL) {
+			spin_unlock(mEp->lock);
+			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
+					mReq->req.length)
+				mEpTemp = mEp->udc->ep0in;
+			mReq->req.complete(&mEpTemp->ep, &mReq->req);
+			spin_lock(mEp->lock);
+		}
+	}
+
+	if (retval == -EBUSY)
+		retval = 0;
+	if (retval < 0)
+		dbg_event(_usb_addr(mEp), "DONE", retval);
+
+	return retval;
+}
+
+/**
+ * isr_tr_complete_handler: transaction complete interrupt handler
+ * @udc: UDC descriptor
+ *
+ * This function handles traffic events
+ */
+static void isr_tr_complete_handler(struct ci13xxx *udc)
+__releases(udc->lock)
+__acquires(udc->lock)
+{
+	unsigned i;
+	u8 tmode = 0;
+
+	for (i = 0; i < udc->hw_ep_max; i++) {
+		struct ci13xxx_ep *mEp  = &udc->ci13xxx_ep[i];
+		int type, num, dir, err = -EINVAL;
+		struct usb_ctrlrequest req;
+
+		if (mEp->ep.desc == NULL)
+			continue;   /* not configured */
+
+		if (hw_test_and_clear_complete(udc, i)) {
+			err = isr_tr_complete_low(mEp);
+			if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
+				if (err > 0)   /* needs status phase */
+					err = isr_setup_status_phase(udc);
+				if (err < 0) {
+					dbg_event(_usb_addr(mEp),
+						  "ERROR", err);
+					spin_unlock(&udc->lock);
+					if (usb_ep_set_halt(&mEp->ep))
+						dev_err(udc->dev,
+							"error: ep_set_halt\n");
+					spin_lock(&udc->lock);
+				}
+			}
+		}
+
+		if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
+		    !hw_test_and_clear_setup_status(udc, i))
+			continue;
+
+		if (i != 0) {
+			dev_warn(udc->dev, "ctrl traffic at endpoint %d\n", i);
+			continue;
+		}
+
+		/*
+		 * Flush data and handshake transactions of previous
+		 * setup packet.
+		 */
+		_ep_nuke(udc->ep0out);
+		_ep_nuke(udc->ep0in);
+
+		/* read_setup_packet */
+		do {
+			hw_test_and_set_setup_guard(udc);
+			memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
+		} while (!hw_test_and_clear_setup_guard(udc));
+
+		type = req.bRequestType;
+
+		udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
+
+		dbg_setup(_usb_addr(mEp), &req);
+
+		switch (req.bRequest) {
+		case USB_REQ_CLEAR_FEATURE:
+			if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
+					le16_to_cpu(req.wValue) ==
+					USB_ENDPOINT_HALT) {
+				if (req.wLength != 0)
+					break;
+				num  = le16_to_cpu(req.wIndex);
+				dir = num & USB_ENDPOINT_DIR_MASK;
+				num &= USB_ENDPOINT_NUMBER_MASK;
+				if (dir) /* TX */
+					num += udc->hw_ep_max/2;
+				if (!udc->ci13xxx_ep[num].wedge) {
+					spin_unlock(&udc->lock);
+					err = usb_ep_clear_halt(
+						&udc->ci13xxx_ep[num].ep);
+					spin_lock(&udc->lock);
+					if (err)
+						break;
+				}
+				err = isr_setup_status_phase(udc);
+			} else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
+					le16_to_cpu(req.wValue) ==
+					USB_DEVICE_REMOTE_WAKEUP) {
+				if (req.wLength != 0)
+					break;
+				udc->remote_wakeup = 0;
+				err = isr_setup_status_phase(udc);
+			} else {
+				goto delegate;
+			}
+			break;
+		case USB_REQ_GET_STATUS:
+			if (type != (USB_DIR_IN|USB_RECIP_DEVICE)   &&
+			    type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
+			    type != (USB_DIR_IN|USB_RECIP_INTERFACE))
+				goto delegate;
+			if (le16_to_cpu(req.wLength) != 2 ||
+			    le16_to_cpu(req.wValue)  != 0)
+				break;
+			err = isr_get_status_response(udc, &req);
+			break;
+		case USB_REQ_SET_ADDRESS:
+			if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
+				goto delegate;
+			if (le16_to_cpu(req.wLength) != 0 ||
+			    le16_to_cpu(req.wIndex)  != 0)
+				break;
+			udc->address = (u8)le16_to_cpu(req.wValue);
+			udc->setaddr = true;
+			err = isr_setup_status_phase(udc);
+			break;
+		case USB_REQ_SET_FEATURE:
+			if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
+					le16_to_cpu(req.wValue) ==
+					USB_ENDPOINT_HALT) {
+				if (req.wLength != 0)
+					break;
+				num  = le16_to_cpu(req.wIndex);
+				dir = num & USB_ENDPOINT_DIR_MASK;
+				num &= USB_ENDPOINT_NUMBER_MASK;
+				if (dir) /* TX */
+					num += udc->hw_ep_max/2;
+
+				spin_unlock(&udc->lock);
+				err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
+				spin_lock(&udc->lock);
+				if (!err)
+					isr_setup_status_phase(udc);
+			} else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
+				if (req.wLength != 0)
+					break;
+				switch (le16_to_cpu(req.wValue)) {
+				case USB_DEVICE_REMOTE_WAKEUP:
+					udc->remote_wakeup = 1;
+					err = isr_setup_status_phase(udc);
+					break;
+				case USB_DEVICE_TEST_MODE:
+					tmode = le16_to_cpu(req.wIndex) >> 8;
+					switch (tmode) {
+					case TEST_J:
+					case TEST_K:
+					case TEST_SE0_NAK:
+					case TEST_PACKET:
+					case TEST_FORCE_EN:
+						udc->test_mode = tmode;
+						err = isr_setup_status_phase(
+								udc);
+						break;
+					default:
+						break;
+					}
+				default:
+					goto delegate;
+				}
+			} else {
+				goto delegate;
+			}
+			break;
+		default:
+delegate:
+			if (req.wLength == 0)   /* no data phase */
+				udc->ep0_dir = TX;
+
+			spin_unlock(&udc->lock);
+			err = udc->driver->setup(&udc->gadget, &req);
+			spin_lock(&udc->lock);
+			break;
+		}
+
+		if (err < 0) {
+			dbg_event(_usb_addr(mEp), "ERROR", err);
+
+			spin_unlock(&udc->lock);
+			if (usb_ep_set_halt(&mEp->ep))
+				dev_err(udc->dev, "error: ep_set_halt\n");
+			spin_lock(&udc->lock);
+		}
+	}
+}
+
+/******************************************************************************
+ * ENDPT block
+ *****************************************************************************/
+/**
+ * ep_enable: configure endpoint, making it usable
+ *
+ * Check usb_ep_enable() at "usb_gadget.h" for details
+ */
+static int ep_enable(struct usb_ep *ep,
+		     const struct usb_endpoint_descriptor *desc)
+{
+	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
+	int retval = 0;
+	unsigned long flags;
+
+	if (ep == NULL || desc == NULL)
+		return -EINVAL;
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	/* only internal SW should enable ctrl endpts */
+
+	mEp->ep.desc = desc;
+
+	if (!list_empty(&mEp->qh.queue))
+		dev_warn(mEp->udc->dev, "enabling a non-empty endpoint!\n");
+
+	mEp->dir  = usb_endpoint_dir_in(desc) ? TX : RX;
+	mEp->num  = usb_endpoint_num(desc);
+	mEp->type = usb_endpoint_type(desc);
+
+	mEp->ep.maxpacket = usb_endpoint_maxp(desc);
+
+	dbg_event(_usb_addr(mEp), "ENABLE", 0);
+
+	mEp->qh.ptr->cap = 0;
+
+	if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
+		mEp->qh.ptr->cap |=  QH_IOS;
+	else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
+		mEp->qh.ptr->cap &= ~QH_MULT;
+	else
+		mEp->qh.ptr->cap &= ~QH_ZLT;
+
+	mEp->qh.ptr->cap |=
+		(mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
+	mEp->qh.ptr->td.next |= TD_TERMINATE;   /* needed? */
+
+	/*
+	 * Enable endpoints in the HW other than ep0 as ep0
+	 * is always enabled
+	 */
+	if (mEp->num)
+		retval |= hw_ep_enable(mEp->udc, mEp->num, mEp->dir, mEp->type);
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+	return retval;
+}
+
+/**
+ * ep_disable: endpoint is no longer usable
+ *
+ * Check usb_ep_disable() at "usb_gadget.h" for details
+ */
+static int ep_disable(struct usb_ep *ep)
+{
+	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
+	int direction, retval = 0;
+	unsigned long flags;
+
+	if (ep == NULL)
+		return -EINVAL;
+	else if (mEp->ep.desc == NULL)
+		return -EBUSY;
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	/* only internal SW should disable ctrl endpts */
+
+	direction = mEp->dir;
+	do {
+		dbg_event(_usb_addr(mEp), "DISABLE", 0);
+
+		retval |= _ep_nuke(mEp);
+		retval |= hw_ep_disable(mEp->udc, mEp->num, mEp->dir);
+
+		if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
+			mEp->dir = (mEp->dir == TX) ? RX : TX;
+
+	} while (mEp->dir != direction);
+
+	mEp->ep.desc = NULL;
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+	return retval;
+}
+
+/**
+ * ep_alloc_request: allocate a request object to use with this endpoint
+ *
+ * Check usb_ep_alloc_request() at "usb_gadget.h" for details
+ */
+static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
+{
+	struct ci13xxx_ep  *mEp  = container_of(ep, struct ci13xxx_ep, ep);
+	struct ci13xxx_req *mReq = NULL;
+
+	if (ep == NULL)
+		return NULL;
+
+	mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
+	if (mReq != NULL) {
+		INIT_LIST_HEAD(&mReq->queue);
+
+		mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
+					   &mReq->dma);
+		if (mReq->ptr == NULL) {
+			kfree(mReq);
+			mReq = NULL;
+		}
+	}
+
+	dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
+
+	return (mReq == NULL) ? NULL : &mReq->req;
+}
+
+/**
+ * ep_free_request: frees a request object
+ *
+ * Check usb_ep_free_request() at "usb_gadget.h" for details
+ */
+static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
+{
+	struct ci13xxx_ep  *mEp  = container_of(ep,  struct ci13xxx_ep, ep);
+	struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
+	unsigned long flags;
+
+	if (ep == NULL || req == NULL) {
+		return;
+	} else if (!list_empty(&mReq->queue)) {
+		dev_err(mEp->udc->dev, "freeing queued request\n");
+		return;
+	}
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	if (mReq->ptr)
+		dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
+	kfree(mReq);
+
+	dbg_event(_usb_addr(mEp), "FREE", 0);
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+}
+
+/**
+ * ep_queue: queues (submits) an I/O request to an endpoint
+ *
+ * Check usb_ep_queue()* at usb_gadget.h" for details
+ */
+static int ep_queue(struct usb_ep *ep, struct usb_request *req,
+		    gfp_t __maybe_unused gfp_flags)
+{
+	struct ci13xxx_ep  *mEp  = container_of(ep,  struct ci13xxx_ep, ep);
+	struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
+	struct ci13xxx *udc = mEp->udc;
+	int retval = 0;
+	unsigned long flags;
+
+	if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
+		return -EINVAL;
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
+		if (req->length)
+			mEp = (udc->ep0_dir == RX) ?
+			       udc->ep0out : udc->ep0in;
+		if (!list_empty(&mEp->qh.queue)) {
+			_ep_nuke(mEp);
+			retval = -EOVERFLOW;
+			dev_warn(mEp->udc->dev, "endpoint ctrl %X nuked\n",
+				 _usb_addr(mEp));
+		}
+	}
+
+	/* first nuke then test link, e.g. previous status has not sent */
+	if (!list_empty(&mReq->queue)) {
+		retval = -EBUSY;
+		dev_err(mEp->udc->dev, "request already in queue\n");
+		goto done;
+	}
+
+	if (req->length > 4 * CI13XXX_PAGE_SIZE) {
+		req->length = 4 * CI13XXX_PAGE_SIZE;
+		retval = -EMSGSIZE;
+		dev_warn(mEp->udc->dev, "request length truncated\n");
+	}
+
+	dbg_queue(_usb_addr(mEp), req, retval);
+
+	/* push request */
+	mReq->req.status = -EINPROGRESS;
+	mReq->req.actual = 0;
+
+	retval = _hardware_enqueue(mEp, mReq);
+
+	if (retval == -EALREADY) {
+		dbg_event(_usb_addr(mEp), "QUEUE", retval);
+		retval = 0;
+	}
+	if (!retval)
+		list_add_tail(&mReq->queue, &mEp->qh.queue);
+
+ done:
+	spin_unlock_irqrestore(mEp->lock, flags);
+	return retval;
+}
+
+/**
+ * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
+ *
+ * Check usb_ep_dequeue() at "usb_gadget.h" for details
+ */
+static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
+{
+	struct ci13xxx_ep  *mEp  = container_of(ep,  struct ci13xxx_ep, ep);
+	struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
+	unsigned long flags;
+
+	if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
+		mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
+		list_empty(&mEp->qh.queue))
+		return -EINVAL;
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
+
+	hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
+
+	/* pop request */
+	list_del_init(&mReq->queue);
+
+	usb_gadget_unmap_request(&mEp->udc->gadget, req, mEp->dir);
+
+	req->status = -ECONNRESET;
+
+	if (mReq->req.complete != NULL) {
+		spin_unlock(mEp->lock);
+		mReq->req.complete(&mEp->ep, &mReq->req);
+		spin_lock(mEp->lock);
+	}
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+	return 0;
+}
+
+/**
+ * ep_set_halt: sets the endpoint halt feature
+ *
+ * Check usb_ep_set_halt() at "usb_gadget.h" for details
+ */
+static int ep_set_halt(struct usb_ep *ep, int value)
+{
+	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
+	int direction, retval = 0;
+	unsigned long flags;
+
+	if (ep == NULL || mEp->ep.desc == NULL)
+		return -EINVAL;
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+#ifndef STALL_IN
+	/* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
+	if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
+	    !list_empty(&mEp->qh.queue)) {
+		spin_unlock_irqrestore(mEp->lock, flags);
+		return -EAGAIN;
+	}
+#endif
+
+	direction = mEp->dir;
+	do {
+		dbg_event(_usb_addr(mEp), "HALT", value);
+		retval |= hw_ep_set_halt(mEp->udc, mEp->num, mEp->dir, value);
+
+		if (!value)
+			mEp->wedge = 0;
+
+		if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
+			mEp->dir = (mEp->dir == TX) ? RX : TX;
+
+	} while (mEp->dir != direction);
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+	return retval;
+}
+
+/**
+ * ep_set_wedge: sets the halt feature and ignores clear requests
+ *
+ * Check usb_ep_set_wedge() at "usb_gadget.h" for details
+ */
+static int ep_set_wedge(struct usb_ep *ep)
+{
+	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
+	unsigned long flags;
+
+	if (ep == NULL || mEp->ep.desc == NULL)
+		return -EINVAL;
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	dbg_event(_usb_addr(mEp), "WEDGE", 0);
+	mEp->wedge = 1;
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+
+	return usb_ep_set_halt(ep);
+}
+
+/**
+ * ep_fifo_flush: flushes contents of a fifo
+ *
+ * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
+ */
+static void ep_fifo_flush(struct usb_ep *ep)
+{
+	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
+	unsigned long flags;
+
+	if (ep == NULL) {
+		dev_err(mEp->udc->dev, "%02X: -EINVAL\n", _usb_addr(mEp));
+		return;
+	}
+
+	spin_lock_irqsave(mEp->lock, flags);
+
+	dbg_event(_usb_addr(mEp), "FFLUSH", 0);
+	hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
+
+	spin_unlock_irqrestore(mEp->lock, flags);
+}
+
+/**
+ * Endpoint-specific part of the API to the USB controller hardware
+ * Check "usb_gadget.h" for details
+ */
+static const struct usb_ep_ops usb_ep_ops = {
+	.enable	       = ep_enable,
+	.disable       = ep_disable,
+	.alloc_request = ep_alloc_request,
+	.free_request  = ep_free_request,
+	.queue	       = ep_queue,
+	.dequeue       = ep_dequeue,
+	.set_halt      = ep_set_halt,
+	.set_wedge     = ep_set_wedge,
+	.fifo_flush    = ep_fifo_flush,
+};
+
+/******************************************************************************
+ * GADGET block
+ *****************************************************************************/
+static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+	struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
+	unsigned long flags;
+	int gadget_ready = 0;
+
+	if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
+		return -EOPNOTSUPP;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->vbus_active = is_active;
+	if (udc->driver)
+		gadget_ready = 1;
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	if (gadget_ready) {
+		if (is_active) {
+			pm_runtime_get_sync(&_gadget->dev);
+			hw_device_reset(udc, USBMODE_CM_DC);
+			hw_device_state(udc, udc->ep0out->qh.dma);
+		} else {
+			hw_device_state(udc, 0);
+			if (udc->udc_driver->notify_event)
+				udc->udc_driver->notify_event(udc,
+				CI13XXX_CONTROLLER_STOPPED_EVENT);
+			_gadget_stop_activity(&udc->gadget);
+			pm_runtime_put_sync(&_gadget->dev);
+		}
+	}
+
+	return 0;
+}
+
+static int ci13xxx_wakeup(struct usb_gadget *_gadget)
+{
+	struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (!udc->remote_wakeup) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+	if (!hw_read(udc, OP_PORTSC, PORTSC_SUSP)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	hw_write(udc, OP_PORTSC, PORTSC_FPR, PORTSC_FPR);
+out:
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return ret;
+}
+
+static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
+{
+	struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
+
+	if (udc->transceiver)
+		return usb_phy_set_power(udc->transceiver, mA);
+	return -ENOTSUPP;
+}
+
+static int ci13xxx_start(struct usb_gadget *gadget,
+			 struct usb_gadget_driver *driver);
+static int ci13xxx_stop(struct usb_gadget *gadget,
+			struct usb_gadget_driver *driver);
+/**
+ * Device operations part of the API to the USB controller hardware,
+ * which don't involve endpoints (or i/o)
+ * Check  "usb_gadget.h" for details
+ */
+static const struct usb_gadget_ops usb_gadget_ops = {
+	.vbus_session	= ci13xxx_vbus_session,
+	.wakeup		= ci13xxx_wakeup,
+	.vbus_draw	= ci13xxx_vbus_draw,
+	.udc_start	= ci13xxx_start,
+	.udc_stop	= ci13xxx_stop,
+};
+
+static int init_eps(struct ci13xxx *udc)
+{
+	int retval = 0, i, j;
+
+	for (i = 0; i < udc->hw_ep_max/2; i++)
+		for (j = RX; j <= TX; j++) {
+			int k = i + j * udc->hw_ep_max/2;
+			struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
+
+			scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
+					(j == TX)  ? "in" : "out");
+
+			mEp->udc          = udc;
+			mEp->lock         = &udc->lock;
+			mEp->td_pool      = udc->td_pool;
+
+			mEp->ep.name      = mEp->name;
+			mEp->ep.ops       = &usb_ep_ops;
+			mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
+
+			INIT_LIST_HEAD(&mEp->qh.queue);
+			mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
+						     &mEp->qh.dma);
+			if (mEp->qh.ptr == NULL)
+				retval = -ENOMEM;
+			else
+				memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
+
+			/*
+			 * set up shorthands for ep0 out and in endpoints,
+			 * don't add to gadget's ep_list
+			 */
+			if (i == 0) {
+				if (j == RX)
+					udc->ep0out = mEp;
+				else
+					udc->ep0in = mEp;
+
+				continue;
+			}
+
+			list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
+		}
+
+	return retval;
+}
+
+/**
+ * ci13xxx_start: register a gadget driver
+ * @gadget: our gadget
+ * @driver: the driver being registered
+ *
+ * Interrupts are enabled here.
+ */
+static int ci13xxx_start(struct usb_gadget *gadget,
+			 struct usb_gadget_driver *driver)
+{
+	struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
+	unsigned long flags;
+	int retval = -ENOMEM;
+
+	if (driver->disconnect == NULL)
+		return -EINVAL;
+
+
+	udc->ep0out->ep.desc = &ctrl_endpt_out_desc;
+	retval = usb_ep_enable(&udc->ep0out->ep);
+	if (retval)
+		return retval;
+
+	udc->ep0in->ep.desc = &ctrl_endpt_in_desc;
+	retval = usb_ep_enable(&udc->ep0in->ep);
+	if (retval)
+		return retval;
+	spin_lock_irqsave(&udc->lock, flags);
+
+	udc->driver = driver;
+	pm_runtime_get_sync(&udc->gadget.dev);
+	if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
+		if (udc->vbus_active) {
+			if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
+				hw_device_reset(udc, USBMODE_CM_DC);
+		} else {
+			pm_runtime_put_sync(&udc->gadget.dev);
+			goto done;
+		}
+	}
+
+	retval = hw_device_state(udc, udc->ep0out->qh.dma);
+	if (retval)
+		pm_runtime_put_sync(&udc->gadget.dev);
+
+ done:
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return retval;
+}
+
+/**
+ * ci13xxx_stop: unregister a gadget driver
+ */
+static int ci13xxx_stop(struct usb_gadget *gadget,
+			struct usb_gadget_driver *driver)
+{
+	struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
+			udc->vbus_active) {
+		hw_device_state(udc, 0);
+		if (udc->udc_driver->notify_event)
+			udc->udc_driver->notify_event(udc,
+			CI13XXX_CONTROLLER_STOPPED_EVENT);
+		udc->driver = NULL;
+		spin_unlock_irqrestore(&udc->lock, flags);
+		_gadget_stop_activity(&udc->gadget);
+		spin_lock_irqsave(&udc->lock, flags);
+		pm_runtime_put(&udc->gadget.dev);
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+/******************************************************************************
+ * BUS block
+ *****************************************************************************/
+/**
+ * udc_irq: udc interrupt handler
+ *
+ * This function returns IRQ_HANDLED if the IRQ has been handled
+ * It locks access to registers
+ */
+static irqreturn_t udc_irq(struct ci13xxx *udc)
+{
+	irqreturn_t retval;
+	u32 intr;
+
+	if (udc == NULL)
+		return IRQ_HANDLED;
+
+	spin_lock(&udc->lock);
+
+	if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
+		if (hw_read(udc, OP_USBMODE, USBMODE_CM) !=
+				USBMODE_CM_DC) {
+			spin_unlock(&udc->lock);
+			return IRQ_NONE;
+		}
+	}
+	intr = hw_test_and_clear_intr_active(udc);
+	dbg_interrupt(intr);
+
+	if (intr) {
+		/* order defines priority - do NOT change it */
+		if (USBi_URI & intr)
+			isr_reset_handler(udc);
+
+		if (USBi_PCI & intr) {
+			udc->gadget.speed = hw_port_is_high_speed(udc) ?
+				USB_SPEED_HIGH : USB_SPEED_FULL;
+			if (udc->suspended && udc->driver->resume) {
+				spin_unlock(&udc->lock);
+				udc->driver->resume(&udc->gadget);
+				spin_lock(&udc->lock);
+				udc->suspended = 0;
+			}
+		}
+
+		if (USBi_UI  & intr)
+			isr_tr_complete_handler(udc);
+
+		if (USBi_SLI & intr) {
+			if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
+			    udc->driver->suspend) {
+				udc->suspended = 1;
+				spin_unlock(&udc->lock);
+				udc->driver->suspend(&udc->gadget);
+				spin_lock(&udc->lock);
+			}
+		}
+		retval = IRQ_HANDLED;
+	} else {
+		retval = IRQ_NONE;
+	}
+	spin_unlock(&udc->lock);
+
+	return retval;
+}
+
+/**
+ * udc_release: driver release function
+ * @dev: device
+ *
+ * Currently does nothing
+ */
+static void udc_release(struct device *dev)
+{
+}
+
+/**
+ * udc_start: initialize gadget role
+ * @udc: chipidea controller
+ */
+static int udc_start(struct ci13xxx *udc)
+{
+	struct device *dev = udc->dev;
+	int retval = 0;
+
+	if (!udc)
+		return -EINVAL;
+
+	spin_lock_init(&udc->lock);
+
+	udc->gadget.ops          = &usb_gadget_ops;
+	udc->gadget.speed        = USB_SPEED_UNKNOWN;
+	udc->gadget.max_speed    = USB_SPEED_HIGH;
+	udc->gadget.is_otg       = 0;
+	udc->gadget.name         = udc->udc_driver->name;
+
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+
+	dev_set_name(&udc->gadget.dev, "gadget");
+	udc->gadget.dev.dma_mask = dev->dma_mask;
+	udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
+	udc->gadget.dev.parent   = dev;
+	udc->gadget.dev.release  = udc_release;
+
+	/* alloc resources */
+	udc->qh_pool = dma_pool_create("ci13xxx_qh", dev,
+				       sizeof(struct ci13xxx_qh),
+				       64, CI13XXX_PAGE_SIZE);
+	if (udc->qh_pool == NULL)
+		return -ENOMEM;
+
+	udc->td_pool = dma_pool_create("ci13xxx_td", dev,
+				       sizeof(struct ci13xxx_td),
+				       64, CI13XXX_PAGE_SIZE);
+	if (udc->td_pool == NULL) {
+		retval = -ENOMEM;
+		goto free_qh_pool;
+	}
+
+	retval = init_eps(udc);
+	if (retval)
+		goto free_pools;
+
+	udc->gadget.ep0 = &udc->ep0in->ep;
+
+	udc->transceiver = usb_get_transceiver();
+
+	if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
+		if (udc->transceiver == NULL) {
+			retval = -ENODEV;
+			goto free_pools;
+		}
+	}
+
+	if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
+		retval = hw_device_reset(udc, USBMODE_CM_DC);
+		if (retval)
+			goto put_transceiver;
+	}
+
+	retval = device_register(&udc->gadget.dev);
+	if (retval) {
+		put_device(&udc->gadget.dev);
+		goto put_transceiver;
+	}
+
+	retval = dbg_create_files(&udc->gadget.dev);
+	if (retval)
+		goto unreg_device;
+
+	if (udc->transceiver) {
+		retval = otg_set_peripheral(udc->transceiver->otg,
+						&udc->gadget);
+		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);
+
+	return retval;
+
+remove_trans:
+	if (udc->transceiver) {
+		otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
+		usb_put_transceiver(udc->transceiver);
+	}
+
+	dev_err(dev, "error = %i\n", retval);
+remove_dbg:
+	dbg_remove_files(&udc->gadget.dev);
+unreg_device:
+	device_unregister(&udc->gadget.dev);
+put_transceiver:
+	if (udc->transceiver)
+		usb_put_transceiver(udc->transceiver);
+free_pools:
+	dma_pool_destroy(udc->td_pool);
+free_qh_pool:
+	dma_pool_destroy(udc->qh_pool);
+	return retval;
+}
+
+/**
+ * udc_remove: parent remove must call this to remove UDC
+ *
+ * No interrupts active, the IRQ has been released
+ */
+static void udc_stop(struct ci13xxx *udc)
+{
+	int i;
+
+	if (udc == NULL)
+		return;
+
+	usb_del_gadget_udc(&udc->gadget);
+
+	for (i = 0; i < udc->hw_ep_max; i++) {
+		struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
+
+		dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
+	}
+
+	dma_pool_destroy(udc->td_pool);
+	dma_pool_destroy(udc->qh_pool);
+
+	if (udc->transceiver) {
+		otg_set_peripheral(udc->transceiver->otg, NULL);
+		usb_put_transceiver(udc->transceiver);
+	}
+	dbg_remove_files(&udc->gadget.dev);
+	device_unregister(&udc->gadget.dev);
+	/* my kobject is dynamic, I swear! */
+	memset(&udc->gadget, 0, sizeof(udc->gadget));
+}
+
+/**
+ * ci_hdrc_gadget_init - initialize device related bits
+ * ci: the controller
+ *
+ * This function enables the gadget role, if the device is "device capable".
+ */
+int ci_hdrc_gadget_init(struct ci13xxx *ci)
+{
+	struct ci_role_driver *rdrv;
+
+	if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC))
+		return -ENXIO;
+
+	rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
+	if (!rdrv)
+		return -ENOMEM;
+
+	rdrv->start	= udc_start;
+	rdrv->stop	= udc_stop;
+	rdrv->irq	= udc_irq;
+	rdrv->name	= "gadget";
+	ci->roles[CI_ROLE_GADGET] = rdrv;
+
+	return 0;
+}
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
new file mode 100644
index 0000000..4ff2384d
--- /dev/null
+++ b/drivers/usb/chipidea/udc.h
@@ -0,0 +1,93 @@
+/*
+ * udc.h - ChipIdea UDC structures
+ *
+ * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
+ *
+ * Author: David Lopo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DRIVERS_USB_CHIPIDEA_UDC_H
+#define __DRIVERS_USB_CHIPIDEA_UDC_H
+
+#include <linux/list.h>
+
+#define CTRL_PAYLOAD_MAX   64
+#define RX        0  /* similar to USB_DIR_OUT but can be used as an index */
+#define TX        1  /* similar to USB_DIR_IN  but can be used as an index */
+
+/* DMA layout of transfer descriptors */
+struct ci13xxx_td {
+	/* 0 */
+	u32 next;
+#define TD_TERMINATE          BIT(0)
+#define TD_ADDR_MASK          (0xFFFFFFEUL << 5)
+	/* 1 */
+	u32 token;
+#define TD_STATUS             (0x00FFUL <<  0)
+#define TD_STATUS_TR_ERR      BIT(3)
+#define TD_STATUS_DT_ERR      BIT(5)
+#define TD_STATUS_HALTED      BIT(6)
+#define TD_STATUS_ACTIVE      BIT(7)
+#define TD_MULTO              (0x0003UL << 10)
+#define TD_IOC                BIT(15)
+#define TD_TOTAL_BYTES        (0x7FFFUL << 16)
+	/* 2 */
+	u32 page[5];
+#define TD_CURR_OFFSET        (0x0FFFUL <<  0)
+#define TD_FRAME_NUM          (0x07FFUL <<  0)
+#define TD_RESERVED_MASK      (0x0FFFUL <<  0)
+} __attribute__ ((packed));
+
+/* DMA layout of queue heads */
+struct ci13xxx_qh {
+	/* 0 */
+	u32 cap;
+#define QH_IOS                BIT(15)
+#define QH_MAX_PKT            (0x07FFUL << 16)
+#define QH_ZLT                BIT(29)
+#define QH_MULT               (0x0003UL << 30)
+	/* 1 */
+	u32 curr;
+	/* 2 - 8 */
+	struct ci13xxx_td        td;
+	/* 9 */
+	u32 RESERVED;
+	struct usb_ctrlrequest   setup;
+} __attribute__ ((packed));
+
+/**
+ * struct ci13xxx_req - usb request representation
+ * @req: request structure for gadget drivers
+ * @queue: link to QH list
+ * @ptr: transfer descriptor for this request
+ * @dma: dma address for the transfer descriptor
+ * @zptr: transfer descriptor for the zero packet
+ * @zdma: dma address of the zero packet's transfer descriptor
+ */
+struct ci13xxx_req {
+	struct usb_request	req;
+	struct list_head	queue;
+	struct ci13xxx_td	*ptr;
+	dma_addr_t		dma;
+	struct ci13xxx_td	*zptr;
+	dma_addr_t		zdma;
+};
+
+#ifdef CONFIG_USB_CHIPIDEA_UDC
+
+int ci_hdrc_gadget_init(struct ci13xxx *ci);
+
+#else
+
+static inline int ci_hdrc_gadget_init(struct ci13xxx *ci)
+{
+	return -ENXIO;
+}
+
+#endif
+
+#endif /* __DRIVERS_USB_CHIPIDEA_UDC_H */
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 0bb2b32..631bb95 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -309,9 +309,6 @@
 
 static void cleanup(struct wdm_device *desc)
 {
-	spin_lock(&wdm_device_list_lock);
-	list_del(&desc->device_list);
-	spin_unlock(&wdm_device_list_lock);
 	kfree(desc->sbuf);
 	kfree(desc->inbuf);
 	kfree(desc->orq);
@@ -369,6 +366,7 @@
 	r = usb_autopm_get_interface(desc->intf);
 	if (r < 0) {
 		kfree(buf);
+		rv = usb_translate_errors(r);
 		goto outnp;
 	}
 
@@ -384,6 +382,7 @@
 
 	if (r < 0) {
 		kfree(buf);
+		rv = r;
 		goto out;
 	}
 
@@ -415,6 +414,7 @@
 		desc->outbuf = NULL;
 		clear_bit(WDM_IN_USE, &desc->flags);
 		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
+		rv = usb_translate_errors(rv);
 	} else {
 		dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
 			req->wIndex);
@@ -530,11 +530,13 @@
 	struct wdm_device *desc = file->private_data;
 
 	wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
-	if (desc->werr < 0)
+
+	/* cannot dereference desc->intf if WDM_DISCONNECTING */
+	if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags))
 		dev_err(&desc->intf->dev, "Error in flush path: %d\n",
 			desc->werr);
 
-	return desc->werr;
+	return usb_translate_errors(desc->werr);
 }
 
 static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait)
@@ -545,7 +547,7 @@
 
 	spin_lock_irqsave(&desc->iuspin, flags);
 	if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
-		mask = POLLERR;
+		mask = POLLHUP | POLLERR;
 		spin_unlock_irqrestore(&desc->iuspin, flags);
 		goto desc_out;
 	}
@@ -596,6 +598,7 @@
 			desc->count--;
 			dev_err(&desc->intf->dev,
 				"Error submitting int urb - %d\n", rv);
+			rv = usb_translate_errors(rv);
 		}
 	} else {
 		rv = 0;
@@ -621,10 +624,15 @@
 	mutex_unlock(&desc->wlock);
 
 	if (!desc->count) {
-		dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
-		kill_urbs(desc);
-		if (!test_bit(WDM_DISCONNECTING, &desc->flags))
+		if (!test_bit(WDM_DISCONNECTING, &desc->flags)) {
+			dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
+			kill_urbs(desc);
 			desc->manage_power(desc->intf, 0);
+		} else {
+			/* must avoid dev_printk here as desc->intf is invalid */
+			pr_debug(KBUILD_MODNAME " %s: device gone - cleaning up\n", __func__);
+			cleanup(desc);
+		}
 	}
 	mutex_unlock(&wdm_mutex);
 	return 0;
@@ -771,6 +779,9 @@
 out:
 	return rv;
 err:
+	spin_lock(&wdm_device_list_lock);
+	list_del(&desc->device_list);
+	spin_unlock(&wdm_device_list_lock);
 	cleanup(desc);
 	return rv;
 }
@@ -896,8 +907,16 @@
 	cancel_work_sync(&desc->rxwork);
 	mutex_unlock(&desc->wlock);
 	mutex_unlock(&desc->rlock);
+
+	/* the desc->intf pointer used as list key is now invalid */
+	spin_lock(&wdm_device_list_lock);
+	list_del(&desc->device_list);
+	spin_unlock(&wdm_device_list_lock);
+
 	if (!desc->count)
 		cleanup(desc);
+	else
+		dev_dbg(&intf->dev, "%s: %d open files - postponing cleanup\n", __func__, desc->count);
 	mutex_unlock(&wdm_mutex);
 }
 
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index a68c1a6..d4c47d5 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -172,27 +172,31 @@
 #ifdef DEBUG
 static void usblp_dump(struct usblp *usblp)
 {
+	struct device *dev = &usblp->intf->dev;
 	int p;
 
-	dbg("usblp=0x%p", usblp);
-	dbg("dev=0x%p", usblp->dev);
-	dbg("present=%d", usblp->present);
-	dbg("readbuf=0x%p", usblp->readbuf);
-	dbg("readcount=%d", usblp->readcount);
-	dbg("ifnum=%d", usblp->ifnum);
-    for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
-	dbg("protocol[%d].alt_setting=%d", p, usblp->protocol[p].alt_setting);
-	dbg("protocol[%d].epwrite=%p", p, usblp->protocol[p].epwrite);
-	dbg("protocol[%d].epread=%p", p, usblp->protocol[p].epread);
-    }
-	dbg("current_protocol=%d", usblp->current_protocol);
-	dbg("minor=%d", usblp->minor);
-	dbg("wstatus=%d", usblp->wstatus);
-	dbg("rstatus=%d", usblp->rstatus);
-	dbg("quirks=%d", usblp->quirks);
-	dbg("used=%d", usblp->used);
-	dbg("bidir=%d", usblp->bidir);
-	dbg("device_id_string=\"%s\"",
+	dev_dbg(dev, "usblp=0x%p\n", usblp);
+	dev_dbg(dev, "dev=0x%p\n", usblp->dev);
+	dev_dbg(dev, "present=%d\n", usblp->present);
+	dev_dbg(dev, "readbuf=0x%p\n", usblp->readbuf);
+	dev_dbg(dev, "readcount=%d\n", usblp->readcount);
+	dev_dbg(dev, "ifnum=%d\n", usblp->ifnum);
+	for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
+		dev_dbg(dev, "protocol[%d].alt_setting=%d\n", p,
+			usblp->protocol[p].alt_setting);
+		dev_dbg(dev, "protocol[%d].epwrite=%p\n", p,
+			usblp->protocol[p].epwrite);
+		dev_dbg(dev, "protocol[%d].epread=%p\n", p,
+			usblp->protocol[p].epread);
+	}
+	dev_dbg(dev, "current_protocol=%d\n", usblp->current_protocol);
+	dev_dbg(dev, "minor=%d\n", usblp->minor);
+	dev_dbg(dev, "wstatus=%d\n", usblp->wstatus);
+	dev_dbg(dev, "rstatus=%d\n", usblp->rstatus);
+	dev_dbg(dev, "quirks=%d\n", usblp->quirks);
+	dev_dbg(dev, "used=%d\n", usblp->used);
+	dev_dbg(dev, "bidir=%d\n", usblp->bidir);
+	dev_dbg(dev, "device_id_string=\"%s\"\n",
 		usblp->device_id_string ?
 			usblp->device_id_string + 2 :
 			(unsigned char *)"(null)");
@@ -262,7 +266,8 @@
 	retval = usb_control_msg(usblp->dev,
 		dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0),
 		request, type | dir | recip, value, index, buf, len, USBLP_CTL_TIMEOUT);
-	dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d",
+	dev_dbg(&usblp->intf->dev,
+		"usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d\n",
 		request, !!dir, recip, value, index, len, retval);
 	return retval < 0 ? retval : 0;
 }
@@ -500,8 +505,9 @@
 		goto done;
 	}
 
-	dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd),
-		_IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd));
+	dev_dbg(&usblp->intf->dev,
+		"usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)\n", cmd,
+		_IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd));
 
 	if (_IOC_TYPE(cmd) == 'P')	/* new-style ioctl number */
 
@@ -594,7 +600,8 @@
 				goto done;
 			}
 
-			dbg("usblp%d requested/got HP channel %ld/%d",
+			dev_dbg(&usblp->intf->dev,
+				"usblp%d requested/got HP channel %ld/%d\n",
 				usblp->minor, arg, newChannel);
 			break;
 
@@ -614,7 +621,8 @@
 				goto done;
 			}
 
-			dbg("usblp%d is bus=%d, device=%d",
+			dev_dbg(&usblp->intf->dev,
+				"usblp%d is bus=%d, device=%d\n",
 				usblp->minor, twoints[0], twoints[1]);
 			break;
 
@@ -634,7 +642,8 @@
 				goto done;
 			}
 
-			dbg("usblp%d is VID=0x%4.4X, PID=0x%4.4X",
+			dev_dbg(&usblp->intf->dev,
+				"usblp%d is VID=0x%4.4X, PID=0x%4.4X\n",
 				usblp->minor, twoints[0], twoints[1]);
 			break;
 
@@ -987,7 +996,7 @@
 	usblp->rcomplete = 0;
 	spin_unlock_irqrestore(&usblp->lock, flags);
 	if ((rc = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
-		dbg("error submitting urb (%d)", rc);
+		dev_dbg(&usblp->intf->dev, "error submitting urb (%d)\n", rc);
 		spin_lock_irqsave(&usblp->lock, flags);
 		usblp->rstatus = rc;
 		usblp->rcomplete = 1;
@@ -1129,7 +1138,8 @@
 	/* Analyze and pick initial alternate settings and endpoints. */
 	protocol = usblp_select_alts(usblp);
 	if (protocol < 0) {
-		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
+		dev_dbg(&intf->dev,
+			"incompatible printer-class device 0x%4.4X/0x%4.4X\n",
 			le16_to_cpu(dev->descriptor.idVendor),
 			le16_to_cpu(dev->descriptor.idProduct));
 		retval = -ENODEV;
@@ -1158,14 +1168,14 @@
 
 	retval = usb_register_dev(intf, &usblp_class);
 	if (retval) {
-		printk(KERN_ERR "usblp: Not able to get a minor"
-		    " (base %u, slice default): %d\n",
-		    USBLP_MINOR_BASE, retval);
+		dev_err(&intf->dev,
+			"usblp: Not able to get a minor (base %u, slice default): %d\n",
+			USBLP_MINOR_BASE, retval);
 		goto abort_intfdata;
 	}
 	usblp->minor = intf->minor;
-	printk(KERN_INFO "usblp%d: USB %sdirectional printer dev %d "
-		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n",
+	dev_info(&intf->dev,
+		"usblp%d: USB %sdirectional printer dev %d if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X\n",
 		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
 		usblp->ifnum,
 		usblp->protocol[usblp->current_protocol].alt_setting,
@@ -1302,7 +1312,8 @@
 
 	usblp->bidir = (usblp->protocol[protocol].epread != NULL);
 	usblp->current_protocol = protocol;
-	dbg("usblp%d set protocol %d", usblp->minor, protocol);
+	dev_dbg(&usblp->intf->dev, "usblp%d set protocol %d\n",
+		usblp->minor, protocol);
 	return 0;
 }
 
@@ -1315,7 +1326,8 @@
 
 	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
 	if (err < 0) {
-		dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
+		dev_dbg(&usblp->intf->dev,
+			"usblp%d: error = %d reading IEEE-1284 Device ID string\n",
 			usblp->minor, err);
 		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
 		return -EIO;
@@ -1331,7 +1343,7 @@
 		length = USBLP_DEVICE_ID_SIZE - 1;
 	usblp->device_id_string[length] = '\0';
 
-	dbg("usblp%d Device ID string [len=%d]=\"%s\"",
+	dev_dbg(&usblp->intf->dev, "usblp%d Device ID string [len=%d]=\"%s\"\n",
 		usblp->minor, length, &usblp->device_id_string[2]);
 
 	return length;
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index 18d02e3..9981984 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -27,58 +27,6 @@
 comment "Miscellaneous USB options"
 	depends on USB
 
-config USB_DEVICEFS
-	bool "USB device filesystem (DEPRECATED)"
-	depends on USB
-	---help---
-	  If you say Y here (and to "/proc file system support" in the "File
-	  systems" section, above), you will get a file /proc/bus/usb/devices
-	  which lists the devices currently connected to your USB bus or
-	  busses, and for every connected device a file named
-	  "/proc/bus/usb/xxx/yyy", where xxx is the bus number and yyy the
-	  device number; the latter files can be used by user space programs
-	  to talk directly to the device. These files are "virtual", meaning
-	  they are generated on the fly and not stored on the hard drive.
-
-	  You may need to mount the usbfs file system to see the files, use
-	  mount -t usbfs none /proc/bus/usb
-
-	  For the format of the various /proc/bus/usb/ files, please read
-	  <file:Documentation/usb/proc_usb_info.txt>.
-
-	  Modern Linux systems do not use this.
-
-	  Usbfs entries are files and not character devices; usbfs can't
-	  handle Access Control Lists (ACL) which are the default way to
-	  grant access to USB devices for untrusted users of a desktop
-	  system.
-
-	  The usbfs functionality is replaced by real device-nodes managed by
-	  udev.  These nodes lived in /dev/bus/usb and are used by libusb.
-
-config USB_DEVICE_CLASS
-	bool "USB device class-devices (DEPRECATED)"
-	depends on USB
-	default y
-	---help---
-	  Userspace access to USB devices is granted by device-nodes exported
-	  directly from the usbdev in sysfs. Old versions of the driver
-	  core and udev needed additional class devices to export device nodes.
-
-	  These additional devices are difficult to handle in userspace, if
-	  information about USB interfaces must be available. One device
-	  contains the device node, the other device contains the interface
-	  data. Both devices are at the same level in sysfs (siblings) and one
-	  can't access the other. The device node created directly by the
-	  usb device is the parent device of the interface and therefore
-	  easily accessible from the interface event.
-
-	  This option provides backward compatibility for libusb device
-	  nodes (lsusb) when usbfs is not used, and the following udev rule
-	  doesn't exist:
-	    SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
-	    NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
-
 config USB_DYNAMIC_MINORS
 	bool "Dynamic USB minor allocation"
 	depends on USB
@@ -125,7 +73,6 @@
 	bool "Rely on OTG Targeted Peripherals List"
 	depends on USB_OTG || EXPERT
 	default y if USB_OTG
-	default n if EXPERT
 	help
 	  If you say Y here, the "otg_whitelist.h" file will be used as a
 	  product whitelist, so USB peripherals not listed there will be
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 507a4e1..26059b9 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -9,6 +9,6 @@
 usbcore-y += devio.o notify.o generic.o quirks.o devices.o
 
 usbcore-$(CONFIG_PCI)		+= hcd-pci.o
-usbcore-$(CONFIG_USB_DEVICEFS)	+= inode.o
+usbcore-$(CONFIG_ACPI)		+= usb-acpi.o
 
 obj-$(CONFIG_USB)		+= usbcore.o
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 8df4b76..c4a1af8 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -727,17 +727,6 @@
 	if (imajor(inode) == USB_DEVICE_MAJOR)
 		dev = usbdev_lookup_by_devt(inode->i_rdev);
 
-#ifdef CONFIG_USB_DEVICEFS
-	/* procfs file */
-	if (!dev) {
-		dev = inode->i_private;
-		if (dev && dev->usbfs_dentry &&
-					dev->usbfs_dentry->d_inode == inode)
-			usb_get_dev(dev);
-		else
-			dev = NULL;
-	}
-#endif
 	mutex_unlock(&usbfs_mutex);
 
 	if (!dev)
@@ -2062,44 +2051,13 @@
 	}
 }
 
-#ifdef CONFIG_USB_DEVICE_CLASS
-static struct class *usb_classdev_class;
-
-static int usb_classdev_add(struct usb_device *dev)
-{
-	struct device *cldev;
-
-	cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt,
-			      NULL, "usbdev%d.%d", dev->bus->busnum,
-			      dev->devnum);
-	if (IS_ERR(cldev))
-		return PTR_ERR(cldev);
-	dev->usb_classdev = cldev;
-	return 0;
-}
-
-static void usb_classdev_remove(struct usb_device *dev)
-{
-	if (dev->usb_classdev)
-		device_unregister(dev->usb_classdev);
-}
-
-#else
-#define usb_classdev_add(dev)		0
-#define usb_classdev_remove(dev)	do {} while (0)
-
-#endif
-
 static int usbdev_notify(struct notifier_block *self,
 			       unsigned long action, void *dev)
 {
 	switch (action) {
 	case USB_DEVICE_ADD:
-		if (usb_classdev_add(dev))
-			return NOTIFY_BAD;
 		break;
 	case USB_DEVICE_REMOVE:
-		usb_classdev_remove(dev);
 		usbdev_remove(dev);
 		break;
 	}
@@ -2129,21 +2087,6 @@
 		       USB_DEVICE_MAJOR);
 		goto error_cdev;
 	}
-#ifdef CONFIG_USB_DEVICE_CLASS
-	usb_classdev_class = class_create(THIS_MODULE, "usb_device");
-	if (IS_ERR(usb_classdev_class)) {
-		printk(KERN_ERR "Unable to register usb_device class\n");
-		retval = PTR_ERR(usb_classdev_class);
-		cdev_del(&usb_device_cdev);
-		usb_classdev_class = NULL;
-		goto out;
-	}
-	/* devices of this class shadow the major:minor of their parent
-	 * device, so clear ->dev_kobj to prevent adding duplicate entries
-	 * to /sys/dev
-	 */
-	usb_classdev_class->dev_kobj = NULL;
-#endif
 	usb_register_notify(&usbdev_nb);
 out:
 	return retval;
@@ -2156,9 +2099,6 @@
 void usb_devio_cleanup(void)
 {
 	usb_unregister_notify(&usbdev_nb);
-#ifdef CONFIG_USB_DEVICE_CLASS
-	class_destroy(usb_classdev_class);
-#endif
 	cdev_del(&usb_device_cdev);
 	unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
 }
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 9a56635..f6f81c8 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -79,6 +79,30 @@
 }
 EXPORT_SYMBOL_GPL(usb_store_new_id);
 
+ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf)
+{
+	struct usb_dynid *dynid;
+	size_t count = 0;
+
+	list_for_each_entry(dynid, &dynids->list, node)
+		if (dynid->id.bInterfaceClass != 0)
+			count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x %02x\n",
+					   dynid->id.idVendor, dynid->id.idProduct,
+					   dynid->id.bInterfaceClass);
+		else
+			count += scnprintf(&buf[count], PAGE_SIZE - count, "%04x %04x\n",
+					   dynid->id.idVendor, dynid->id.idProduct);
+	return count;
+}
+EXPORT_SYMBOL_GPL(usb_show_dynids);
+
+static ssize_t show_dynids(struct device_driver *driver, char *buf)
+{
+	struct usb_driver *usb_drv = to_usb_driver(driver);
+
+	return usb_show_dynids(&usb_drv->dynids, buf);
+}
+
 static ssize_t store_new_id(struct device_driver *driver,
 			    const char *buf, size_t count)
 {
@@ -86,7 +110,7 @@
 
 	return usb_store_new_id(&usb_drv->dynids, driver, buf, count);
 }
-static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+static DRIVER_ATTR(new_id, S_IRUGO | S_IWUSR, show_dynids, store_new_id);
 
 /**
  * store_remove_id - remove a USB device ID from this driver
@@ -127,7 +151,7 @@
 		return retval;
 	return count;
 }
-static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
+static DRIVER_ATTR(remove_id, S_IRUGO | S_IWUSR, show_dynids, store_remove_id);
 
 static int usb_create_newid_files(struct usb_driver *usb_drv)
 {
@@ -726,16 +750,6 @@
 		return -ENODEV;
 	}
 
-#ifdef	CONFIG_USB_DEVICEFS
-	/* If this is available, userspace programs can directly read
-	 * all the device descriptors we don't tell them about.  Or
-	 * act as usermode drivers.
-	 */
-	if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
-			   usb_dev->bus->busnum, usb_dev->devnum))
-		return -ENOMEM;
-#endif
-
 	/* per-device configurations are common */
 	if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
 			   le16_to_cpu(usb_dev->descriptor.idVendor),
@@ -788,15 +802,13 @@
 
 	retval = driver_register(&new_udriver->drvwrap.driver);
 
-	if (!retval) {
+	if (!retval)
 		pr_info("%s: registered new device driver %s\n",
 			usbcore_name, new_udriver->name);
-		usbfs_update_special();
-	} else {
+	else
 		printk(KERN_ERR "%s: error %d registering device "
 			"	driver %s\n",
 			usbcore_name, retval, new_udriver->name);
-	}
 
 	return retval;
 }
@@ -815,7 +827,6 @@
 			usbcore_name, udriver->name);
 
 	driver_unregister(&udriver->drvwrap.driver);
-	usbfs_update_special();
 }
 EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
 
@@ -856,8 +867,6 @@
 	if (retval)
 		goto out;
 
-	usbfs_update_special();
-
 	retval = usb_create_newid_files(new_driver);
 	if (retval)
 		goto out_newid;
@@ -897,8 +906,6 @@
 	usb_remove_newid_files(driver);
 	driver_unregister(&driver->drvwrap.driver);
 	usb_free_dynids(driver);
-
-	usbfs_update_special();
 }
 EXPORT_SYMBOL_GPL(usb_deregister);
 
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index d95760d..e673b26 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -183,7 +183,7 @@
 	if (retval)
 		return retval;
 
-	dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);
+	dev_dbg(&intf->dev, "looking for a minor, starting at %d\n", minor_base);
 
 	down_write(&minor_rwsem);
 	for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
@@ -239,7 +239,7 @@
 	if (intf->minor == -1)
 		return;
 
-	dbg ("removing %d minor", intf->minor);
+	dev_dbg(&intf->dev, "removing %d minor\n", intf->minor);
 
 	down_write(&minor_rwsem);
 	usb_minors[intf->minor] = NULL;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 140d3e1..0cd2daa 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -138,7 +138,7 @@
 	0x03,       /*  __u8  bDeviceProtocol; USB 3.0 hub */
 	0x09,       /*  __u8  bMaxPacketSize0; 2^9 = 512 Bytes */
 
-	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
+	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */
 	0x03, 0x00, /*  __le16 idProduct; device 0x0003 */
 	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
@@ -159,7 +159,7 @@
 	0x00,       /*  __u8  bDeviceProtocol; [ usb 2.0 no TT ] */
 	0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
 
-	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
+	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */
 	0x02, 0x00, /*  __le16 idProduct; device 0x0002 */
 	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
@@ -182,7 +182,7 @@
 	0x00,       /*  __u8  bDeviceProtocol; [ low/full speeds only ] */
 	0x40,       /*  __u8  bMaxPacketSize0; 64 Bytes */
 
-	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation */
+	0x6b, 0x1d, /*  __le16 idVendor; Linux Foundation 0x1d6b */
 	0x01, 0x00, /*  __le16 idProduct; device 0x0001 */
 	KERNEL_VER, KERNEL_REL, /*  __le16 bcdDevice */
 
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
deleted file mode 100644
index d2b9af5..0000000
--- a/drivers/usb/core/inode.c
+++ /dev/null
@@ -1,748 +0,0 @@
-/*****************************************************************************/
-
-/*
- *	inode.c  --  Inode/Dentry functions for the USB device file system.
- *
- *	Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *	Copyright (C) 2001,2002,2004 Greg Kroah-Hartman (greg@kroah.com)
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	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, write to the Free Software
- *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  History:
- *   0.1  04.01.2000  Created
- *   0.2  10.12.2001  converted to use the vfs layer better
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/pagemap.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/usb.h>
-#include <linux/namei.h>
-#include <linux/usbdevice_fs.h>
-#include <linux/parser.h>
-#include <linux/notifier.h>
-#include <linux/seq_file.h>
-#include <linux/usb/hcd.h>
-#include <asm/byteorder.h>
-#include "usb.h"
-
-#define USBFS_DEFAULT_DEVMODE (S_IWUSR | S_IRUGO)
-#define USBFS_DEFAULT_BUSMODE (S_IXUGO | S_IRUGO)
-#define USBFS_DEFAULT_LISTMODE S_IRUGO
-
-static const struct file_operations default_file_operations;
-static struct vfsmount *usbfs_mount;
-static int usbfs_mount_count;	/* = 0 */
-
-static struct dentry *devices_usbfs_dentry;
-static int num_buses;	/* = 0 */
-
-static uid_t devuid;	/* = 0 */
-static uid_t busuid;	/* = 0 */
-static uid_t listuid;	/* = 0 */
-static gid_t devgid;	/* = 0 */
-static gid_t busgid;	/* = 0 */
-static gid_t listgid;	/* = 0 */
-static umode_t devmode = USBFS_DEFAULT_DEVMODE;
-static umode_t busmode = USBFS_DEFAULT_BUSMODE;
-static umode_t listmode = USBFS_DEFAULT_LISTMODE;
-
-static int usbfs_show_options(struct seq_file *seq, struct dentry *root)
-{
-	if (devuid != 0)
-		seq_printf(seq, ",devuid=%u", devuid);
-	if (devgid != 0)
-		seq_printf(seq, ",devgid=%u", devgid);
-	if (devmode != USBFS_DEFAULT_DEVMODE)
-		seq_printf(seq, ",devmode=%o", devmode);
-	if (busuid != 0)
-		seq_printf(seq, ",busuid=%u", busuid);
-	if (busgid != 0)
-		seq_printf(seq, ",busgid=%u", busgid);
-	if (busmode != USBFS_DEFAULT_BUSMODE)
-		seq_printf(seq, ",busmode=%o", busmode);
-	if (listuid != 0)
-		seq_printf(seq, ",listuid=%u", listuid);
-	if (listgid != 0)
-		seq_printf(seq, ",listgid=%u", listgid);
-	if (listmode != USBFS_DEFAULT_LISTMODE)
-		seq_printf(seq, ",listmode=%o", listmode);
-
-	return 0;
-}
-
-enum {
-	Opt_devuid, Opt_devgid, Opt_devmode,
-	Opt_busuid, Opt_busgid, Opt_busmode,
-	Opt_listuid, Opt_listgid, Opt_listmode,
-	Opt_err,
-};
-
-static const match_table_t tokens = {
-	{Opt_devuid, "devuid=%u"},
-	{Opt_devgid, "devgid=%u"},
-	{Opt_devmode, "devmode=%o"},
-	{Opt_busuid, "busuid=%u"},
-	{Opt_busgid, "busgid=%u"},
-	{Opt_busmode, "busmode=%o"},
-	{Opt_listuid, "listuid=%u"},
-	{Opt_listgid, "listgid=%u"},
-	{Opt_listmode, "listmode=%o"},
-	{Opt_err, NULL}
-};
-
-static int parse_options(struct super_block *s, char *data)
-{
-	char *p;
-	int option;
-
-	/* (re)set to defaults. */
-	devuid = 0;
-	busuid = 0;
-	listuid = 0;
-	devgid = 0;
-	busgid = 0;
-	listgid = 0;
-	devmode = USBFS_DEFAULT_DEVMODE;
-	busmode = USBFS_DEFAULT_BUSMODE;
-	listmode = USBFS_DEFAULT_LISTMODE;
-
-	while ((p = strsep(&data, ",")) != NULL) {
-		substring_t args[MAX_OPT_ARGS];
-		int token;
-		if (!*p)
-			continue;
-
-		token = match_token(p, tokens, args);
-		switch (token) {
-		case Opt_devuid:
-			if (match_int(&args[0], &option))
-			       return -EINVAL;
-			devuid = option;
-			break;
-		case Opt_devgid:
-			if (match_int(&args[0], &option))
-			       return -EINVAL;
-			devgid = option;
-			break;
-		case Opt_devmode:
-			if (match_octal(&args[0], &option))
-				return -EINVAL;
-			devmode = option & S_IRWXUGO;
-			break;
-		case Opt_busuid:
-			if (match_int(&args[0], &option))
-			       return -EINVAL;
-			busuid = option;
-			break;
-		case Opt_busgid:
-			if (match_int(&args[0], &option))
-			       return -EINVAL;
-			busgid = option;
-			break;
-		case Opt_busmode:
-			if (match_octal(&args[0], &option))
-				return -EINVAL;
-			busmode = option & S_IRWXUGO;
-			break;
-		case Opt_listuid:
-			if (match_int(&args[0], &option))
-			       return -EINVAL;
-			listuid = option;
-			break;
-		case Opt_listgid:
-			if (match_int(&args[0], &option))
-			       return -EINVAL;
-			listgid = option;
-			break;
-		case Opt_listmode:
-			if (match_octal(&args[0], &option))
-				return -EINVAL;
-			listmode = option & S_IRWXUGO;
-			break;
-		default:
-			printk(KERN_ERR "usbfs: unrecognised mount option "
-			       "\"%s\" or missing value\n", p);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static void update_special(struct dentry *special)
-{
-	special->d_inode->i_uid = listuid;
-	special->d_inode->i_gid = listgid;
-	special->d_inode->i_mode = S_IFREG | listmode;
-}
-
-static void update_dev(struct dentry *dev)
-{
-	dev->d_inode->i_uid = devuid;
-	dev->d_inode->i_gid = devgid;
-	dev->d_inode->i_mode = S_IFREG | devmode;
-}
-
-static void update_bus(struct dentry *bus)
-{
-	struct dentry *dev = NULL;
-
-	bus->d_inode->i_uid = busuid;
-	bus->d_inode->i_gid = busgid;
-	bus->d_inode->i_mode = S_IFDIR | busmode;
-
-	mutex_lock(&bus->d_inode->i_mutex);
-
-	list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
-		if (dev->d_inode)
-			update_dev(dev);
-
-	mutex_unlock(&bus->d_inode->i_mutex);
-}
-
-static void update_sb(struct super_block *sb)
-{
-	struct dentry *root = sb->s_root;
-	struct dentry *bus = NULL;
-
-	if (!root)
-		return;
-
-	mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
-
-	list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
-		if (bus->d_inode) {
-			switch (S_IFMT & bus->d_inode->i_mode) {
-			case S_IFDIR:
-				update_bus(bus);
-				break;
-			case S_IFREG:
-				update_special(bus);
-				break;
-			default:
-				printk(KERN_WARNING "usbfs: Unknown node %s "
-				       "mode %x found on remount!\n",
-				       bus->d_name.name, bus->d_inode->i_mode);
-				break;
-			}
-		}
-	}
-
-	mutex_unlock(&root->d_inode->i_mutex);
-}
-
-static int remount(struct super_block *sb, int *flags, char *data)
-{
-	/* If this is not a real mount,
-	 * i.e. it's a simple_pin_fs from create_special_files,
-	 * then ignore it.
-	 */
-	if (*flags & MS_KERNMOUNT)
-		return 0;
-
-	if (parse_options(sb, data)) {
-		printk(KERN_WARNING "usbfs: mount parameter error.\n");
-		return -EINVAL;
-	}
-
-	if (usbfs_mount)
-		update_sb(usbfs_mount->mnt_sb);
-
-	return 0;
-}
-
-static struct inode *usbfs_get_inode (struct super_block *sb, umode_t mode, dev_t dev)
-{
-	struct inode *inode = new_inode(sb);
-
-	if (inode) {
-		inode->i_ino = get_next_ino();
-		inode_init_owner(inode, NULL, mode);
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = &default_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &simple_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inc_nlink(inode);
-			break;
-		}
-	}
-	return inode; 
-}
-
-/* SMP-safe */
-static int usbfs_mknod (struct inode *dir, struct dentry *dentry, umode_t mode,
-			dev_t dev)
-{
-	struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev);
-	int error = -EPERM;
-
-	if (dentry->d_inode)
-		return -EEXIST;
-
-	if (inode) {
-		d_instantiate(dentry, inode);
-		dget(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, umode_t mode)
-{
-	int res;
-
-	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
-	res = usbfs_mknod (dir, dentry, mode, 0);
-	if (!res)
-		inc_nlink(dir);
-	return res;
-}
-
-static int usbfs_create (struct inode *dir, struct dentry *dentry, umode_t mode)
-{
-	mode = (mode & S_IALLUGO) | S_IFREG;
-	return usbfs_mknod (dir, dentry, mode, 0);
-}
-
-static inline int usbfs_positive (struct dentry *dentry)
-{
-	return dentry->d_inode && !d_unhashed(dentry);
-}
-
-static int usbfs_empty (struct dentry *dentry)
-{
-	struct list_head *list;
-
-	spin_lock(&dentry->d_lock);
-	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
-
-		spin_lock_nested(&de->d_lock, DENTRY_D_LOCK_NESTED);
-		if (usbfs_positive(de)) {
-			spin_unlock(&de->d_lock);
-			spin_unlock(&dentry->d_lock);
-			return 0;
-		}
-		spin_unlock(&de->d_lock);
-	}
-	spin_unlock(&dentry->d_lock);
-	return 1;
-}
-
-static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	mutex_lock(&inode->i_mutex);
-	drop_nlink(dentry->d_inode);
-	dput(dentry);
-	mutex_unlock(&inode->i_mutex);
-	d_delete(dentry);
-	return 0;
-}
-
-static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
-{
-	int error = -ENOTEMPTY;
-	struct inode * inode = dentry->d_inode;
-
-	mutex_lock(&inode->i_mutex);
-	dentry_unhash(dentry);
-	if (usbfs_empty(dentry)) {
-		dont_mount(dentry);
-		drop_nlink(dentry->d_inode);
-		drop_nlink(dentry->d_inode);
-		dput(dentry);
-		inode->i_flags |= S_DEAD;
-		drop_nlink(dir);
-		error = 0;
-	}
-	mutex_unlock(&inode->i_mutex);
-	if (!error)
-		d_delete(dentry);
-	return error;
-}
-
-
-/* default file operations */
-static ssize_t default_read_file (struct file *file, char __user *buf,
-				  size_t count, loff_t *ppos)
-{
-	return 0;
-}
-
-static ssize_t default_write_file (struct file *file, const char __user *buf,
-				   size_t count, loff_t *ppos)
-{
-	return count;
-}
-
-static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
-{
-	loff_t retval = -EINVAL;
-
-	mutex_lock(&file->f_path.dentry->d_inode->i_mutex);
-	switch(orig) {
-	case 0:
-		if (offset > 0) {
-			file->f_pos = offset;
-			retval = file->f_pos;
-		} 
-		break;
-	case 1:
-		if ((offset + file->f_pos) > 0) {
-			file->f_pos += offset;
-			retval = file->f_pos;
-		} 
-		break;
-	default:
-		break;
-	}
-	mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
-	return retval;
-}
-
-static const struct file_operations default_file_operations = {
-	.read =		default_read_file,
-	.write =	default_write_file,
-	.open =		simple_open,
-	.llseek =	default_file_lseek,
-};
-
-static const struct super_operations usbfs_ops = {
-	.statfs =	simple_statfs,
-	.drop_inode =	generic_delete_inode,
-	.remount_fs =	remount,
-	.show_options = usbfs_show_options,
-};
-
-static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *inode;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = USBDEVICE_SUPER_MAGIC;
-	sb->s_op = &usbfs_ops;
-	sb->s_time_gran = 1;
-	inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
-	sb->s_root = d_make_root(inode);
-	if (!sb->s_root) {
-		dbg("%s: could not get root dentry!",__func__);
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-/*
- * fs_create_by_name - create a file, given a name
- * @name:	name of file
- * @mode:	type of file
- * @parent:	dentry of directory to create it in
- * @dentry:	resulting dentry of file
- *
- * This function handles both regular files and directories.
- */
-static int fs_create_by_name (const char *name, umode_t mode,
-			      struct dentry *parent, struct dentry **dentry)
-{
-	int error = 0;
-
-	/* If the parent is not specified, we create it in the root.
-	 * We need the root dentry to do this, which is in the super 
-	 * block. A pointer to that is in the struct vfsmount that we
-	 * have around.
-	 */
-	if (!parent ) {
-		if (usbfs_mount)
-			parent = usbfs_mount->mnt_root;
-	}
-
-	if (!parent) {
-		dbg("Ah! can not find a parent!");
-		return -EFAULT;
-	}
-
-	*dentry = NULL;
-	mutex_lock(&parent->d_inode->i_mutex);
-	*dentry = lookup_one_len(name, parent, strlen(name));
-	if (!IS_ERR(*dentry)) {
-		if (S_ISDIR(mode))
-			error = usbfs_mkdir (parent->d_inode, *dentry, mode);
-		else 
-			error = usbfs_create (parent->d_inode, *dentry, mode);
-	} else
-		error = PTR_ERR(*dentry);
-	mutex_unlock(&parent->d_inode->i_mutex);
-
-	return error;
-}
-
-static struct dentry *fs_create_file (const char *name, umode_t mode,
-				      struct dentry *parent, void *data,
-				      const struct file_operations *fops,
-				      uid_t uid, gid_t gid)
-{
-	struct dentry *dentry;
-	int error;
-
-	dbg("creating file '%s'",name);
-
-	error = fs_create_by_name (name, mode, parent, &dentry);
-	if (error) {
-		dentry = NULL;
-	} else {
-		if (dentry->d_inode) {
-			if (data)
-				dentry->d_inode->i_private = data;
-			if (fops)
-				dentry->d_inode->i_fop = fops;
-			dentry->d_inode->i_uid = uid;
-			dentry->d_inode->i_gid = gid;
-		}
-	}
-
-	return dentry;
-}
-
-static void fs_remove_file (struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	
-	if (!parent || !parent->d_inode)
-		return;
-
-	mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT);
-	if (usbfs_positive(dentry)) {
-		if (dentry->d_inode) {
-			if (S_ISDIR(dentry->d_inode->i_mode))
-				usbfs_rmdir(parent->d_inode, dentry);
-			else
-				usbfs_unlink(parent->d_inode, dentry);
-		dput(dentry);
-		}
-	}
-	mutex_unlock(&parent->d_inode->i_mutex);
-}
-
-/* --------------------------------------------------------------------- */
-
-static struct dentry *usb_mount(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data)
-{
-	return mount_single(fs_type, flags, data, usbfs_fill_super);
-}
-
-static struct file_system_type usb_fs_type = {
-	.owner =	THIS_MODULE,
-	.name =		"usbfs",
-	.mount =	usb_mount,
-	.kill_sb =	kill_litter_super,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int create_special_files (void)
-{
-	struct dentry *parent;
-	int retval;
-
-	/* create the devices special file */
-	retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
-	if (retval) {
-		printk(KERN_ERR "Unable to get usbfs mount\n");
-		goto exit;
-	}
-
-	parent = usbfs_mount->mnt_root;
-	devices_usbfs_dentry = fs_create_file ("devices",
-					       listmode | S_IFREG, parent,
-					       NULL, &usbfs_devices_fops,
-					       listuid, listgid);
-	if (devices_usbfs_dentry == NULL) {
-		printk(KERN_ERR "Unable to create devices usbfs file\n");
-		retval = -ENODEV;
-		goto error_clean_mounts;
-	}
-
-	goto exit;
-	
-error_clean_mounts:
-	simple_release_fs(&usbfs_mount, &usbfs_mount_count);
-exit:
-	return retval;
-}
-
-static void remove_special_files (void)
-{
-	if (devices_usbfs_dentry)
-		fs_remove_file (devices_usbfs_dentry);
-	devices_usbfs_dentry = NULL;
-	simple_release_fs(&usbfs_mount, &usbfs_mount_count);
-}
-
-void usbfs_update_special (void)
-{
-	struct inode *inode;
-
-	if (devices_usbfs_dentry) {
-		inode = devices_usbfs_dentry->d_inode;
-		if (inode)
-			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	}
-}
-
-static void usbfs_add_bus(struct usb_bus *bus)
-{
-	struct dentry *parent;
-	char name[8];
-	int retval;
-
-	/* create the special files if this is the first bus added */
-	if (num_buses == 0) {
-		retval = create_special_files();
-		if (retval)
-			return;
-	}
-	++num_buses;
-
-	sprintf (name, "%03d", bus->busnum);
-
-	parent = usbfs_mount->mnt_root;
-	bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
-					    bus, NULL, busuid, busgid);
-	if (bus->usbfs_dentry == NULL) {
-		printk(KERN_ERR "Error creating usbfs bus entry\n");
-		return;
-	}
-}
-
-static void usbfs_remove_bus(struct usb_bus *bus)
-{
-	if (bus->usbfs_dentry) {
-		fs_remove_file (bus->usbfs_dentry);
-		bus->usbfs_dentry = NULL;
-	}
-
-	--num_buses;
-	if (num_buses <= 0) {
-		remove_special_files();
-		num_buses = 0;
-	}
-}
-
-static void usbfs_add_device(struct usb_device *dev)
-{
-	char name[8];
-	int i;
-	int i_size;
-
-	sprintf (name, "%03d", dev->devnum);
-	dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
-					    dev->bus->usbfs_dentry, dev,
-					    &usbdev_file_operations,
-					    devuid, devgid);
-	if (dev->usbfs_dentry == NULL) {
-		printk(KERN_ERR "Error creating usbfs device entry\n");
-		return;
-	}
-
-	/* Set the size of the device's file to be
-	 * equal to the size of the device descriptors. */
-	i_size = sizeof (struct usb_device_descriptor);
-	for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) {
-		struct usb_config_descriptor *config =
-			(struct usb_config_descriptor *)dev->rawdescriptors[i];
-		i_size += le16_to_cpu(config->wTotalLength);
-	}
-	if (dev->usbfs_dentry->d_inode)
-		dev->usbfs_dentry->d_inode->i_size = i_size;
-}
-
-static void usbfs_remove_device(struct usb_device *dev)
-{
-	if (dev->usbfs_dentry) {
-		fs_remove_file (dev->usbfs_dentry);
-		dev->usbfs_dentry = NULL;
-	}
-}
-
-static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
-{
-	switch (action) {
-	case USB_DEVICE_ADD:
-		usbfs_add_device(dev);
-		break;
-	case USB_DEVICE_REMOVE:
-		usbfs_remove_device(dev);
-		break;
-	case USB_BUS_ADD:
-		usbfs_add_bus(dev);
-		break;
-	case USB_BUS_REMOVE:
-		usbfs_remove_bus(dev);
-	}
-
-	usbfs_update_special();
-	usbfs_conn_disc_event();
-	return NOTIFY_OK;
-}
-
-static struct notifier_block usbfs_nb = {
-	.notifier_call = 	usbfs_notify,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct proc_dir_entry *usbdir = NULL;
-
-int __init usbfs_init(void)
-{
-	int retval;
-
-	retval = register_filesystem(&usb_fs_type);
-	if (retval)
-		return retval;
-
-	usb_register_notify(&usbfs_nb);
-
-	/* create mount point for usbfs */
-	usbdir = proc_mkdir("bus/usb", NULL);
-
-	return 0;
-}
-
-void usbfs_cleanup(void)
-{
-	usb_unregister_notify(&usbfs_nb);
-	unregister_filesystem(&usb_fs_type);
-	if (usbdir)
-		remove_proc_entry("bus/usb", NULL);
-}
-
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 4c65eb6..32d3adc 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -123,6 +123,9 @@
 	/* Guillemot Webcam Hercules Dualpix Exchange*/
 	{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
 
+	/* Midiman M-Audio Keystation 88es */
+	{ USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
+
 	/* M-Systems Flash Disk Pioneers */
 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index cd9b3a2..9d912bf 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -681,6 +681,27 @@
 EXPORT_SYMBOL_GPL(usb_unpoison_urb);
 
 /**
+ * usb_block_urb - reliably prevent further use of an URB
+ * @urb: pointer to URB to be blocked, may be NULL
+ *
+ * After the routine has run, attempts to resubmit the URB will fail
+ * with error -EPERM.  Thus even if the URB's completion handler always
+ * tries to resubmit, it will not succeed and the URB will become idle.
+ *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ */
+void usb_block_urb(struct urb *urb)
+{
+	if (!urb)
+		return;
+
+	atomic_inc(&urb->reject);
+}
+EXPORT_SYMBOL_GPL(usb_block_urb);
+
+/**
  * usb_kill_anchored_urbs - cancel transfer requests en masse
  * @anchor: anchor the requests are bound to
  *
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
new file mode 100644
index 0000000..8947b20
--- /dev/null
+++ b/drivers/usb/core/usb-acpi.c
@@ -0,0 +1,117 @@
+/*
+ * USB-ACPI glue code
+ *
+ * Copyright 2012 Red Hat <mjg@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ */
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/pci.h>
+#include <acpi/acpi_bus.h>
+
+#include "usb.h"
+
+static int usb_acpi_check_upc(struct usb_device *udev, acpi_handle handle)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *upc;
+	int ret = 0;
+
+	status = acpi_evaluate_object(handle, "_UPC", NULL, &buffer);
+
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	upc = buffer.pointer;
+
+	if (!upc || (upc->type != ACPI_TYPE_PACKAGE)
+		|| upc->package.count != 4) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (upc->package.elements[0].integer.value)
+		udev->removable = USB_DEVICE_REMOVABLE;
+	else
+		udev->removable = USB_DEVICE_FIXED;
+
+out:
+	kfree(upc);
+	return ret;
+}
+
+static int usb_acpi_check_pld(struct usb_device *udev, acpi_handle handle)
+{
+	acpi_status status;
+	struct acpi_pld pld;
+
+	status = acpi_get_physical_device_location(handle, &pld);
+
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (pld.user_visible)
+		udev->removable = USB_DEVICE_REMOVABLE;
+	else
+		udev->removable = USB_DEVICE_FIXED;
+
+	return 0;
+}
+
+static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
+{
+	struct usb_device *udev;
+	struct device *parent;
+	acpi_handle *parent_handle;
+
+	if (!is_usb_device(dev))
+		return -ENODEV;
+
+	udev = to_usb_device(dev);
+	parent = dev->parent;
+	parent_handle = DEVICE_ACPI_HANDLE(parent);
+
+	if (!parent_handle)
+		return -ENODEV;
+
+	*handle = acpi_get_child(parent_handle, udev->portnum);
+
+	if (!*handle)
+		return -ENODEV;
+
+	/*
+	 * PLD will tell us whether a port is removable to the user or
+	 * not. If we don't get an answer from PLD (it's not present
+	 * or it's malformed) then try to infer it from UPC. If a
+	 * device isn't connectable then it's probably not removable.
+	 */
+	if (usb_acpi_check_pld(udev, *handle) != 0)
+		usb_acpi_check_upc(udev, *handle);
+
+	return 0;
+}
+
+static struct acpi_bus_type usb_acpi_bus = {
+	.bus = &usb_bus_type,
+	.find_bridge = NULL,
+	.find_device = usb_acpi_find_device,
+};
+
+int usb_acpi_register(void)
+{
+	return register_acpi_bus_type(&usb_acpi_bus);
+}
+
+void usb_acpi_unregister(void)
+{
+	unregister_acpi_bus_type(&usb_acpi_bus);
+}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index c74ba7b..25d0c61 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1015,6 +1015,7 @@
 	if (retval)
 		goto out;
 
+	usb_acpi_register();
 	retval = bus_register(&usb_bus_type);
 	if (retval)
 		goto bus_register_failed;
@@ -1030,9 +1031,6 @@
 	retval = usb_devio_init();
 	if (retval)
 		goto usb_devio_init_failed;
-	retval = usbfs_init();
-	if (retval)
-		goto fs_init_failed;
 	retval = usb_hub_init();
 	if (retval)
 		goto hub_init_failed;
@@ -1042,8 +1040,6 @@
 
 	usb_hub_cleanup();
 hub_init_failed:
-	usbfs_cleanup();
-fs_init_failed:
 	usb_devio_cleanup();
 usb_devio_init_failed:
 	usb_deregister(&usbfs_driver);
@@ -1054,6 +1050,7 @@
 bus_notifier_failed:
 	bus_unregister(&usb_bus_type);
 bus_register_failed:
+	usb_acpi_unregister();
 	usb_debugfs_cleanup();
 out:
 	return retval;
@@ -1070,12 +1067,12 @@
 
 	usb_deregister_device_driver(&usb_generic_driver);
 	usb_major_cleanup();
-	usbfs_cleanup();
 	usb_deregister(&usbfs_driver);
 	usb_devio_cleanup();
 	usb_hub_cleanup();
 	bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
 	bus_unregister(&usb_bus_type);
+	usb_acpi_unregister();
 	usb_debugfs_cleanup();
 }
 
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 71648dc..5c5c538 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -156,3 +156,10 @@
 extern void usb_notify_add_bus(struct usb_bus *ubus);
 extern void usb_notify_remove_bus(struct usb_bus *ubus);
 
+#ifdef CONFIG_ACPI
+extern int usb_acpi_register(void);
+extern void usb_acpi_unregister(void);
+#else
+static inline int usb_acpi_register(void) { return 0; };
+static inline void usb_acpi_unregister(void) { };
+#endif
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index d8f741f..d13c60f4 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -4,7 +4,7 @@
 	select USB_OTG_UTILS
 	select USB_GADGET_DUALSPEED
 	select USB_GADGET_SUPERSPEED
-	select USB_XHCI_PLATFORM
+	select USB_XHCI_PLATFORM if USB_SUPPORT && USB_XHCI_HCD
 	help
 	  Say Y or M here if your system has a Dual Role SuperSpeed
 	  USB controller based on the DesignWare USB3 IP Core.
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 99b58d84..1040bdb 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -410,7 +410,6 @@
 	struct device		*dev = &pdev->dev;
 
 	int			ret = -ENOMEM;
-	int			irq;
 
 	void __iomem		*regs;
 	void			*mem;
@@ -425,15 +424,28 @@
 	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
 	dwc->mem = mem;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
-		dev_err(dev, "missing resource\n");
+		dev_err(dev, "missing IRQ\n");
 		return -ENODEV;
 	}
+	dwc->xhci_resources[1] = *res;
 
-	dwc->res = res;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "missing memory resource\n");
+		return -ENODEV;
+	}
+	dwc->xhci_resources[0] = *res;
+	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
+					DWC3_XHCI_REGS_END;
 
-	res = devm_request_mem_region(dev, res->start, resource_size(res),
+	 /*
+	  * Request memory region but exclude xHCI regs,
+	  * since it will be requested by the xhci-plat driver.
+	  */
+	res = devm_request_mem_region(dev, res->start + DWC3_GLOBALS_REGS_START,
+			resource_size(res) - DWC3_GLOBALS_REGS_START,
 			dev_name(dev));
 	if (!res) {
 		dev_err(dev, "can't request mem region\n");
@@ -446,19 +458,12 @@
 		return -ENOMEM;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(dev, "missing IRQ\n");
-		return -ENODEV;
-	}
-
 	spin_lock_init(&dwc->lock);
 	platform_set_drvdata(pdev, dwc);
 
 	dwc->regs	= regs;
 	dwc->regs_size	= resource_size(res);
 	dwc->dev	= dev;
-	dwc->irq	= irq;
 
 	if (!strncmp("super", maximum_speed, 5))
 		dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 6c7945b..f69c877 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -51,7 +51,9 @@
 #include <linux/usb/gadget.h>
 
 /* Global constants */
+#define DWC3_EP0_BOUNCE_SIZE	512
 #define DWC3_ENDPOINTS_NUM	32
+#define DWC3_XHCI_RESOURCES_NUM	2
 
 #define DWC3_EVENT_BUFFERS_SIZE	PAGE_SIZE
 #define DWC3_EVENT_TYPE_MASK	0xfe
@@ -75,6 +77,16 @@
 #define DWC3_GSNPSID_MASK	0xffff0000
 #define DWC3_GSNPSREV_MASK	0xffff
 
+/* DWC3 registers memory space boundries */
+#define DWC3_XHCI_REGS_START		0x0
+#define DWC3_XHCI_REGS_END		0x7fff
+#define DWC3_GLOBALS_REGS_START		0xc100
+#define DWC3_GLOBALS_REGS_END		0xc6ff
+#define DWC3_DEVICE_REGS_START		0xc700
+#define DWC3_DEVICE_REGS_END		0xcbff
+#define DWC3_OTG_REGS_START		0xcc00
+#define DWC3_OTG_REGS_END		0xccff
+
 /* Global Registers */
 #define DWC3_GSBUSCFG0		0xc100
 #define DWC3_GSBUSCFG1		0xc104
@@ -183,6 +195,7 @@
 #define DWC3_GHWPARAMS1_EN_PWROPT_CLK	1
 
 /* Device Configuration Register */
+#define DWC3_DCFG_LPM_CAP	(1 << 22)
 #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
 #define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
 
@@ -272,12 +285,14 @@
 #define DWC3_DGCMD_SET_ENDPOINT_NRDY	0x0c
 #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK	0x10
 
+#define DWC3_DGCMD_STATUS(n)		(((n) >> 15) & 1)
+#define DWC3_DGCMD_CMDACT		(1 << 10)
+
 /* 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_STATUS(x)		(((x) >> 15) & 1)
 #define DWC3_DEPCMD_HIPRI_FORCERM	(1 << 11)
 #define DWC3_DEPCMD_CMDACT		(1 << 10)
 #define DWC3_DEPCMD_CMDIOC		(1 << 8)
@@ -361,7 +376,6 @@
 	dma_addr_t		trb_pool_dma;
 	u32			free_slot;
 	u32			busy_slot;
-	const struct usb_endpoint_descriptor *desc;
 	const struct usb_ss_ep_comp_descriptor *comp_desc;
 	struct dwc3		*dwc;
 
@@ -561,6 +575,11 @@
  * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
  * @needs_fifo_resize: not all users might want fifo resizing, flag it
  * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes.
+ * @isoch_delay: wValue from Set Isochronous Delay request;
+ * @u2sel: parameter from Set SEL request.
+ * @u2pel: parameter from Set SEL request.
+ * @u1sel: parameter from Set SEL request.
+ * @u1pel: parameter from Set SEL request.
  * @ep0_next_event: hold the next expected event
  * @ep0state: state of endpoint zero
  * @link_state: link state
@@ -583,7 +602,7 @@
 	struct device		*dev;
 
 	struct platform_device	*xhci;
-	struct resource		*res;
+	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
 
 	struct dwc3_event_buffer **ev_buffs;
 	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
@@ -594,8 +613,6 @@
 	void __iomem		*regs;
 	size_t			regs_size;
 
-	int			irq;
-
 	u32			num_event_buffers;
 	u32			u1u2;
 	u32			maximum_speed;
@@ -609,6 +626,10 @@
 #define DWC3_REVISION_185A	0x5533185a
 #define DWC3_REVISION_188A	0x5533188a
 #define DWC3_REVISION_190A	0x5533190a
+#define DWC3_REVISION_200A	0x5533200a
+#define DWC3_REVISION_202A	0x5533202a
+#define DWC3_REVISION_210A	0x5533210a
+#define DWC3_REVISION_220A	0x5533220a
 
 	unsigned		is_selfpowered:1;
 	unsigned		three_stage_setup:1;
@@ -625,7 +646,14 @@
 	enum dwc3_link_state	link_state;
 	enum dwc3_device_state	dev_state;
 
+	u16			isoch_delay;
+	u16			u2sel;
+	u16			u2pel;
+	u8			u1sel;
+	u8			u1pel;
+
 	u8			speed;
+
 	void			*mem;
 
 	struct dwc3_hwparams	hwparams;
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index d7d9c0e..479dc04 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -49,7 +49,6 @@
 #include <linux/of.h>
 
 #include "core.h"
-#include "io.h"
 
 /*
  * All these registers belong to OMAP's Wrapper around the
@@ -143,6 +142,17 @@
 	u32			dma_status:1;
 };
 
+static inline u32 dwc3_omap_readl(void __iomem *base, u32 offset)
+{
+	return readl(base + offset);
+}
+
+static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value)
+{
+	writel(value, base + offset);
+}
+
+
 static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
 {
 	struct dwc3_omap	*omap = _omap;
@@ -150,7 +160,7 @@
 
 	spin_lock(&omap->lock);
 
-	reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1);
+	reg = dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_1);
 
 	if (reg & USBOTGSS_IRQ1_DMADISABLECLR) {
 		dev_dbg(omap->dev, "DMA Disable was Cleared\n");
@@ -184,10 +194,10 @@
 	if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL)
 		dev_dbg(omap->dev, "IDPULLUP Fall\n");
 
-	dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg);
+	dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg);
 
-	reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_0);
-	dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg);
+	reg = dwc3_omap_readl(omap->base, USBOTGSS_IRQSTATUS_0);
+	dwc3_omap_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg);
 
 	spin_unlock(&omap->lock);
 
@@ -270,7 +280,7 @@
 	omap->base	= base;
 	omap->dwc3	= dwc3;
 
-	reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
+	reg = dwc3_omap_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
 
 	utmi_mode = of_get_property(node, "utmi-mode", &size);
 	if (utmi_mode && size == sizeof(*utmi_mode)) {
@@ -293,10 +303,10 @@
 		}
 	}
 
-	dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg);
+	dwc3_omap_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg);
 
 	/* check the DMA Status */
-	reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);
+	reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
 	omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE);
 
 	/* Set No-Idle and No-Standby */
@@ -306,7 +316,7 @@
 	reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY)
 		| USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE));
 
-	dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg);
+	dwc3_omap_writel(omap->base, USBOTGSS_SYSCONFIG, reg);
 
 	ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0,
 			"dwc3-omap", omap);
@@ -318,7 +328,7 @@
 
 	/* enable all IRQs */
 	reg = USBOTGSS_IRQO_COREIRQ_ST;
-	dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg);
+	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg);
 
 	reg = (USBOTGSS_IRQ1_OEVT |
 			USBOTGSS_IRQ1_DRVVBUS_RISE |
@@ -330,7 +340,7 @@
 			USBOTGSS_IRQ1_DISCHRGVBUS_FALL |
 			USBOTGSS_IRQ1_IDPULLUP_FALL);
 
-	dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg);
+	dwc3_omap_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg);
 
 	ret = platform_device_add_resources(dwc3, pdev->resource,
 			pdev->num_resources);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 3584a16..9e8a3dc 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -179,7 +179,7 @@
 	int				ret;
 
 	spin_lock_irqsave(&dwc->lock, flags);
-	if (!dep->desc) {
+	if (!dep->endpoint.desc) {
 		dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
 				request, dep->name);
 		ret = -ESHUTDOWN;
@@ -261,6 +261,7 @@
 {
 	struct dwc3_ep		*dep;
 	u32			recip;
+	u32			reg;
 	u16			usb_status = 0;
 	__le16			*response_pkt;
 
@@ -268,10 +269,18 @@
 	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
+		 * LTM will be set once we know how to set this in HW.
 		 */
 		usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED;
+
+		if (dwc->speed == DWC3_DSTS_SUPERSPEED) {
+			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+			if (reg & DWC3_DCTL_INITU1ENA)
+				usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
+			if (reg & DWC3_DCTL_INITU2ENA)
+				usb_status |= 1 << USB_DEV_STAT_U2_ENABLED;
+		}
+
 		break;
 
 	case USB_RECIP_INTERFACE:
@@ -312,6 +321,7 @@
 	u32			recip;
 	u32			wValue;
 	u32			wIndex;
+	u32			reg;
 	int			ret;
 
 	wValue = le16_to_cpu(ctrl->wValue);
@@ -320,29 +330,43 @@
 	switch (recip) {
 	case USB_RECIP_DEVICE:
 
+		switch (wValue) {
+		case USB_DEVICE_REMOTE_WAKEUP:
+			break;
 		/*
 		 * 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:
+			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+			if (set)
+				reg |= DWC3_DCTL_INITU1ENA;
+			else
+				reg &= ~DWC3_DCTL_INITU1ENA;
+			dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 			break;
-		case USB_DEVICE_U1_ENABLE:
-			break;
+
 		case USB_DEVICE_U2_ENABLE:
+			if (dwc->dev_state != DWC3_CONFIGURED_STATE)
+				return -EINVAL;
+			if (dwc->speed != DWC3_DSTS_SUPERSPEED)
+				return -EINVAL;
+
+			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+			if (set)
+				reg |= DWC3_DCTL_INITU2ENA;
+			else
+				reg &= ~DWC3_DCTL_INITU2ENA;
+			dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 			break;
+
 		case USB_DEVICE_LTM_ENABLE:
+			return -EINVAL;
 			break;
 
 		case USB_DEVICE_TEST_MODE:
@@ -469,6 +493,107 @@
 	return ret;
 }
 
+static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req)
+{
+	struct dwc3_ep	*dep = to_dwc3_ep(ep);
+	struct dwc3	*dwc = dep->dwc;
+
+	u32		param = 0;
+	u32		reg;
+
+	struct timing {
+		u8	u1sel;
+		u8	u1pel;
+		u16	u2sel;
+		u16	u2pel;
+	} __packed timing;
+
+	int		ret;
+
+	memcpy(&timing, req->buf, sizeof(timing));
+
+	dwc->u1sel = timing.u1sel;
+	dwc->u1pel = timing.u1pel;
+	dwc->u2sel = timing.u2sel;
+	dwc->u2pel = timing.u2pel;
+
+	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+	if (reg & DWC3_DCTL_INITU2ENA)
+		param = dwc->u2pel;
+	if (reg & DWC3_DCTL_INITU1ENA)
+		param = dwc->u1pel;
+
+	/*
+	 * According to Synopsys Databook, if parameter is
+	 * greater than 125, a value of zero should be
+	 * programmed in the register.
+	 */
+	if (param > 125)
+		param = 0;
+
+	/* now that we have the time, issue DGCMD Set Sel */
+	ret = dwc3_send_gadget_generic_command(dwc,
+			DWC3_DGCMD_SET_PERIODIC_PAR, param);
+	WARN_ON(ret < 0);
+}
+
+static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
+{
+	struct dwc3_ep	*dep;
+	u16		wLength;
+	u16		wValue;
+
+	if (dwc->dev_state == DWC3_DEFAULT_STATE)
+		return -EINVAL;
+
+	wValue = le16_to_cpu(ctrl->wValue);
+	wLength = le16_to_cpu(ctrl->wLength);
+
+	if (wLength != 6) {
+		dev_err(dwc->dev, "Set SEL should be 6 bytes, got %d\n",
+				wLength);
+		return -EINVAL;
+	}
+
+	/*
+	 * To handle Set SEL we need to receive 6 bytes from Host. So let's
+	 * queue a usb_request for 6 bytes.
+	 *
+	 * Remember, though, this controller can't handle non-wMaxPacketSize
+	 * aligned transfers on the OUT direction, so we queue a request for
+	 * wMaxPacketSize instead.
+	 */
+	dep = dwc->eps[0];
+	dwc->ep0_usb_req.dep = dep;
+	dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket;
+	dwc->ep0_usb_req.request.buf = dwc->setup_buf;
+	dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl;
+
+	return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
+}
+
+static int dwc3_ep0_set_isoch_delay(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
+{
+	u16		wLength;
+	u16		wValue;
+	u16		wIndex;
+
+	wValue = le16_to_cpu(ctrl->wValue);
+	wLength = le16_to_cpu(ctrl->wLength);
+	wIndex = le16_to_cpu(ctrl->wIndex);
+
+	if (wIndex || wLength)
+		return -EINVAL;
+
+	/*
+	 * REVISIT It's unclear from Databook what to do with this
+	 * value. For now, just cache it.
+	 */
+	dwc->isoch_delay = wValue;
+
+	return 0;
+}
+
 static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 {
 	int ret;
@@ -494,6 +619,14 @@
 		dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");
 		ret = dwc3_ep0_set_config(dwc, ctrl);
 		break;
+	case USB_REQ_SET_SEL:
+		dev_vdbg(dwc->dev, "USB_REQ_SET_SEL\n");
+		ret = dwc3_ep0_set_sel(dwc, ctrl);
+		break;
+	case USB_REQ_SET_ISOCH_DELAY:
+		dev_vdbg(dwc->dev, "USB_REQ_SET_ISOCH_DELAY\n");
+		ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
+		break;
 	default:
 		dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
 		ret = dwc3_ep0_delegate_req(dwc, ctrl);
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 5255fe97..3df1a19 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -178,8 +178,8 @@
 		if (!(dep->flags & DWC3_EP_ENABLED))
 			continue;
 
-		if (usb_endpoint_xfer_bulk(dep->desc)
-				|| usb_endpoint_xfer_isoc(dep->desc))
+		if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
+				|| usb_endpoint_xfer_isoc(dep->endpoint.desc))
 			mult = 3;
 
 		/*
@@ -229,7 +229,7 @@
 		 * completed (not the LINK TRB).
 		 */
 		if (((dep->busy_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
-				usb_endpoint_xfer_isoc(dep->desc))
+				usb_endpoint_xfer_isoc(dep->endpoint.desc))
 			dep->busy_slot++;
 	}
 	list_del(&req->list);
@@ -276,6 +276,33 @@
 	}
 }
 
+int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param)
+{
+	u32		timeout = 500;
+	u32		reg;
+
+	dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
+	dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
+
+	do {
+		reg = dwc3_readl(dwc->regs, DWC3_DGCMD);
+		if (!(reg & DWC3_DGCMD_CMDACT)) {
+			dev_vdbg(dwc->dev, "Command Complete --> %d\n",
+					DWC3_DGCMD_STATUS(reg));
+			return 0;
+		}
+
+		/*
+		 * We can't sleep here, because it's also called from
+		 * interrupt context.
+		 */
+		timeout--;
+		if (!timeout)
+			return -ETIMEDOUT;
+		udelay(1);
+	} while (1);
+}
+
 int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
 {
@@ -470,7 +497,7 @@
 		if (ret)
 			return ret;
 
-		dep->desc = desc;
+		dep->endpoint.desc = desc;
 		dep->comp_desc = comp_desc;
 		dep->type = usb_endpoint_type(desc);
 		dep->flags |= DWC3_EP_ENABLED;
@@ -533,7 +560,6 @@
 	dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
 
 	dep->stream_capable = false;
-	dep->desc = NULL;
 	dep->endpoint.desc = NULL;
 	dep->comp_desc = NULL;
 	dep->type = 0;
@@ -694,7 +720,7 @@
 
 	/* Skip the LINK-TRB on ISOC */
 	if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
-			usb_endpoint_xfer_isoc(dep->desc))
+			usb_endpoint_xfer_isoc(dep->endpoint.desc))
 		return;
 
 	if (!req->trb) {
@@ -707,7 +733,7 @@
 	trb->bpl = lower_32_bits(dma);
 	trb->bph = upper_32_bits(dma);
 
-	switch (usb_endpoint_type(dep->desc)) {
+	switch (usb_endpoint_type(dep->endpoint.desc)) {
 	case USB_ENDPOINT_XFER_CONTROL:
 		trb->ctrl = DWC3_TRBCTL_CONTROL_SETUP;
 		break;
@@ -732,7 +758,7 @@
 		BUG();
 	}
 
-	if (usb_endpoint_xfer_isoc(dep->desc)) {
+	if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
 		trb->ctrl |= DWC3_TRB_CTRL_CSP;
 	} else {
@@ -743,7 +769,7 @@
 			trb->ctrl |= DWC3_TRB_CTRL_LST;
 	}
 
-	if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
+	if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable)
 		trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);
 
 	trb->ctrl |= DWC3_TRB_CTRL_HWO;
@@ -771,7 +797,7 @@
 	trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
 
 	/* Can't wrap around on a non-isoc EP since there's no link TRB */
-	if (!usb_endpoint_xfer_isoc(dep->desc)) {
+	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 		max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK);
 		if (trbs_left > max)
 			trbs_left = max;
@@ -797,7 +823,7 @@
 		 * 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)) {
+		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 			dep->busy_slot = 1;
 			dep->free_slot = 1;
 		} else {
@@ -807,7 +833,7 @@
 	}
 
 	/* The last TRB is a link TRB, not used for xfer */
-	if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc))
+	if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc))
 		return;
 
 	list_for_each_entry_safe(req, n, &dep->request_list, list) {
@@ -930,10 +956,12 @@
 	}
 
 	dep->flags |= DWC3_EP_BUSY;
-	dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
-			dep->number);
 
-	WARN_ON_ONCE(!dep->res_trans_idx);
+	if (start_new) {
+		dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
+				dep->number);
+		WARN_ON_ONCE(!dep->res_trans_idx);
+	}
 
 	return 0;
 }
@@ -967,28 +995,37 @@
 
 	list_add_tail(&req->list, &dep->request_list);
 
+	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && (dep->flags & DWC3_EP_BUSY))
+		dep->flags |= DWC3_EP_PENDING_REQUEST;
+
 	/*
-	 * 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.
+	 * There are two special cases:
 	 *
-	 * 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.
+	 * 1. 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.
+	 *
+	 * 2. XferInProgress on Isoc EP with an active transfer. We need to
+	 *    kick the transfer here after queuing a request, otherwise the
+	 *    core may not see the modified TRB(s).
 	 */
 	if (dep->flags & DWC3_EP_PENDING_REQUEST) {
-		int ret;
-		int start_trans;
+		int	ret;
+		int	start_trans = 1;
+		u8	trans_idx = dep->res_trans_idx;
 
-		start_trans = 1;
-		if (usb_endpoint_xfer_isoc(dep->desc) &&
-				(dep->flags & DWC3_EP_BUSY))
+		if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+				(dep->flags & DWC3_EP_BUSY)) {
 			start_trans = 0;
+			WARN_ON_ONCE(!trans_idx);
+		} else {
+			trans_idx = 0;
+		}
 
-		ret = __dwc3_gadget_kick_transfer(dep, 0, start_trans);
+		ret = __dwc3_gadget_kick_transfer(dep, trans_idx, start_trans);
 		if (ret && ret != -EBUSY) {
 			struct dwc3	*dwc = dep->dwc;
 
@@ -1011,7 +1048,7 @@
 
 	int				ret;
 
-	if (!dep->desc) {
+	if (!dep->endpoint.desc) {
 		dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
 				request, ep->name);
 		return -ESHUTDOWN;
@@ -1125,7 +1162,7 @@
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	if (usb_endpoint_xfer_isoc(dep->desc)) {
+	if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 		dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);
 		ret = -EINVAL;
 		goto out;
@@ -1356,7 +1393,24 @@
 
 	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
 	reg &= ~(DWC3_DCFG_SPEED_MASK);
-	reg |= dwc->maximum_speed;
+
+	/**
+	 * WORKAROUND: DWC3 revision < 2.20a have an issue
+	 * which would cause metastability state on Run/Stop
+	 * bit if we try to force the IP to USB2-only mode.
+	 *
+	 * Because of that, we cannot configure the IP to any
+	 * speed other than the SuperSpeed
+	 *
+	 * Refers to:
+	 *
+	 * STAR#9000525659: Clock Domain Crossing on DCTL in
+	 * USB 2.0 Mode
+	 */
+	if (dwc->revision < DWC3_REVISION_220A)
+		reg |= DWC3_DCFG_SUPERSPEED;
+	else
+		reg |= dwc->maximum_speed;
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
 	dwc->start_config_issued = false;
@@ -1681,7 +1735,7 @@
 	case DWC3_DEPEVT_XFERCOMPLETE:
 		dep->res_trans_idx = 0;
 
-		if (usb_endpoint_xfer_isoc(dep->desc)) {
+		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 			dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n",
 					dep->name);
 			return;
@@ -1690,7 +1744,7 @@
 		dwc3_endpoint_transfer_complete(dwc, dep, event, 1);
 		break;
 	case DWC3_DEPEVT_XFERINPROGRESS:
-		if (!usb_endpoint_xfer_isoc(dep->desc)) {
+		if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 			dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",
 					dep->name);
 			return;
@@ -1699,7 +1753,7 @@
 		dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
 		break;
 	case DWC3_DEPEVT_XFERNOTREADY:
-		if (usb_endpoint_xfer_isoc(dep->desc)) {
+		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 			dwc3_gadget_start_isoc(dwc, dep, event);
 		} else {
 			int ret;
@@ -1720,7 +1774,7 @@
 
 		break;
 	case DWC3_DEPEVT_STREAMEVT:
-		if (!usb_endpoint_xfer_bulk(dep->desc)) {
+		if (!usb_endpoint_xfer_bulk(dep->endpoint.desc)) {
 			dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
 					dep->name);
 			return;
@@ -1916,6 +1970,7 @@
 
 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 	reg &= ~DWC3_DCTL_TSTCTRL_MASK;
+	reg &= ~(DWC3_DCTL_INITU1ENA | DWC3_DCTL_INITU2ENA);
 	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 	dwc->test_mode = false;
 
@@ -2263,8 +2318,7 @@
 		goto err1;
 	}
 
-	dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2,
-			GFP_KERNEL);
+	dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL);
 	if (!dwc->setup_buf) {
 		dev_err(dwc->dev, "failed to allocate setup buffer\n");
 		ret = -ENOMEM;
@@ -2272,7 +2326,8 @@
 	}
 
 	dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
-			512, &dwc->ep0_bounce_addr, GFP_KERNEL);
+			DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
+			GFP_KERNEL);
 	if (!dwc->ep0_bounce) {
 		dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
 		ret = -ENOMEM;
@@ -2313,6 +2368,14 @@
 		goto err5;
 	}
 
+	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+	reg |= DWC3_DCFG_LPM_CAP;
+	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+
+	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+	reg |= DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA;
+	dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+
 	/* Enable all but Start and End of Frame IRQs */
 	reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN |
 			DWC3_DEVTEN_EVNTOVERFLOWEN |
@@ -2351,8 +2414,8 @@
 	dwc3_gadget_free_endpoints(dwc);
 
 err4:
-	dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
-			dwc->ep0_bounce_addr);
+	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 err3:
 	kfree(dwc->setup_buf);
@@ -2381,8 +2444,8 @@
 
 	dwc3_gadget_free_endpoints(dwc);
 
-	dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
-			dwc->ep0_bounce_addr);
+	dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+			dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 	kfree(dwc->setup_buf);
 
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index a860008..95ef6a2 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -111,6 +111,7 @@
 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);
+int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param);
 
 /**
  * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index b108d18..56a6234 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -39,15 +39,6 @@
 
 #include "core.h"
 
-static struct resource generic_resources[] = {
-	{
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.flags = IORESOURCE_MEM,
-	},
-};
-
 int dwc3_host_init(struct dwc3 *dwc)
 {
 	struct platform_device	*xhci;
@@ -68,14 +59,8 @@
 
 	dwc->xhci = xhci;
 
-	/* setup resources */
-	generic_resources[0].start = dwc->irq;
-
-	generic_resources[1].start = dwc->res->start;
-	generic_resources[1].end = dwc->res->start + 0x7fff;
-
-	ret = platform_device_add_resources(xhci, generic_resources,
-			ARRAY_SIZE(generic_resources));
+	ret = platform_device_add_resources(xhci, dwc->xhci_resources,
+						DWC3_XHCI_RESOURCES_NUM);
 	if (ret) {
 		dev_err(dwc->dev, "couldn't add resources to xHCI device\n");
 		goto err1;
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 071d561..a50f76b 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -41,14 +41,26 @@
 
 #include <linux/io.h>
 
+#include "core.h"
+
 static inline u32 dwc3_readl(void __iomem *base, u32 offset)
 {
-	return readl(base + offset);
+	/*
+	 * We requested the mem region starting from the Globals address
+	 * space, see dwc3_probe in core.c.
+	 * However, the offsets are given starting from xHCI address space.
+	 */
+	return readl(base + (offset - DWC3_GLOBALS_REGS_START));
 }
 
 static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
 {
-	writel(value, base + offset);
+	/*
+	 * We requested the mem region starting from the Globals address
+	 * space, see dwc3_probe in core.c.
+	 * However, the offsets are given starting from xHCI address space.
+	 */
+	writel(value, base + (offset - DWC3_GLOBALS_REGS_START));
 }
 
 #endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 2633f75..11c2b21 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -123,13 +123,7 @@
 #   - discrete ones (including all PCI-only controllers)
 #   - debug/dummy gadget+hcd is last.
 #
-choice
-	prompt "USB Peripheral Controller"
-	help
-	   A USB device uses a controller to talk to its host.
-	   Systems should have only one such upstream link.
-	   Many controller drivers are platform-specific; these
-	   often need board-specific hooks.
+menu "USB Peripheral Controller"
 
 #
 # Integrated controllers
@@ -147,6 +141,17 @@
 	   dynamically linked module called "at91_udc" and force all
 	   gadget drivers to also be dynamically linked.
 
+config USB_LPC32XX
+	tristate "LPC32XX USB Peripheral Controller"
+	depends on ARCH_LPC32XX
+	select USB_ISP1301
+	help
+	   This option selects the USB device controller in the LPC32xx SoC.
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "lpc32xx_udc" and force all
+	   gadget drivers to also be dynamically linked.
+
 config USB_ATMEL_USBA
 	tristate "Atmel USBA"
 	select USB_GADGET_DUALSPEED
@@ -161,7 +166,7 @@
 	select USB_GADGET_DUALSPEED
 	select USB_FSL_MPH_DR_OF if OF
 	help
-	   Some of Freescale PowerPC processors have a High Speed
+	   Some of Freescale PowerPC and i.MX processors have a High Speed
 	   Dual-Role(DR) USB controller, which supports device mode.
 
 	   The number of programmable endpoints is different through
@@ -373,18 +378,6 @@
 	   Set CONFIG_USB_GADGET to "m" to build this driver as a
 	   dynamically linked module called "fsl_qe_udc".
 
-config USB_CI13XXX_PCI
-	tristate "MIPS USB CI13xxx PCI UDC"
-	depends on PCI
-	select USB_GADGET_DUALSPEED
-	help
-	  MIPS USB IP core family device controller
-	  Currently it only supports IP part number CI13412
-
-	  Say "y" to link the driver statically, or "m" to build a
-	  dynamically linked module called "ci13xxx_udc" and force all
-	  gadget drivers to also be dynamically linked.
-
 config USB_NET2272
 	tristate "PLX NET2272"
 	select USB_GADGET_DUALSPEED
@@ -438,22 +431,6 @@
 	   dynamically linked module called "goku_udc" and to force all
 	   gadget drivers to also be dynamically linked.
 
-config USB_LANGWELL
-	tristate "Intel Langwell USB Device Controller"
-	depends on PCI
-	depends on !PHYS_ADDR_T_64BIT
-	select USB_GADGET_DUALSPEED
-	help
-	   Intel Langwell USB Device Controller is a High-Speed USB
-	   On-The-Go device controller.
-
-	   The number of programmable endpoints is different through
-	   controller revision.
-
-	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "langwell_udc" and force all
-	   gadget drivers to also be dynamically linked.
-
 config USB_EG20T
 	tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"
 	depends on PCI
@@ -477,23 +454,6 @@
 	  ML7213/ML7831 is companion chip for Intel Atom E6xx series.
 	  ML7213/ML7831 is completely compatible for Intel EG20T PCH.
 
-config USB_CI13XXX_MSM
-	tristate "MIPS USB CI13xxx for MSM"
-	depends on ARCH_MSM
-	select USB_GADGET_DUALSPEED
-	select USB_MSM_OTG
-	help
-	  MSM SoC has chipidea USB controller.  This driver uses
-	  ci13xxx_udc core.
-	  This driver depends on OTG driver for PHY initialization,
-	  clock management, powering up VBUS, and power management.
-	  This driver is not supported on boards like trout which
-	  has an external PHY.
-
-	  Say "y" to link the driver statically, or "m" to build a
-	  dynamically linked module called "ci13xxx_msm" and force all
-	  gadget drivers to also be dynamically linked.
-
 #
 # LAST -- dummy/emulated controller
 #
@@ -525,7 +485,7 @@
 # NOTE:  Please keep dummy_hcd LAST so that "real hardware" appears
 # first and will be selected by default.
 
-endchoice
+endmenu
 
 # Selected by UDC drivers that support high-speed operation.
 config USB_GADGET_DUALSPEED
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index b7f6eef..51019aa 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -22,14 +22,12 @@
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
 obj-$(CONFIG_USB_R8A66597)	+= r8a66597-udc.o
 obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
-obj-$(CONFIG_USB_CI13XXX_PCI)	+= ci13xxx_pci.o
 obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
 obj-$(CONFIG_USB_S3C_HSUDC)	+= s3c-hsudc.o
-obj-$(CONFIG_USB_LANGWELL)	+= langwell_udc.o
+obj-$(CONFIG_USB_LPC32XX)	+= lpc32xx_udc.o
 obj-$(CONFIG_USB_EG20T)		+= pch_udc.o
 obj-$(CONFIG_USB_MV_UDC)	+= mv_udc.o
 mv_udc-y			:= mv_udc_core.o
-obj-$(CONFIG_USB_CI13XXX_MSM)	+= ci13xxx_msm.o
 obj-$(CONFIG_USB_FUSB300)	+= fusb300_udc.o
 
 #
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index 7777927..187d211 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -333,7 +333,7 @@
 		return -ESHUTDOWN;
 
 	spin_lock_irqsave(&dev->lock, iflags);
-	ep->desc = desc;
+	ep->ep.desc = desc;
 
 	ep->halted = 0;
 
@@ -442,7 +442,6 @@
 	u32		tmp;
 
 	VDBG(ep->dev, "ep-%d reset\n", ep->num);
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->ep.ops = &udc_ep_ops;
 	INIT_LIST_HEAD(&ep->queue);
@@ -489,7 +488,7 @@
 		return -EINVAL;
 
 	ep = container_of(usbep, struct udc_ep, ep);
-	if (usbep->name == ep0_string || !ep->desc)
+	if (usbep->name == ep0_string || !ep->ep.desc)
 		return -EINVAL;
 
 	DBG(ep->dev, "Disable ep-%d\n", ep->num);
@@ -1066,7 +1065,7 @@
 		return -EINVAL;
 
 	ep = container_of(usbep, struct udc_ep, ep);
-	if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
+	if (!ep->ep.desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
 		return -EINVAL;
 
 	VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in);
@@ -1257,7 +1256,7 @@
 	unsigned long		iflags;
 
 	ep = container_of(usbep, struct udc_ep, ep);
-	if (!usbep || !usbreq || (!ep->desc && (ep->num != 0
+	if (!usbep || !usbreq || (!ep->ep.desc && (ep->num != 0
 				&& ep->num != UDC_EP0OUT_IX)))
 		return -EINVAL;
 
@@ -1317,7 +1316,7 @@
 	pr_debug("set_halt %s: halt=%d\n", usbep->name, halt);
 
 	ep = container_of(usbep, struct udc_ep, ep);
-	if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
+	if (!ep->ep.desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
 		return -EINVAL;
 	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
 		return -ESHUTDOWN;
@@ -1539,7 +1538,7 @@
 		 * disabling ep interrupts when ENUM interrupt occurs but ep is
 		 * not enabled by gadget driver
 		 */
-		if (!ep->desc)
+		if (!ep->ep.desc)
 			ep_init(dev->regs, ep);
 
 		if (use_dma) {
@@ -3402,19 +3401,7 @@
 	.remove =	udc_pci_remove,
 };
 
-/* Inits driver */
-static int __init init(void)
-{
-	return pci_register_driver(&udc_pci_driver);
-}
-module_init(init);
-
-/* Cleans driver */
-static void __exit cleanup(void)
-{
-	pci_unregister_driver(&udc_pci_driver);
-}
-module_exit(cleanup);
+module_pci_driver(udc_pci_driver);
 
 MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION);
 MODULE_AUTHOR("Thomas Dahlmann");
diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h
index f87e29c..14af87d 100644
--- a/drivers/usb/gadget/amd5536udc.h
+++ b/drivers/usb/gadget/amd5536udc.h
@@ -512,7 +512,6 @@
 
 	/* queue for requests */
 	struct list_head		queue;
-	const struct usb_endpoint_descriptor	*desc;
 	unsigned			halted;
 	unsigned			cancel_transfer;
 	unsigned			num : 5,
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 9d7bcd9..1a4430f 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -212,7 +212,7 @@
 	if (udc->enabled && udc->vbus) {
 		proc_ep_show(s, &udc->ep[0]);
 		list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
-			if (ep->desc)
+			if (ep->ep.desc)
 				proc_ep_show(s, ep);
 		}
 	}
@@ -475,7 +475,7 @@
 	unsigned long	flags;
 
 	if (!_ep || !ep
-			|| !desc || ep->desc
+			|| !desc || ep->ep.desc
 			|| _ep->name == ep0name
 			|| desc->bDescriptorType != USB_DT_ENDPOINT
 			|| (maxpacket = usb_endpoint_maxp(desc)) == 0
@@ -530,7 +530,7 @@
 	tmp |= AT91_UDP_EPEDS;
 	__raw_writel(tmp, ep->creg);
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->ep.maxpacket = maxpacket;
 
 	/*
@@ -558,7 +558,6 @@
 	nuke(ep, -ESHUTDOWN);
 
 	/* restore the endpoint's pristine config */
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->ep.maxpacket = ep->maxpacket;
 
@@ -618,7 +617,7 @@
 		return -EINVAL;
 	}
 
-	if (!_ep || (!ep->desc && ep->ep.name != ep0name)) {
+	if (!_ep || (!ep->ep.desc && ep->ep.name != ep0name)) {
 		DBG("invalid ep\n");
 		return -EINVAL;
 	}
@@ -833,7 +832,7 @@
 
 		if (i != 0)
 			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
-		ep->desc = NULL;
+		ep->ep.desc = NULL;
 		ep->stopped = 0;
 		ep->fifo_bank = 0;
 		ep->ep.maxpacket = ep->maxpacket;
@@ -978,18 +977,18 @@
 	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 int at91_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
+static int at91_stop(struct usb_gadget *gadget,
+		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,
+	.udc_start		= at91_start,
+	.udc_stop		= at91_stop,
 
 	/*
 	 * VBUS-powered devices may also also want to support bigger
@@ -1172,7 +1171,7 @@
 			| USB_REQ_GET_STATUS:
 		tmp = w_index & USB_ENDPOINT_NUMBER_MASK;
 		ep = &udc->ep[tmp];
-		if (tmp >= NUM_ENDPOINTS || (tmp && !ep->desc))
+		if (tmp >= NUM_ENDPOINTS || (tmp && !ep->ep.desc))
 			goto stall;
 
 		if (tmp) {
@@ -1197,7 +1196,7 @@
 		ep = &udc->ep[tmp];
 		if (w_value != USB_ENDPOINT_HALT || tmp >= NUM_ENDPOINTS)
 			goto stall;
-		if (!ep->desc || ep->is_iso)
+		if (!ep->ep.desc || ep->is_iso)
 			goto stall;
 		if ((w_index & USB_DIR_IN)) {
 			if (!ep->is_in)
@@ -1218,7 +1217,7 @@
 			goto stall;
 		if (tmp == 0)
 			goto succeed;
-		if (!ep->desc || ep->is_iso)
+		if (!ep->ep.desc || ep->is_iso)
 			goto stall;
 		if ((w_index & USB_DIR_IN)) {
 			if (!ep->is_in)
@@ -1627,66 +1626,34 @@
 		schedule_work(&udc->vbus_timer_work);
 }
 
-static int at91_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
+static int at91_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	struct at91_udc	*udc = &controller;
-	int		retval;
-	unsigned long	flags;
+	struct at91_udc	*udc;
 
-	if (!driver
-			|| driver->max_speed < USB_SPEED_FULL
-			|| !bind
-			|| !driver->setup) {
-		DBG("bad parameter.\n");
-		return -EINVAL;
-	}
-
-	if (udc->driver) {
-		DBG("UDC already has a gadget driver\n");
-		return -EBUSY;
-	}
-
+	udc = container_of(gadget, struct at91_udc, gadget);
 	udc->driver = driver;
 	udc->gadget.dev.driver = &driver->driver;
 	dev_set_drvdata(&udc->gadget.dev, &driver->driver);
 	udc->enabled = 1;
 	udc->selfpowered = 1;
 
-	retval = bind(&udc->gadget);
-	if (retval) {
-		DBG("bind() returned %d\n", retval);
-		udc->driver = NULL;
-		udc->gadget.dev.driver = NULL;
-		dev_set_drvdata(&udc->gadget.dev, NULL);
-		udc->enabled = 0;
-		udc->selfpowered = 0;
-		return retval;
-	}
-
-	spin_lock_irqsave(&udc->lock, flags);
-	pullup(udc, 1);
-	spin_unlock_irqrestore(&udc->lock, flags);
-
 	DBG("bound to %s\n", driver->driver.name);
 	return 0;
 }
 
-static int at91_stop(struct usb_gadget_driver *driver)
+static int at91_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	struct at91_udc *udc = &controller;
+	struct at91_udc *udc;
 	unsigned long	flags;
 
-	if (!driver || driver != udc->driver || !driver->unbind)
-		return -EINVAL;
-
+	udc = container_of(gadget, struct at91_udc, gadget);
 	spin_lock_irqsave(&udc->lock, flags);
 	udc->enabled = 0;
 	at91_udp_write(udc, AT91_UDP_IDR, ~0);
-	pullup(udc, 0);
 	spin_unlock_irqrestore(&udc->lock, flags);
 
-	driver->unbind(&udc->gadget);
 	udc->gadget.dev.driver = NULL;
 	dev_set_drvdata(&udc->gadget.dev, NULL);
 	udc->driver = NULL;
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index 3c0315b..e647d1c 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -105,9 +105,6 @@
 	unsigned			is_in:1;
 	unsigned			is_iso:1;
 	unsigned			fifo_bank:1;
-
-	const struct usb_endpoint_descriptor
-					*desc;
 };
 
 /*
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 9f98508..e23bf79 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -599,13 +599,13 @@
 
 	spin_lock_irqsave(&ep->udc->lock, flags);
 
-	if (ep->desc) {
+	if (ep->ep.desc) {
 		spin_unlock_irqrestore(&ep->udc->lock, flags);
 		DBG(DBG_ERR, "ep%d already enabled\n", ep->index);
 		return -EBUSY;
 	}
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->ep.maxpacket = maxpacket;
 
 	usba_ep_writel(ep, CFG, ept_cfg);
@@ -647,7 +647,7 @@
 
 	spin_lock_irqsave(&udc->lock, flags);
 
-	if (!ep->desc) {
+	if (!ep->ep.desc) {
 		spin_unlock_irqrestore(&udc->lock, flags);
 		/* REVISIT because this driver disables endpoints in
 		 * reset_all_endpoints() before calling disconnect(),
@@ -658,7 +658,6 @@
 					ep->ep.name);
 		return -EINVAL;
 	}
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 
 	list_splice_init(&ep->queue, &req_list);
@@ -752,7 +751,7 @@
 	 */
 	ret = -ESHUTDOWN;
 	spin_lock_irqsave(&udc->lock, flags);
-	if (ep->desc) {
+	if (ep->ep.desc) {
 		if (list_empty(&ep->queue))
 			submit_request(ep, req);
 
@@ -776,7 +775,8 @@
 	DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ, "%s: queue req %p, len %u\n",
 			ep->ep.name, req, _req->length);
 
-	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN || !ep->desc)
+	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN ||
+	    !ep->ep.desc)
 		return -ESHUTDOWN;
 
 	req->submitted = 0;
@@ -792,7 +792,7 @@
 	/* May have received a reset since last time we checked */
 	ret = -ESHUTDOWN;
 	spin_lock_irqsave(&udc->lock, flags);
-	if (ep->desc) {
+	if (ep->ep.desc) {
 		list_add_tail(&req->queue, &ep->queue);
 
 		if ((!ep_is_control(ep) && ep->is_in) ||
@@ -905,7 +905,7 @@
 	DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep->ep.name,
 			value ? "set" : "clear");
 
-	if (!ep->desc) {
+	if (!ep->ep.desc) {
 		DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n",
 				ep->ep.name);
 		return -ENODEV;
@@ -1008,16 +1008,16 @@
 	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 int atmel_usba_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
+static int atmel_usba_stop(struct usb_gadget *gadget,
+		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,
+	.udc_start		= atmel_usba_start,
+	.udc_stop		= atmel_usba_stop,
 };
 
 static struct usb_endpoint_descriptor usba_ep0_desc = {
@@ -1071,7 +1071,7 @@
 	 * FIXME remove this code ... and retest thoroughly.
 	 */
 	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
-		if (ep->desc) {
+		if (ep->ep.desc) {
 			spin_unlock(&udc->lock);
 			usba_ep_disable(&ep->ep);
 			spin_lock(&udc->lock);
@@ -1089,9 +1089,9 @@
 	list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
 		u8 bEndpointAddress;
 
-		if (!ep->desc)
+		if (!ep->ep.desc)
 			continue;
-		bEndpointAddress = ep->desc->bEndpointAddress;
+		bEndpointAddress = ep->ep.desc->bEndpointAddress;
 		if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
 			continue;
 		if ((bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
@@ -1727,7 +1727,7 @@
 		    usb_speed_string(udc->gadget.speed));
 
 		ep0 = &usba_ep[0];
-		ep0->desc = &usba_ep0_desc;
+		ep0->ep.desc = &usba_ep0_desc;
 		ep0->state = WAIT_FOR_SETUP;
 		usba_ep_writel(ep0, CFG,
 				(USBA_BF(EPT_SIZE, EP0_EPT_SIZE)
@@ -1795,21 +1795,13 @@
 	return IRQ_HANDLED;
 }
 
-static int atmel_usba_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
+static int atmel_usba_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	struct usba_udc *udc = &the_udc;
+	struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget);
 	unsigned long flags;
-	int ret;
-
-	if (!udc->pdev)
-		return -ENODEV;
 
 	spin_lock_irqsave(&udc->lock, flags);
-	if (udc->driver) {
-		spin_unlock_irqrestore(&udc->lock, flags);
-		return -EBUSY;
-	}
 
 	udc->devstatus = 1 << USB_DEVICE_SELF_POWERED;
 	udc->driver = driver;
@@ -1819,13 +1811,6 @@
 	clk_enable(udc->pclk);
 	clk_enable(udc->hclk);
 
-	ret = bind(&udc->gadget);
-	if (ret) {
-		DBG(DBG_ERR, "Could not bind to driver %s: error %d\n",
-			driver->driver.name, ret);
-		goto err_driver_bind;
-	}
-
 	DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
 
 	udc->vbus_prev = 0;
@@ -1842,23 +1827,14 @@
 	spin_unlock_irqrestore(&udc->lock, flags);
 
 	return 0;
-
-err_driver_bind:
-	udc->driver = NULL;
-	udc->gadget.dev.driver = NULL;
-	return ret;
 }
 
-static int atmel_usba_stop(struct usb_gadget_driver *driver)
+static int atmel_usba_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	struct usba_udc *udc = &the_udc;
+	struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget);
 	unsigned long flags;
 
-	if (!udc->pdev)
-		return -ENODEV;
-	if (driver != udc->driver || !driver->unbind)
-		return -EINVAL;
-
 	if (gpio_is_valid(udc->vbus_pin))
 		disable_irq(gpio_to_irq(udc->vbus_pin));
 
@@ -1871,10 +1847,6 @@
 	toggle_bias(0);
 	usba_writel(udc, CTRL, USBA_DISABLE_MASK);
 
-	if (udc->driver->disconnect)
-		udc->driver->disconnect(&udc->gadget);
-
-	driver->unbind(&udc->gadget);
 	udc->gadget.dev.driver = NULL;
 	udc->driver = NULL;
 
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h
index 88a2e07..9791259 100644
--- a/drivers/usb/gadget/atmel_usba_udc.h
+++ b/drivers/usb/gadget/atmel_usba_udc.h
@@ -280,7 +280,6 @@
 	struct usba_udc				*udc;
 
 	struct list_head			queue;
-	const struct usb_endpoint_descriptor	*desc;
 
 	u16					fifo_size;
 	u8					nr_banks;
diff --git a/drivers/usb/gadget/ci13xxx_pci.c b/drivers/usb/gadget/ci13xxx_pci.c
deleted file mode 100644
index 883ab5e..0000000
--- a/drivers/usb/gadget/ci13xxx_pci.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * ci13xxx_pci.c - MIPS USB IP core family device controller
- *
- * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
- *
- * Author: David Lopo
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-
-#include "ci13xxx_udc.c"
-
-/* driver name */
-#define UDC_DRIVER_NAME   "ci13xxx_pci"
-
-/******************************************************************************
- * PCI block
- *****************************************************************************/
-/**
- * ci13xxx_pci_irq: interrut handler
- * @irq:  irq number
- * @pdev: USB Device Controller interrupt source
- *
- * This function returns IRQ_HANDLED if the IRQ has been handled
- * This is an ISR don't trace, use attribute interface instead
- */
-static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev)
-{
-	if (irq == 0) {
-		dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!");
-		return IRQ_HANDLED;
-	}
-	return udc_irq();
-}
-
-static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = {
-	.name		= UDC_DRIVER_NAME,
-};
-
-/**
- * ci13xxx_pci_probe: PCI probe
- * @pdev: USB device controller being probed
- * @id:   PCI hotplug ID connecting controller to UDC framework
- *
- * This function returns an error code
- * Allocates basic PCI resources for this USB device controller, and then
- * invokes the udc_probe() method to start the UDC associated with it
- */
-static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
-				       const struct pci_device_id *id)
-{
-	void __iomem *regs = NULL;
-	int retval = 0;
-
-	if (id == NULL)
-		return -EINVAL;
-
-	retval = pci_enable_device(pdev);
-	if (retval)
-		goto done;
-
-	if (!pdev->irq) {
-		dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!");
-		retval = -ENODEV;
-		goto disable_device;
-	}
-
-	retval = pci_request_regions(pdev, UDC_DRIVER_NAME);
-	if (retval)
-		goto disable_device;
-
-	/* BAR 0 holds all the registers */
-	regs = pci_iomap(pdev, 0, 0);
-	if (!regs) {
-		dev_err(&pdev->dev, "Error mapping memory!");
-		retval = -EFAULT;
-		goto release_regions;
-	}
-	pci_set_drvdata(pdev, (__force void *)regs);
-
-	pci_set_master(pdev);
-	pci_try_set_mwi(pdev);
-
-	retval = udc_probe(&ci13xxx_pci_udc_driver, &pdev->dev, regs);
-	if (retval)
-		goto iounmap;
-
-	/* our device does not have MSI capability */
-
-	retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED,
-			     UDC_DRIVER_NAME, pdev);
-	if (retval)
-		goto gadget_remove;
-
-	return 0;
-
- gadget_remove:
-	udc_remove();
- iounmap:
-	pci_iounmap(pdev, regs);
- release_regions:
-	pci_release_regions(pdev);
- disable_device:
-	pci_disable_device(pdev);
- done:
-	return retval;
-}
-
-/**
- * ci13xxx_pci_remove: PCI remove
- * @pdev: USB Device Controller being removed
- *
- * Reverses the effect of ci13xxx_pci_probe(),
- * first invoking the udc_remove() and then releases
- * all PCI resources allocated for this USB device controller
- */
-static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
-{
-	free_irq(pdev->irq, pdev);
-	udc_remove();
-	pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev));
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-}
-
-/**
- * PCI device table
- * PCI device structure
- *
- * Check "pci.h" for details
- */
-static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = {
-	{ PCI_DEVICE(0x153F, 0x1004) },
-	{ PCI_DEVICE(0x153F, 0x1006) },
-	{ 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
-};
-MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table);
-
-static struct pci_driver ci13xxx_pci_driver = {
-	.name         =	UDC_DRIVER_NAME,
-	.id_table     =	ci13xxx_pci_id_table,
-	.probe        =	ci13xxx_pci_probe,
-	.remove       =	__devexit_p(ci13xxx_pci_remove),
-};
-
-/**
- * ci13xxx_pci_init: module init
- *
- * Driver load
- */
-static int __init ci13xxx_pci_init(void)
-{
-	return pci_register_driver(&ci13xxx_pci_driver);
-}
-module_init(ci13xxx_pci_init);
-
-/**
- * ci13xxx_pci_exit: module exit
- *
- * Driver unload
- */
-static void __exit ci13xxx_pci_exit(void)
-{
-	pci_unregister_driver(&ci13xxx_pci_driver);
-}
-module_exit(ci13xxx_pci_exit);
-
-MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>");
-MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("June 2008");
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
deleted file mode 100644
index 243ef1a..0000000
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ /dev/null
@@ -1,2996 +0,0 @@
-/*
- * ci13xxx_udc.c - MIPS USB IP core family device controller
- *
- * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
- *
- * Author: David Lopo
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/*
- * Description: MIPS USB IP core family device controller
- *              Currently it only supports IP part number CI13412
- *
- * This driver is composed of several blocks:
- * - HW:     hardware interface
- * - DBG:    debug facilities (optional)
- * - UTIL:   utilities
- * - ISR:    interrupts handling
- * - ENDPT:  endpoint operations (Gadget API)
- * - GADGET: gadget operations (Gadget API)
- * - BUS:    bus glue code, bus abstraction layer
- *
- * Compile Options
- * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities
- * - STALL_IN:  non-empty bulk-in pipes cannot be halted
- *              if defined mass storage compliance succeeds but with warnings
- *              => case 4: Hi >  Dn
- *              => case 5: Hi >  Di
- *              => case 8: Hi <> Do
- *              if undefined usbtest 13 fails
- * - TRACE:     enable function tracing (depends on DEBUG)
- *
- * Main Features
- * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
- * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
- * - Normal & LPM support
- *
- * USBTEST Report
- * - OK: 0-12, 13 (STALL_IN defined) & 14
- * - Not Supported: 15 & 16 (ISO)
- *
- * TODO List
- * - OTG
- * - Isochronous & Interrupt Traffic
- * - Handle requests which spawns into several TDs
- * - GET_STATUS(device) - always reports 0
- * - Gadget API (majority of optional features)
- * - Suspend & Remote Wakeup
- */
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dmapool.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb/otg.h>
-
-#include "ci13xxx_udc.h"
-
-
-/******************************************************************************
- * DEFINE
- *****************************************************************************/
-
-#define DMA_ADDR_INVALID	(~(dma_addr_t)0)
-
-/* ctrl register bank access */
-static DEFINE_SPINLOCK(udc_lock);
-
-/* control endpoint description */
-static const struct usb_endpoint_descriptor
-ctrl_endpt_out_desc = {
-	.bLength         = USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType = USB_DT_ENDPOINT,
-
-	.bEndpointAddress = USB_DIR_OUT,
-	.bmAttributes    = USB_ENDPOINT_XFER_CONTROL,
-	.wMaxPacketSize  = cpu_to_le16(CTRL_PAYLOAD_MAX),
-};
-
-static const struct usb_endpoint_descriptor
-ctrl_endpt_in_desc = {
-	.bLength         = USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType = USB_DT_ENDPOINT,
-
-	.bEndpointAddress = USB_DIR_IN,
-	.bmAttributes    = USB_ENDPOINT_XFER_CONTROL,
-	.wMaxPacketSize  = cpu_to_le16(CTRL_PAYLOAD_MAX),
-};
-
-/* UDC descriptor */
-static struct ci13xxx *_udc;
-
-/* Interrupt statistics */
-#define ISR_MASK   0x1F
-static struct {
-	u32 test;
-	u32 ui;
-	u32 uei;
-	u32 pci;
-	u32 uri;
-	u32 sli;
-	u32 none;
-	struct {
-		u32 cnt;
-		u32 buf[ISR_MASK+1];
-		u32 idx;
-	} hndl;
-} isr_statistics;
-
-/**
- * ffs_nr: find first (least significant) bit set
- * @x: the word to search
- *
- * This function returns bit number (instead of position)
- */
-static int ffs_nr(u32 x)
-{
-	int n = ffs(x);
-
-	return n ? n-1 : 32;
-}
-
-/******************************************************************************
- * HW block
- *****************************************************************************/
-/* register bank descriptor */
-static struct {
-	unsigned      lpm;    /* is LPM? */
-	void __iomem *abs;    /* bus map offset */
-	void __iomem *cap;    /* bus map offset + CAP offset + CAP data */
-	size_t        size;   /* bank size */
-} hw_bank;
-
-/* MSM specific */
-#define ABS_AHBBURST        (0x0090UL)
-#define ABS_AHBMODE         (0x0098UL)
-/* UDC register map */
-#define ABS_CAPLENGTH       (0x100UL)
-#define ABS_HCCPARAMS       (0x108UL)
-#define ABS_DCCPARAMS       (0x124UL)
-#define ABS_TESTMODE        (hw_bank.lpm ? 0x0FCUL : 0x138UL)
-/* offset to CAPLENTGH (addr + data) */
-#define CAP_USBCMD          (0x000UL)
-#define CAP_USBSTS          (0x004UL)
-#define CAP_USBINTR         (0x008UL)
-#define CAP_DEVICEADDR      (0x014UL)
-#define CAP_ENDPTLISTADDR   (0x018UL)
-#define CAP_PORTSC          (0x044UL)
-#define CAP_DEVLC           (0x084UL)
-#define CAP_USBMODE         (hw_bank.lpm ? 0x0C8UL : 0x068UL)
-#define CAP_ENDPTSETUPSTAT  (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
-#define CAP_ENDPTPRIME      (hw_bank.lpm ? 0x0DCUL : 0x070UL)
-#define CAP_ENDPTFLUSH      (hw_bank.lpm ? 0x0E0UL : 0x074UL)
-#define CAP_ENDPTSTAT       (hw_bank.lpm ? 0x0E4UL : 0x078UL)
-#define CAP_ENDPTCOMPLETE   (hw_bank.lpm ? 0x0E8UL : 0x07CUL)
-#define CAP_ENDPTCTRL       (hw_bank.lpm ? 0x0ECUL : 0x080UL)
-#define CAP_LAST            (hw_bank.lpm ? 0x12CUL : 0x0C0UL)
-
-/* maximum number of enpoints: valid only after hw_device_reset() */
-static unsigned hw_ep_max;
-
-/**
- * hw_ep_bit: calculates the bit number
- * @num: endpoint number
- * @dir: endpoint direction
- *
- * This function returns bit number
- */
-static inline int hw_ep_bit(int num, int dir)
-{
-	return num + (dir ? 16 : 0);
-}
-
-static int ep_to_bit(int n)
-{
-	int fill = 16 - hw_ep_max / 2;
-
-	if (n >= hw_ep_max / 2)
-		n += fill;
-
-	return n;
-}
-
-/**
- * hw_aread: reads from register bitfield
- * @addr: address relative to bus map
- * @mask: bitfield mask
- *
- * This function returns register bitfield data
- */
-static u32 hw_aread(u32 addr, u32 mask)
-{
-	return ioread32(addr + hw_bank.abs) & mask;
-}
-
-/**
- * hw_awrite: writes to register bitfield
- * @addr: address relative to bus map
- * @mask: bitfield mask
- * @data: new data
- */
-static void hw_awrite(u32 addr, u32 mask, u32 data)
-{
-	iowrite32(hw_aread(addr, ~mask) | (data & mask),
-		  addr + hw_bank.abs);
-}
-
-/**
- * hw_cread: reads from register bitfield
- * @addr: address relative to CAP offset plus content
- * @mask: bitfield mask
- *
- * This function returns register bitfield data
- */
-static u32 hw_cread(u32 addr, u32 mask)
-{
-	return ioread32(addr + hw_bank.cap) & mask;
-}
-
-/**
- * hw_cwrite: writes to register bitfield
- * @addr: address relative to CAP offset plus content
- * @mask: bitfield mask
- * @data: new data
- */
-static void hw_cwrite(u32 addr, u32 mask, u32 data)
-{
-	iowrite32(hw_cread(addr, ~mask) | (data & mask),
-		  addr + hw_bank.cap);
-}
-
-/**
- * hw_ctest_and_clear: tests & clears register bitfield
- * @addr: address relative to CAP offset plus content
- * @mask: bitfield mask
- *
- * This function returns register bitfield data
- */
-static u32 hw_ctest_and_clear(u32 addr, u32 mask)
-{
-	u32 reg = hw_cread(addr, mask);
-
-	iowrite32(reg, addr + hw_bank.cap);
-	return reg;
-}
-
-/**
- * hw_ctest_and_write: tests & writes register bitfield
- * @addr: address relative to CAP offset plus content
- * @mask: bitfield mask
- * @data: new data
- *
- * This function returns register bitfield data
- */
-static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data)
-{
-	u32 reg = hw_cread(addr, ~0);
-
-	iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap);
-	return (reg & mask) >> ffs_nr(mask);
-}
-
-static int hw_device_init(void __iomem *base)
-{
-	u32 reg;
-
-	/* bank is a module variable */
-	hw_bank.abs = base;
-
-	hw_bank.cap = hw_bank.abs;
-	hw_bank.cap += ABS_CAPLENGTH;
-	hw_bank.cap += ioread8(hw_bank.cap);
-
-	reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN);
-	hw_bank.lpm  = reg;
-	hw_bank.size = hw_bank.cap - hw_bank.abs;
-	hw_bank.size += CAP_LAST;
-	hw_bank.size /= sizeof(u32);
-
-	reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN);
-	hw_ep_max = reg * 2;   /* cache hw ENDPT_MAX */
-
-	if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX)
-		return -ENODEV;
-
-	/* setup lock mode ? */
-
-	/* ENDPTSETUPSTAT is '0' by default */
-
-	/* HCSPARAMS.bf.ppc SHOULD BE zero for device */
-
-	return 0;
-}
-/**
- * hw_device_reset: resets chip (execute without interruption)
- * @base: register base address
- *
- * This function returns an error code
- */
-static int hw_device_reset(struct ci13xxx *udc)
-{
-	/* should flush & stop before reset */
-	hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
-	hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
-
-	hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
-	while (hw_cread(CAP_USBCMD, USBCMD_RST))
-		udelay(10);             /* not RTOS friendly */
-
-
-	if (udc->udc_driver->notify_event)
-		udc->udc_driver->notify_event(udc,
-			CI13XXX_CONTROLLER_RESET_EVENT);
-
-	if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
-		hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
-
-	/* USBMODE should be configured step by step */
-	hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
-	hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
-	hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);  /* HW >= 2.3 */
-
-	if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
-		pr_err("cannot enter in device mode");
-		pr_err("lpm = %i", hw_bank.lpm);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-/**
- * hw_device_state: enables/disables interrupts & starts/stops device (execute
- *                  without interruption)
- * @dma: 0 => disable, !0 => enable and set dma engine
- *
- * This function returns an error code
- */
-static int hw_device_state(u32 dma)
-{
-	if (dma) {
-		hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
-		/* interrupt, error, port change, reset, sleep/suspend */
-		hw_cwrite(CAP_USBINTR, ~0,
-			     USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
-		hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS);
-	} else {
-		hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
-		hw_cwrite(CAP_USBINTR, ~0, 0);
-	}
-	return 0;
-}
-
-/**
- * hw_ep_flush: flush endpoint fifo (execute without interruption)
- * @num: endpoint number
- * @dir: endpoint direction
- *
- * This function returns an error code
- */
-static int hw_ep_flush(int num, int dir)
-{
-	int n = hw_ep_bit(num, dir);
-
-	do {
-		/* flush any pending transfer */
-		hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n));
-		while (hw_cread(CAP_ENDPTFLUSH, BIT(n)))
-			cpu_relax();
-	} while (hw_cread(CAP_ENDPTSTAT, BIT(n)));
-
-	return 0;
-}
-
-/**
- * hw_ep_disable: disables endpoint (execute without interruption)
- * @num: endpoint number
- * @dir: endpoint direction
- *
- * This function returns an error code
- */
-static int hw_ep_disable(int num, int dir)
-{
-	hw_ep_flush(num, dir);
-	hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32),
-		  dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
-	return 0;
-}
-
-/**
- * hw_ep_enable: enables endpoint (execute without interruption)
- * @num:  endpoint number
- * @dir:  endpoint direction
- * @type: endpoint type
- *
- * This function returns an error code
- */
-static int hw_ep_enable(int num, int dir, int type)
-{
-	u32 mask, data;
-
-	if (dir) {
-		mask  = ENDPTCTRL_TXT;  /* type    */
-		data  = type << ffs_nr(mask);
-
-		mask |= ENDPTCTRL_TXS;  /* unstall */
-		mask |= ENDPTCTRL_TXR;  /* reset data toggle */
-		data |= ENDPTCTRL_TXR;
-		mask |= ENDPTCTRL_TXE;  /* enable  */
-		data |= ENDPTCTRL_TXE;
-	} else {
-		mask  = ENDPTCTRL_RXT;  /* type    */
-		data  = type << ffs_nr(mask);
-
-		mask |= ENDPTCTRL_RXS;  /* unstall */
-		mask |= ENDPTCTRL_RXR;  /* reset data toggle */
-		data |= ENDPTCTRL_RXR;
-		mask |= ENDPTCTRL_RXE;  /* enable  */
-		data |= ENDPTCTRL_RXE;
-	}
-	hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data);
-	return 0;
-}
-
-/**
- * hw_ep_get_halt: return endpoint halt status
- * @num: endpoint number
- * @dir: endpoint direction
- *
- * This function returns 1 if endpoint halted
- */
-static int hw_ep_get_halt(int num, int dir)
-{
-	u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
-
-	return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0;
-}
-
-/**
- * hw_test_and_clear_setup_status: test & clear setup status (execute without
- *                                 interruption)
- * @n: endpoint number
- *
- * This function returns setup status
- */
-static int hw_test_and_clear_setup_status(int n)
-{
-	n = ep_to_bit(n);
-	return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n));
-}
-
-/**
- * hw_ep_prime: primes endpoint (execute without interruption)
- * @num:     endpoint number
- * @dir:     endpoint direction
- * @is_ctrl: true if control endpoint
- *
- * This function returns an error code
- */
-static int hw_ep_prime(int num, int dir, int is_ctrl)
-{
-	int n = hw_ep_bit(num, dir);
-
-	if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
-		return -EAGAIN;
-
-	hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n));
-
-	while (hw_cread(CAP_ENDPTPRIME, BIT(n)))
-		cpu_relax();
-	if (is_ctrl && dir == RX  && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
-		return -EAGAIN;
-
-	/* status shoult be tested according with manual but it doesn't work */
-	return 0;
-}
-
-/**
- * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
- *                 without interruption)
- * @num:   endpoint number
- * @dir:   endpoint direction
- * @value: true => stall, false => unstall
- *
- * This function returns an error code
- */
-static int hw_ep_set_halt(int num, int dir, int value)
-{
-	if (value != 0 && value != 1)
-		return -EINVAL;
-
-	do {
-		u32 addr = CAP_ENDPTCTRL + num * sizeof(u32);
-		u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
-		u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
-
-		/* data toggle - reserved for EP0 but it's in ESS */
-		hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr);
-
-	} while (value != hw_ep_get_halt(num, dir));
-
-	return 0;
-}
-
-/**
- * hw_intr_clear: disables interrupt & clears interrupt status (execute without
- *                interruption)
- * @n: interrupt bit
- *
- * This function returns an error code
- */
-static int hw_intr_clear(int n)
-{
-	if (n >= REG_BITS)
-		return -EINVAL;
-
-	hw_cwrite(CAP_USBINTR, BIT(n), 0);
-	hw_cwrite(CAP_USBSTS,  BIT(n), BIT(n));
-	return 0;
-}
-
-/**
- * hw_intr_force: enables interrupt & forces interrupt status (execute without
- *                interruption)
- * @n: interrupt bit
- *
- * This function returns an error code
- */
-static int hw_intr_force(int n)
-{
-	if (n >= REG_BITS)
-		return -EINVAL;
-
-	hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
-	hw_cwrite(CAP_USBINTR,  BIT(n), BIT(n));
-	hw_cwrite(CAP_USBSTS,   BIT(n), BIT(n));
-	hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0);
-	return 0;
-}
-
-/**
- * hw_is_port_high_speed: test if port is high speed
- *
- * This function returns true if high speed port
- */
-static int hw_port_is_high_speed(void)
-{
-	return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) :
-		hw_cread(CAP_PORTSC, PORTSC_HSP);
-}
-
-/**
- * hw_port_test_get: reads port test mode value
- *
- * This function returns port test mode value
- */
-static u8 hw_port_test_get(void)
-{
-	return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
-}
-
-/**
- * hw_port_test_set: writes port test mode (execute without interruption)
- * @mode: new value
- *
- * This function returns an error code
- */
-static int hw_port_test_set(u8 mode)
-{
-	const u8 TEST_MODE_MAX = 7;
-
-	if (mode > TEST_MODE_MAX)
-		return -EINVAL;
-
-	hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
-	return 0;
-}
-
-/**
- * hw_read_intr_enable: returns interrupt enable register
- *
- * This function returns register data
- */
-static u32 hw_read_intr_enable(void)
-{
-	return hw_cread(CAP_USBINTR, ~0);
-}
-
-/**
- * hw_read_intr_status: returns interrupt status register
- *
- * This function returns register data
- */
-static u32 hw_read_intr_status(void)
-{
-	return hw_cread(CAP_USBSTS, ~0);
-}
-
-/**
- * hw_register_read: reads all device registers (execute without interruption)
- * @buf:  destination buffer
- * @size: buffer size
- *
- * This function returns number of registers read
- */
-static size_t hw_register_read(u32 *buf, size_t size)
-{
-	unsigned i;
-
-	if (size > hw_bank.size)
-		size = hw_bank.size;
-
-	for (i = 0; i < size; i++)
-		buf[i] = hw_aread(i * sizeof(u32), ~0);
-
-	return size;
-}
-
-/**
- * hw_register_write: writes to register
- * @addr: register address
- * @data: register value
- *
- * This function returns an error code
- */
-static int hw_register_write(u16 addr, u32 data)
-{
-	/* align */
-	addr /= sizeof(u32);
-
-	if (addr >= hw_bank.size)
-		return -EINVAL;
-
-	/* align */
-	addr *= sizeof(u32);
-
-	hw_awrite(addr, ~0, data);
-	return 0;
-}
-
-/**
- * hw_test_and_clear_complete: test & clear complete status (execute without
- *                             interruption)
- * @n: endpoint number
- *
- * This function returns complete status
- */
-static int hw_test_and_clear_complete(int n)
-{
-	n = ep_to_bit(n);
-	return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n));
-}
-
-/**
- * hw_test_and_clear_intr_active: test & clear active interrupts (execute
- *                                without interruption)
- *
- * This function returns active interrutps
- */
-static u32 hw_test_and_clear_intr_active(void)
-{
-	u32 reg = hw_read_intr_status() & hw_read_intr_enable();
-
-	hw_cwrite(CAP_USBSTS, ~0, reg);
-	return reg;
-}
-
-/**
- * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
- *                                interruption)
- *
- * This function returns guard value
- */
-static int hw_test_and_clear_setup_guard(void)
-{
-	return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0);
-}
-
-/**
- * hw_test_and_set_setup_guard: test & set setup guard (execute without
- *                              interruption)
- *
- * This function returns guard value
- */
-static int hw_test_and_set_setup_guard(void)
-{
-	return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
-}
-
-/**
- * hw_usb_set_address: configures USB address (execute without interruption)
- * @value: new USB address
- *
- * This function returns an error code
- */
-static int hw_usb_set_address(u8 value)
-{
-	/* advance */
-	hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
-		  value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
-	return 0;
-}
-
-/**
- * hw_usb_reset: restart device after a bus reset (execute without
- *               interruption)
- *
- * This function returns an error code
- */
-static int hw_usb_reset(void)
-{
-	hw_usb_set_address(0);
-
-	/* ESS flushes only at end?!? */
-	hw_cwrite(CAP_ENDPTFLUSH,    ~0, ~0);   /* flush all EPs */
-
-	/* clear setup token semaphores */
-	hw_cwrite(CAP_ENDPTSETUPSTAT, 0,  0);   /* writes its content */
-
-	/* clear complete status */
-	hw_cwrite(CAP_ENDPTCOMPLETE,  0,  0);   /* writes its content */
-
-	/* wait until all bits cleared */
-	while (hw_cread(CAP_ENDPTPRIME, ~0))
-		udelay(10);             /* not RTOS friendly */
-
-	/* reset all endpoints ? */
-
-	/* reset internal status and wait for further instructions
-	   no need to verify the port reset status (ESS does it) */
-
-	return 0;
-}
-
-/******************************************************************************
- * DBG block
- *****************************************************************************/
-/**
- * show_device: prints information about device capabilities and status
- *
- * Check "device.h" for details
- */
-static ssize_t show_device(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	struct usb_gadget *gadget = &udc->gadget;
-	int n = 0;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	n += scnprintf(buf + n, PAGE_SIZE - n, "speed             = %d\n",
-		       gadget->speed);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed         = %d\n",
-		       gadget->max_speed);
-	/* TODO: Scheduled for removal in 3.8. */
-	n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed      = %d\n",
-		       gadget_is_dualspeed(gadget));
-	n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg            = %d\n",
-		       gadget->is_otg);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral   = %d\n",
-		       gadget->is_a_peripheral);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable      = %d\n",
-		       gadget->b_hnp_enable);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support     = %d\n",
-		       gadget->a_hnp_support);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
-		       gadget->a_alt_hnp_support);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "name              = %s\n",
-		       (gadget->name ? gadget->name : ""));
-
-	return n;
-}
-static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
-
-/**
- * show_driver: prints information about attached gadget (if any)
- *
- * Check "device.h" for details
- */
-static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	struct usb_gadget_driver *driver = udc->driver;
-	int n = 0;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	if (driver == NULL)
-		return scnprintf(buf, PAGE_SIZE,
-				 "There is no gadget attached!\n");
-
-	n += scnprintf(buf + n, PAGE_SIZE - n, "function  = %s\n",
-		       (driver->function ? driver->function : ""));
-	n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
-		       driver->max_speed);
-
-	return n;
-}
-static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
-
-/* Maximum event message length */
-#define DBG_DATA_MSG   64UL
-
-/* Maximum event messages */
-#define DBG_DATA_MAX   128UL
-
-/* Event buffer descriptor */
-static struct {
-	char     (buf[DBG_DATA_MAX])[DBG_DATA_MSG];   /* buffer */
-	unsigned idx;   /* index */
-	unsigned tty;   /* print to console? */
-	rwlock_t lck;   /* lock */
-} dbg_data = {
-	.idx = 0,
-	.tty = 0,
-	.lck = __RW_LOCK_UNLOCKED(lck)
-};
-
-/**
- * dbg_dec: decrements debug event index
- * @idx: buffer index
- */
-static void dbg_dec(unsigned *idx)
-{
-	*idx = (*idx - 1) & (DBG_DATA_MAX-1);
-}
-
-/**
- * dbg_inc: increments debug event index
- * @idx: buffer index
- */
-static void dbg_inc(unsigned *idx)
-{
-	*idx = (*idx + 1) & (DBG_DATA_MAX-1);
-}
-
-/**
- * dbg_print:  prints the common part of the event
- * @addr:   endpoint address
- * @name:   event name
- * @status: status
- * @extra:  extra information
- */
-static void dbg_print(u8 addr, const char *name, int status, const char *extra)
-{
-	struct timeval tval;
-	unsigned int stamp;
-	unsigned long flags;
-
-	write_lock_irqsave(&dbg_data.lck, flags);
-
-	do_gettimeofday(&tval);
-	stamp = tval.tv_sec & 0xFFFF;	/* 2^32 = 4294967296. Limit to 4096s */
-	stamp = stamp * 1000000 + tval.tv_usec;
-
-	scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
-		  "%04X\t? %02X %-7.7s %4i ?\t%s\n",
-		  stamp, addr, name, status, extra);
-
-	dbg_inc(&dbg_data.idx);
-
-	write_unlock_irqrestore(&dbg_data.lck, flags);
-
-	if (dbg_data.tty != 0)
-		pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
-			  stamp, addr, name, status, extra);
-}
-
-/**
- * dbg_done: prints a DONE event
- * @addr:   endpoint address
- * @td:     transfer descriptor
- * @status: status
- */
-static void dbg_done(u8 addr, const u32 token, int status)
-{
-	char msg[DBG_DATA_MSG];
-
-	scnprintf(msg, sizeof(msg), "%d %02X",
-		  (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
-		  (int)(token & TD_STATUS)      >> ffs_nr(TD_STATUS));
-	dbg_print(addr, "DONE", status, msg);
-}
-
-/**
- * dbg_event: prints a generic event
- * @addr:   endpoint address
- * @name:   event name
- * @status: status
- */
-static void dbg_event(u8 addr, const char *name, int status)
-{
-	if (name != NULL)
-		dbg_print(addr, name, status, "");
-}
-
-/*
- * dbg_queue: prints a QUEUE event
- * @addr:   endpoint address
- * @req:    USB request
- * @status: status
- */
-static void dbg_queue(u8 addr, const struct usb_request *req, int status)
-{
-	char msg[DBG_DATA_MSG];
-
-	if (req != NULL) {
-		scnprintf(msg, sizeof(msg),
-			  "%d %d", !req->no_interrupt, req->length);
-		dbg_print(addr, "QUEUE", status, msg);
-	}
-}
-
-/**
- * dbg_setup: prints a SETUP event
- * @addr: endpoint address
- * @req:  setup request
- */
-static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
-{
-	char msg[DBG_DATA_MSG];
-
-	if (req != NULL) {
-		scnprintf(msg, sizeof(msg),
-			  "%02X %02X %04X %04X %d", req->bRequestType,
-			  req->bRequest, le16_to_cpu(req->wValue),
-			  le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
-		dbg_print(addr, "SETUP", 0, msg);
-	}
-}
-
-/**
- * show_events: displays the event buffer
- *
- * Check "device.h" for details
- */
-static ssize_t show_events(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	unsigned long flags;
-	unsigned i, j, n = 0;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	read_lock_irqsave(&dbg_data.lck, flags);
-
-	i = dbg_data.idx;
-	for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
-		n += strlen(dbg_data.buf[i]);
-		if (n >= PAGE_SIZE) {
-			n -= strlen(dbg_data.buf[i]);
-			break;
-		}
-	}
-	for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
-		j += scnprintf(buf + j, PAGE_SIZE - j,
-			       "%s", dbg_data.buf[i]);
-
-	read_unlock_irqrestore(&dbg_data.lck, flags);
-
-	return n;
-}
-
-/**
- * store_events: configure if events are going to be also printed to console
- *
- * Check "device.h" for details
- */
-static ssize_t store_events(struct device *dev, struct device_attribute *attr,
-			    const char *buf, size_t count)
-{
-	unsigned tty;
-
-	dbg_trace("[%s] %p, %d\n", __func__, buf, count);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		goto done;
-	}
-
-	if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
-		dev_err(dev, "<1|0>: enable|disable console log\n");
-		goto done;
-	}
-
-	dbg_data.tty = tty;
-	dev_info(dev, "tty = %u", dbg_data.tty);
-
- done:
-	return count;
-}
-static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
-
-/**
- * show_inters: interrupt status, enable status and historic
- *
- * Check "device.h" for details
- */
-static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	u32 intr;
-	unsigned i, j, n = 0;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-
-	n += scnprintf(buf + n, PAGE_SIZE - n,
-		       "status = %08x\n", hw_read_intr_status());
-	n += scnprintf(buf + n, PAGE_SIZE - n,
-		       "enable = %08x\n", hw_read_intr_enable());
-
-	n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
-		       isr_statistics.test);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "? ui  = %d\n",
-		       isr_statistics.ui);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
-		       isr_statistics.uei);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
-		       isr_statistics.pci);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
-		       isr_statistics.uri);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
-		       isr_statistics.sli);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
-		       isr_statistics.none);
-	n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
-		       isr_statistics.hndl.cnt);
-
-	for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
-		i   &= ISR_MASK;
-		intr = isr_statistics.hndl.buf[i];
-
-		if (USBi_UI  & intr)
-			n += scnprintf(buf + n, PAGE_SIZE - n, "ui  ");
-		intr &= ~USBi_UI;
-		if (USBi_UEI & intr)
-			n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
-		intr &= ~USBi_UEI;
-		if (USBi_PCI & intr)
-			n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
-		intr &= ~USBi_PCI;
-		if (USBi_URI & intr)
-			n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
-		intr &= ~USBi_URI;
-		if (USBi_SLI & intr)
-			n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
-		intr &= ~USBi_SLI;
-		if (intr)
-			n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
-		if (isr_statistics.hndl.buf[i])
-			n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
-	}
-
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	return n;
-}
-
-/**
- * store_inters: enable & force or disable an individual interrutps
- *                   (to be used for test purposes only)
- *
- * Check "device.h" for details
- */
-static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
-			    const char *buf, size_t count)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	unsigned en, bit;
-
-	dbg_trace("[%s] %p, %d\n", __func__, buf, count);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		goto done;
-	}
-
-	if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
-		dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
-		goto done;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	if (en) {
-		if (hw_intr_force(bit))
-			dev_err(dev, "invalid bit number\n");
-		else
-			isr_statistics.test++;
-	} else {
-		if (hw_intr_clear(bit))
-			dev_err(dev, "invalid bit number\n");
-	}
-	spin_unlock_irqrestore(udc->lock, flags);
-
- done:
-	return count;
-}
-static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
-
-/**
- * show_port_test: reads port test mode
- *
- * Check "device.h" for details
- */
-static ssize_t show_port_test(struct device *dev,
-			      struct device_attribute *attr, char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	unsigned mode;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	mode = hw_port_test_get();
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
-}
-
-/**
- * store_port_test: writes port test mode
- *
- * Check "device.h" for details
- */
-static ssize_t store_port_test(struct device *dev,
-			       struct device_attribute *attr,
-			       const char *buf, size_t count)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	unsigned mode;
-
-	dbg_trace("[%s] %p, %d\n", __func__, buf, count);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		goto done;
-	}
-
-	if (sscanf(buf, "%u", &mode) != 1) {
-		dev_err(dev, "<mode>: set port test mode");
-		goto done;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	if (hw_port_test_set(mode))
-		dev_err(dev, "invalid mode\n");
-	spin_unlock_irqrestore(udc->lock, flags);
-
- done:
-	return count;
-}
-static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
-		   show_port_test, store_port_test);
-
-/**
- * show_qheads: DMA contents of all queue heads
- *
- * Check "device.h" for details
- */
-static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
-			   char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	unsigned i, j, n = 0;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	for (i = 0; i < hw_ep_max/2; i++) {
-		struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
-		struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2];
-		n += scnprintf(buf + n, PAGE_SIZE - n,
-			       "EP=%02i: RX=%08X TX=%08X\n",
-			       i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
-		for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
-			n += scnprintf(buf + n, PAGE_SIZE - n,
-				       " %04X:    %08X    %08X\n", j,
-				       *((u32 *)mEpRx->qh.ptr + j),
-				       *((u32 *)mEpTx->qh.ptr + j));
-		}
-	}
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	return n;
-}
-static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
-
-/**
- * show_registers: dumps all registers
- *
- * Check "device.h" for details
- */
-#define DUMP_ENTRIES	512
-static ssize_t show_registers(struct device *dev,
-			      struct device_attribute *attr, char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	u32 *dump;
-	unsigned i, k, n = 0;
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
-	if (!dump) {
-		dev_err(dev, "%s: out of memory\n", __func__);
-		return 0;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	k = hw_register_read(dump, DUMP_ENTRIES);
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	for (i = 0; i < k; i++) {
-		n += scnprintf(buf + n, PAGE_SIZE - n,
-			       "reg[0x%04X] = 0x%08X\n",
-			       i * (unsigned)sizeof(u32), dump[i]);
-	}
-	kfree(dump);
-
-	return n;
-}
-
-/**
- * store_registers: writes value to register address
- *
- * Check "device.h" for details
- */
-static ssize_t store_registers(struct device *dev,
-			       struct device_attribute *attr,
-			       const char *buf, size_t count)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long addr, data, flags;
-
-	dbg_trace("[%s] %p, %d\n", __func__, buf, count);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		goto done;
-	}
-
-	if (sscanf(buf, "%li %li", &addr, &data) != 2) {
-		dev_err(dev, "<addr> <data>: write data to register address");
-		goto done;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	if (hw_register_write(addr, data))
-		dev_err(dev, "invalid address range\n");
-	spin_unlock_irqrestore(udc->lock, flags);
-
- done:
-	return count;
-}
-static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
-		   show_registers, store_registers);
-
-/**
- * show_requests: DMA contents of all requests currently queued (all endpts)
- *
- * Check "device.h" for details
- */
-static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
-			     char *buf)
-{
-	struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
-	unsigned long flags;
-	struct list_head   *ptr = NULL;
-	struct ci13xxx_req *req = NULL;
-	unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
-
-	dbg_trace("[%s] %p\n", __func__, buf);
-	if (attr == NULL || buf == NULL) {
-		dev_err(dev, "[%s] EINVAL\n", __func__);
-		return 0;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-	for (i = 0; i < hw_ep_max; i++)
-		list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
-		{
-			req = list_entry(ptr, struct ci13xxx_req, queue);
-
-			n += scnprintf(buf + n, PAGE_SIZE - n,
-					"EP=%02i: TD=%08X %s\n",
-					i % hw_ep_max/2, (u32)req->dma,
-					((i < hw_ep_max/2) ? "RX" : "TX"));
-
-			for (j = 0; j < qSize; j++)
-				n += scnprintf(buf + n, PAGE_SIZE - n,
-						" %04X:    %08X\n", j,
-						*((u32 *)req->ptr + j));
-		}
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	return n;
-}
-static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
-
-/**
- * dbg_create_files: initializes the attribute interface
- * @dev: device
- *
- * This function returns an error code
- */
-__maybe_unused static int dbg_create_files(struct device *dev)
-{
-	int retval = 0;
-
-	if (dev == NULL)
-		return -EINVAL;
-	retval = device_create_file(dev, &dev_attr_device);
-	if (retval)
-		goto done;
-	retval = device_create_file(dev, &dev_attr_driver);
-	if (retval)
-		goto rm_device;
-	retval = device_create_file(dev, &dev_attr_events);
-	if (retval)
-		goto rm_driver;
-	retval = device_create_file(dev, &dev_attr_inters);
-	if (retval)
-		goto rm_events;
-	retval = device_create_file(dev, &dev_attr_port_test);
-	if (retval)
-		goto rm_inters;
-	retval = device_create_file(dev, &dev_attr_qheads);
-	if (retval)
-		goto rm_port_test;
-	retval = device_create_file(dev, &dev_attr_registers);
-	if (retval)
-		goto rm_qheads;
-	retval = device_create_file(dev, &dev_attr_requests);
-	if (retval)
-		goto rm_registers;
-	return 0;
-
- rm_registers:
-	device_remove_file(dev, &dev_attr_registers);
- rm_qheads:
-	device_remove_file(dev, &dev_attr_qheads);
- rm_port_test:
-	device_remove_file(dev, &dev_attr_port_test);
- rm_inters:
-	device_remove_file(dev, &dev_attr_inters);
- rm_events:
-	device_remove_file(dev, &dev_attr_events);
- rm_driver:
-	device_remove_file(dev, &dev_attr_driver);
- rm_device:
-	device_remove_file(dev, &dev_attr_device);
- done:
-	return retval;
-}
-
-/**
- * dbg_remove_files: destroys the attribute interface
- * @dev: device
- *
- * This function returns an error code
- */
-__maybe_unused static int dbg_remove_files(struct device *dev)
-{
-	if (dev == NULL)
-		return -EINVAL;
-	device_remove_file(dev, &dev_attr_requests);
-	device_remove_file(dev, &dev_attr_registers);
-	device_remove_file(dev, &dev_attr_qheads);
-	device_remove_file(dev, &dev_attr_port_test);
-	device_remove_file(dev, &dev_attr_inters);
-	device_remove_file(dev, &dev_attr_events);
-	device_remove_file(dev, &dev_attr_driver);
-	device_remove_file(dev, &dev_attr_device);
-	return 0;
-}
-
-/******************************************************************************
- * UTIL block
- *****************************************************************************/
-/**
- * _usb_addr: calculates endpoint address from direction & number
- * @ep:  endpoint
- */
-static inline u8 _usb_addr(struct ci13xxx_ep *ep)
-{
-	return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
-}
-
-/**
- * _hardware_queue: configures a request at hardware level
- * @gadget: gadget
- * @mEp:    endpoint
- *
- * This function returns an error code
- */
-static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
-{
-	unsigned i;
-	int ret = 0;
-	unsigned length = mReq->req.length;
-
-	trace("%p, %p", mEp, mReq);
-
-	/* don't queue twice */
-	if (mReq->req.status == -EALREADY)
-		return -EALREADY;
-
-	mReq->req.status = -EALREADY;
-	if (length && mReq->req.dma == DMA_ADDR_INVALID) {
-		mReq->req.dma = \
-			dma_map_single(mEp->device, mReq->req.buf,
-				       length, mEp->dir ? DMA_TO_DEVICE :
-				       DMA_FROM_DEVICE);
-		if (mReq->req.dma == 0)
-			return -ENOMEM;
-
-		mReq->map = 1;
-	}
-
-	if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
-		mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
-					   &mReq->zdma);
-		if (mReq->zptr == NULL) {
-			if (mReq->map) {
-				dma_unmap_single(mEp->device, mReq->req.dma,
-					length, mEp->dir ? DMA_TO_DEVICE :
-					DMA_FROM_DEVICE);
-				mReq->req.dma = DMA_ADDR_INVALID;
-				mReq->map     = 0;
-			}
-			return -ENOMEM;
-		}
-		memset(mReq->zptr, 0, sizeof(*mReq->zptr));
-		mReq->zptr->next    = TD_TERMINATE;
-		mReq->zptr->token   = TD_STATUS_ACTIVE;
-		if (!mReq->req.no_interrupt)
-			mReq->zptr->token   |= TD_IOC;
-	}
-	/*
-	 * TD configuration
-	 * TODO - handle requests which spawns into several TDs
-	 */
-	memset(mReq->ptr, 0, sizeof(*mReq->ptr));
-	mReq->ptr->token    = length << ffs_nr(TD_TOTAL_BYTES);
-	mReq->ptr->token   &= TD_TOTAL_BYTES;
-	mReq->ptr->token   |= TD_STATUS_ACTIVE;
-	if (mReq->zptr) {
-		mReq->ptr->next    = mReq->zdma;
-	} else {
-		mReq->ptr->next    = TD_TERMINATE;
-		if (!mReq->req.no_interrupt)
-			mReq->ptr->token  |= TD_IOC;
-	}
-	mReq->ptr->page[0]  = mReq->req.dma;
-	for (i = 1; i < 5; i++)
-		mReq->ptr->page[i] =
-			(mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
-
-	if (!list_empty(&mEp->qh.queue)) {
-		struct ci13xxx_req *mReqPrev;
-		int n = hw_ep_bit(mEp->num, mEp->dir);
-		int tmp_stat;
-
-		mReqPrev = list_entry(mEp->qh.queue.prev,
-				struct ci13xxx_req, queue);
-		if (mReqPrev->zptr)
-			mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
-		else
-			mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
-		wmb();
-		if (hw_cread(CAP_ENDPTPRIME, BIT(n)))
-			goto done;
-		do {
-			hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
-			tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n));
-		} while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW));
-		hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0);
-		if (tmp_stat)
-			goto done;
-	}
-
-	/*  QH configuration */
-	mEp->qh.ptr->td.next   = mReq->dma;    /* TERMINATE = 0 */
-	mEp->qh.ptr->td.token &= ~TD_STATUS;   /* clear status */
-	mEp->qh.ptr->cap |=  QH_ZLT;
-
-	wmb();   /* synchronize before ep prime */
-
-	ret = hw_ep_prime(mEp->num, mEp->dir,
-			   mEp->type == USB_ENDPOINT_XFER_CONTROL);
-done:
-	return ret;
-}
-
-/**
- * _hardware_dequeue: handles a request at hardware level
- * @gadget: gadget
- * @mEp:    endpoint
- *
- * This function returns an error code
- */
-static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
-{
-	trace("%p, %p", mEp, mReq);
-
-	if (mReq->req.status != -EALREADY)
-		return -EINVAL;
-
-	if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
-		return -EBUSY;
-
-	if (mReq->zptr) {
-		if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
-			return -EBUSY;
-		dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
-		mReq->zptr = NULL;
-	}
-
-	mReq->req.status = 0;
-
-	if (mReq->map) {
-		dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
-				 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-		mReq->req.dma = DMA_ADDR_INVALID;
-		mReq->map     = 0;
-	}
-
-	mReq->req.status = mReq->ptr->token & TD_STATUS;
-	if ((TD_STATUS_HALTED & mReq->req.status) != 0)
-		mReq->req.status = -1;
-	else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
-		mReq->req.status = -1;
-	else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
-		mReq->req.status = -1;
-
-	mReq->req.actual   = mReq->ptr->token & TD_TOTAL_BYTES;
-	mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
-	mReq->req.actual   = mReq->req.length - mReq->req.actual;
-	mReq->req.actual   = mReq->req.status ? 0 : mReq->req.actual;
-
-	return mReq->req.actual;
-}
-
-/**
- * _ep_nuke: dequeues all endpoint requests
- * @mEp: endpoint
- *
- * This function returns an error code
- * Caller must hold lock
- */
-static int _ep_nuke(struct ci13xxx_ep *mEp)
-__releases(mEp->lock)
-__acquires(mEp->lock)
-{
-	trace("%p", mEp);
-
-	if (mEp == NULL)
-		return -EINVAL;
-
-	hw_ep_flush(mEp->num, mEp->dir);
-
-	while (!list_empty(&mEp->qh.queue)) {
-
-		/* pop oldest request */
-		struct ci13xxx_req *mReq = \
-			list_entry(mEp->qh.queue.next,
-				   struct ci13xxx_req, queue);
-		list_del_init(&mReq->queue);
-		mReq->req.status = -ESHUTDOWN;
-
-		if (mReq->req.complete != NULL) {
-			spin_unlock(mEp->lock);
-			mReq->req.complete(&mEp->ep, &mReq->req);
-			spin_lock(mEp->lock);
-		}
-	}
-	return 0;
-}
-
-/**
- * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
- * @gadget: gadget
- *
- * This function returns an error code
- */
-static int _gadget_stop_activity(struct usb_gadget *gadget)
-{
-	struct usb_ep *ep;
-	struct ci13xxx    *udc = container_of(gadget, struct ci13xxx, gadget);
-	unsigned long flags;
-
-	trace("%p", gadget);
-
-	if (gadget == NULL)
-		return -EINVAL;
-
-	spin_lock_irqsave(udc->lock, flags);
-	udc->gadget.speed = USB_SPEED_UNKNOWN;
-	udc->remote_wakeup = 0;
-	udc->suspended = 0;
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	/* flush all endpoints */
-	gadget_for_each_ep(ep, gadget) {
-		usb_ep_fifo_flush(ep);
-	}
-	usb_ep_fifo_flush(&udc->ep0out.ep);
-	usb_ep_fifo_flush(&udc->ep0in.ep);
-
-	udc->driver->disconnect(gadget);
-
-	/* make sure to disable all endpoints */
-	gadget_for_each_ep(ep, gadget) {
-		usb_ep_disable(ep);
-	}
-
-	if (udc->status != NULL) {
-		usb_ep_free_request(&udc->ep0in.ep, udc->status);
-		udc->status = NULL;
-	}
-
-	return 0;
-}
-
-/******************************************************************************
- * ISR block
- *****************************************************************************/
-/**
- * isr_reset_handler: USB reset interrupt handler
- * @udc: UDC device
- *
- * This function resets USB engine after a bus reset occurred
- */
-static void isr_reset_handler(struct ci13xxx *udc)
-__releases(udc->lock)
-__acquires(udc->lock)
-{
-	int retval;
-
-	trace("%p", udc);
-
-	if (udc == NULL) {
-		err("EINVAL");
-		return;
-	}
-
-	dbg_event(0xFF, "BUS RST", 0);
-
-	spin_unlock(udc->lock);
-	retval = _gadget_stop_activity(&udc->gadget);
-	if (retval)
-		goto done;
-
-	retval = hw_usb_reset();
-	if (retval)
-		goto done;
-
-	udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
-	if (udc->status == NULL)
-		retval = -ENOMEM;
-
-	spin_lock(udc->lock);
-
- done:
-	if (retval)
-		err("error: %i", retval);
-}
-
-/**
- * isr_get_status_complete: get_status request complete function
- * @ep:  endpoint
- * @req: request handled
- *
- * Caller must release lock
- */
-static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
-{
-	trace("%p, %p", ep, req);
-
-	if (ep == NULL || req == NULL) {
-		err("EINVAL");
-		return;
-	}
-
-	kfree(req->buf);
-	usb_ep_free_request(ep, req);
-}
-
-/**
- * isr_get_status_response: get_status request response
- * @udc: udc struct
- * @setup: setup request packet
- *
- * This function returns an error code
- */
-static int isr_get_status_response(struct ci13xxx *udc,
-				   struct usb_ctrlrequest *setup)
-__releases(mEp->lock)
-__acquires(mEp->lock)
-{
-	struct ci13xxx_ep *mEp = &udc->ep0in;
-	struct usb_request *req = NULL;
-	gfp_t gfp_flags = GFP_ATOMIC;
-	int dir, num, retval;
-
-	trace("%p, %p", mEp, setup);
-
-	if (mEp == NULL || setup == NULL)
-		return -EINVAL;
-
-	spin_unlock(mEp->lock);
-	req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
-	spin_lock(mEp->lock);
-	if (req == NULL)
-		return -ENOMEM;
-
-	req->complete = isr_get_status_complete;
-	req->length   = 2;
-	req->buf      = kzalloc(req->length, gfp_flags);
-	if (req->buf == NULL) {
-		retval = -ENOMEM;
-		goto err_free_req;
-	}
-
-	if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
-		/* Assume that device is bus powered for now. */
-		*((u16 *)req->buf) = _udc->remote_wakeup << 1;
-		retval = 0;
-	} else if ((setup->bRequestType & USB_RECIP_MASK) \
-		   == USB_RECIP_ENDPOINT) {
-		dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
-			TX : RX;
-		num =  le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
-		*((u16 *)req->buf) = hw_ep_get_halt(num, dir);
-	}
-	/* else do nothing; reserved for future use */
-
-	spin_unlock(mEp->lock);
-	retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
-	spin_lock(mEp->lock);
-	if (retval)
-		goto err_free_buf;
-
-	return 0;
-
- err_free_buf:
-	kfree(req->buf);
- err_free_req:
-	spin_unlock(mEp->lock);
-	usb_ep_free_request(&mEp->ep, req);
-	spin_lock(mEp->lock);
-	return retval;
-}
-
-/**
- * isr_setup_status_complete: setup_status request complete function
- * @ep:  endpoint
- * @req: request handled
- *
- * Caller must release lock. Put the port in test mode if test mode
- * feature is selected.
- */
-static void
-isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
-{
-	struct ci13xxx *udc = req->context;
-	unsigned long flags;
-
-	trace("%p, %p", ep, req);
-
-	spin_lock_irqsave(udc->lock, flags);
-	if (udc->test_mode)
-		hw_port_test_set(udc->test_mode);
-	spin_unlock_irqrestore(udc->lock, flags);
-}
-
-/**
- * isr_setup_status_phase: queues the status phase of a setup transation
- * @udc: udc struct
- *
- * This function returns an error code
- */
-static int isr_setup_status_phase(struct ci13xxx *udc)
-__releases(mEp->lock)
-__acquires(mEp->lock)
-{
-	int retval;
-	struct ci13xxx_ep *mEp;
-
-	trace("%p", udc);
-
-	mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
-	udc->status->context = udc;
-	udc->status->complete = isr_setup_status_complete;
-
-	spin_unlock(mEp->lock);
-	retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
-	spin_lock(mEp->lock);
-
-	return retval;
-}
-
-/**
- * isr_tr_complete_low: transaction complete low level handler
- * @mEp: endpoint
- *
- * This function returns an error code
- * Caller must hold lock
- */
-static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
-__releases(mEp->lock)
-__acquires(mEp->lock)
-{
-	struct ci13xxx_req *mReq, *mReqTemp;
-	struct ci13xxx_ep *mEpTemp = mEp;
-	int uninitialized_var(retval);
-
-	trace("%p", mEp);
-
-	if (list_empty(&mEp->qh.queue))
-		return -EINVAL;
-
-	list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
-			queue) {
-		retval = _hardware_dequeue(mEp, mReq);
-		if (retval < 0)
-			break;
-		list_del_init(&mReq->queue);
-		dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
-		if (mReq->req.complete != NULL) {
-			spin_unlock(mEp->lock);
-			if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
-					mReq->req.length)
-				mEpTemp = &_udc->ep0in;
-			mReq->req.complete(&mEpTemp->ep, &mReq->req);
-			spin_lock(mEp->lock);
-		}
-	}
-
-	if (retval == -EBUSY)
-		retval = 0;
-	if (retval < 0)
-		dbg_event(_usb_addr(mEp), "DONE", retval);
-
-	return retval;
-}
-
-/**
- * isr_tr_complete_handler: transaction complete interrupt handler
- * @udc: UDC descriptor
- *
- * This function handles traffic events
- */
-static void isr_tr_complete_handler(struct ci13xxx *udc)
-__releases(udc->lock)
-__acquires(udc->lock)
-{
-	unsigned i;
-	u8 tmode = 0;
-
-	trace("%p", udc);
-
-	if (udc == NULL) {
-		err("EINVAL");
-		return;
-	}
-
-	for (i = 0; i < hw_ep_max; i++) {
-		struct ci13xxx_ep *mEp  = &udc->ci13xxx_ep[i];
-		int type, num, dir, err = -EINVAL;
-		struct usb_ctrlrequest req;
-
-		if (mEp->desc == NULL)
-			continue;   /* not configured */
-
-		if (hw_test_and_clear_complete(i)) {
-			err = isr_tr_complete_low(mEp);
-			if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
-				if (err > 0)   /* needs status phase */
-					err = isr_setup_status_phase(udc);
-				if (err < 0) {
-					dbg_event(_usb_addr(mEp),
-						  "ERROR", err);
-					spin_unlock(udc->lock);
-					if (usb_ep_set_halt(&mEp->ep))
-						err("error: ep_set_halt");
-					spin_lock(udc->lock);
-				}
-			}
-		}
-
-		if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
-		    !hw_test_and_clear_setup_status(i))
-			continue;
-
-		if (i != 0) {
-			warn("ctrl traffic received at endpoint");
-			continue;
-		}
-
-		/*
-		 * Flush data and handshake transactions of previous
-		 * setup packet.
-		 */
-		_ep_nuke(&udc->ep0out);
-		_ep_nuke(&udc->ep0in);
-
-		/* read_setup_packet */
-		do {
-			hw_test_and_set_setup_guard();
-			memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
-		} while (!hw_test_and_clear_setup_guard());
-
-		type = req.bRequestType;
-
-		udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
-
-		dbg_setup(_usb_addr(mEp), &req);
-
-		switch (req.bRequest) {
-		case USB_REQ_CLEAR_FEATURE:
-			if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
-					le16_to_cpu(req.wValue) ==
-					USB_ENDPOINT_HALT) {
-				if (req.wLength != 0)
-					break;
-				num  = le16_to_cpu(req.wIndex);
-				dir = num & USB_ENDPOINT_DIR_MASK;
-				num &= USB_ENDPOINT_NUMBER_MASK;
-				if (dir) /* TX */
-					num += hw_ep_max/2;
-				if (!udc->ci13xxx_ep[num].wedge) {
-					spin_unlock(udc->lock);
-					err = usb_ep_clear_halt(
-						&udc->ci13xxx_ep[num].ep);
-					spin_lock(udc->lock);
-					if (err)
-						break;
-				}
-				err = isr_setup_status_phase(udc);
-			} else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
-					le16_to_cpu(req.wValue) ==
-					USB_DEVICE_REMOTE_WAKEUP) {
-				if (req.wLength != 0)
-					break;
-				udc->remote_wakeup = 0;
-				err = isr_setup_status_phase(udc);
-			} else {
-				goto delegate;
-			}
-			break;
-		case USB_REQ_GET_STATUS:
-			if (type != (USB_DIR_IN|USB_RECIP_DEVICE)   &&
-			    type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
-			    type != (USB_DIR_IN|USB_RECIP_INTERFACE))
-				goto delegate;
-			if (le16_to_cpu(req.wLength) != 2 ||
-			    le16_to_cpu(req.wValue)  != 0)
-				break;
-			err = isr_get_status_response(udc, &req);
-			break;
-		case USB_REQ_SET_ADDRESS:
-			if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
-				goto delegate;
-			if (le16_to_cpu(req.wLength) != 0 ||
-			    le16_to_cpu(req.wIndex)  != 0)
-				break;
-			err = hw_usb_set_address((u8)le16_to_cpu(req.wValue));
-			if (err)
-				break;
-			err = isr_setup_status_phase(udc);
-			break;
-		case USB_REQ_SET_FEATURE:
-			if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
-					le16_to_cpu(req.wValue) ==
-					USB_ENDPOINT_HALT) {
-				if (req.wLength != 0)
-					break;
-				num  = le16_to_cpu(req.wIndex);
-				dir = num & USB_ENDPOINT_DIR_MASK;
-				num &= USB_ENDPOINT_NUMBER_MASK;
-				if (dir) /* TX */
-					num += hw_ep_max/2;
-
-				spin_unlock(udc->lock);
-				err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
-				spin_lock(udc->lock);
-				if (!err)
-					isr_setup_status_phase(udc);
-			} else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
-				if (req.wLength != 0)
-					break;
-				switch (le16_to_cpu(req.wValue)) {
-				case USB_DEVICE_REMOTE_WAKEUP:
-					udc->remote_wakeup = 1;
-					err = isr_setup_status_phase(udc);
-					break;
-				case USB_DEVICE_TEST_MODE:
-					tmode = le16_to_cpu(req.wIndex) >> 8;
-					switch (tmode) {
-					case TEST_J:
-					case TEST_K:
-					case TEST_SE0_NAK:
-					case TEST_PACKET:
-					case TEST_FORCE_EN:
-						udc->test_mode = tmode;
-						err = isr_setup_status_phase(
-								udc);
-						break;
-					default:
-						break;
-					}
-				default:
-					goto delegate;
-				}
-			} else {
-				goto delegate;
-			}
-			break;
-		default:
-delegate:
-			if (req.wLength == 0)   /* no data phase */
-				udc->ep0_dir = TX;
-
-			spin_unlock(udc->lock);
-			err = udc->driver->setup(&udc->gadget, &req);
-			spin_lock(udc->lock);
-			break;
-		}
-
-		if (err < 0) {
-			dbg_event(_usb_addr(mEp), "ERROR", err);
-
-			spin_unlock(udc->lock);
-			if (usb_ep_set_halt(&mEp->ep))
-				err("error: ep_set_halt");
-			spin_lock(udc->lock);
-		}
-	}
-}
-
-/******************************************************************************
- * ENDPT block
- *****************************************************************************/
-/**
- * ep_enable: configure endpoint, making it usable
- *
- * Check usb_ep_enable() at "usb_gadget.h" for details
- */
-static int ep_enable(struct usb_ep *ep,
-		     const struct usb_endpoint_descriptor *desc)
-{
-	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
-	int retval = 0;
-	unsigned long flags;
-
-	trace("%p, %p", ep, desc);
-
-	if (ep == NULL || desc == NULL)
-		return -EINVAL;
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	/* only internal SW should enable ctrl endpts */
-
-	mEp->desc = desc;
-
-	if (!list_empty(&mEp->qh.queue))
-		warn("enabling a non-empty endpoint!");
-
-	mEp->dir  = usb_endpoint_dir_in(desc) ? TX : RX;
-	mEp->num  = usb_endpoint_num(desc);
-	mEp->type = usb_endpoint_type(desc);
-
-	mEp->ep.maxpacket = usb_endpoint_maxp(desc);
-
-	dbg_event(_usb_addr(mEp), "ENABLE", 0);
-
-	mEp->qh.ptr->cap = 0;
-
-	if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
-		mEp->qh.ptr->cap |=  QH_IOS;
-	else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
-		mEp->qh.ptr->cap &= ~QH_MULT;
-	else
-		mEp->qh.ptr->cap &= ~QH_ZLT;
-
-	mEp->qh.ptr->cap |=
-		(mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
-	mEp->qh.ptr->td.next |= TD_TERMINATE;   /* needed? */
-
-	/*
-	 * Enable endpoints in the HW other than ep0 as ep0
-	 * is always enabled
-	 */
-	if (mEp->num)
-		retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-	return retval;
-}
-
-/**
- * ep_disable: endpoint is no longer usable
- *
- * Check usb_ep_disable() at "usb_gadget.h" for details
- */
-static int ep_disable(struct usb_ep *ep)
-{
-	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
-	int direction, retval = 0;
-	unsigned long flags;
-
-	trace("%p", ep);
-
-	if (ep == NULL)
-		return -EINVAL;
-	else if (mEp->desc == NULL)
-		return -EBUSY;
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	/* only internal SW should disable ctrl endpts */
-
-	direction = mEp->dir;
-	do {
-		dbg_event(_usb_addr(mEp), "DISABLE", 0);
-
-		retval |= _ep_nuke(mEp);
-		retval |= hw_ep_disable(mEp->num, mEp->dir);
-
-		if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
-			mEp->dir = (mEp->dir == TX) ? RX : TX;
-
-	} while (mEp->dir != direction);
-
-	mEp->desc = NULL;
-	mEp->ep.desc = NULL;
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-	return retval;
-}
-
-/**
- * ep_alloc_request: allocate a request object to use with this endpoint
- *
- * Check usb_ep_alloc_request() at "usb_gadget.h" for details
- */
-static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
-{
-	struct ci13xxx_ep  *mEp  = container_of(ep, struct ci13xxx_ep, ep);
-	struct ci13xxx_req *mReq = NULL;
-
-	trace("%p, %i", ep, gfp_flags);
-
-	if (ep == NULL) {
-		err("EINVAL");
-		return NULL;
-	}
-
-	mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
-	if (mReq != NULL) {
-		INIT_LIST_HEAD(&mReq->queue);
-		mReq->req.dma = DMA_ADDR_INVALID;
-
-		mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
-					   &mReq->dma);
-		if (mReq->ptr == NULL) {
-			kfree(mReq);
-			mReq = NULL;
-		}
-	}
-
-	dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
-
-	return (mReq == NULL) ? NULL : &mReq->req;
-}
-
-/**
- * ep_free_request: frees a request object
- *
- * Check usb_ep_free_request() at "usb_gadget.h" for details
- */
-static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
-{
-	struct ci13xxx_ep  *mEp  = container_of(ep,  struct ci13xxx_ep, ep);
-	struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
-	unsigned long flags;
-
-	trace("%p, %p", ep, req);
-
-	if (ep == NULL || req == NULL) {
-		err("EINVAL");
-		return;
-	} else if (!list_empty(&mReq->queue)) {
-		err("EBUSY");
-		return;
-	}
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	if (mReq->ptr)
-		dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
-	kfree(mReq);
-
-	dbg_event(_usb_addr(mEp), "FREE", 0);
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-}
-
-/**
- * ep_queue: queues (submits) an I/O request to an endpoint
- *
- * Check usb_ep_queue()* at usb_gadget.h" for details
- */
-static int ep_queue(struct usb_ep *ep, struct usb_request *req,
-		    gfp_t __maybe_unused gfp_flags)
-{
-	struct ci13xxx_ep  *mEp  = container_of(ep,  struct ci13xxx_ep, ep);
-	struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
-	int retval = 0;
-	unsigned long flags;
-
-	trace("%p, %p, %X", ep, req, gfp_flags);
-
-	if (ep == NULL || req == NULL || mEp->desc == NULL)
-		return -EINVAL;
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
-		if (req->length)
-			mEp = (_udc->ep0_dir == RX) ?
-				&_udc->ep0out : &_udc->ep0in;
-		if (!list_empty(&mEp->qh.queue)) {
-			_ep_nuke(mEp);
-			retval = -EOVERFLOW;
-			warn("endpoint ctrl %X nuked", _usb_addr(mEp));
-		}
-	}
-
-	/* first nuke then test link, e.g. previous status has not sent */
-	if (!list_empty(&mReq->queue)) {
-		retval = -EBUSY;
-		err("request already in queue");
-		goto done;
-	}
-
-	if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
-		req->length = (4 * CI13XXX_PAGE_SIZE);
-		retval = -EMSGSIZE;
-		warn("request length truncated");
-	}
-
-	dbg_queue(_usb_addr(mEp), req, retval);
-
-	/* push request */
-	mReq->req.status = -EINPROGRESS;
-	mReq->req.actual = 0;
-
-	retval = _hardware_enqueue(mEp, mReq);
-
-	if (retval == -EALREADY) {
-		dbg_event(_usb_addr(mEp), "QUEUE", retval);
-		retval = 0;
-	}
-	if (!retval)
-		list_add_tail(&mReq->queue, &mEp->qh.queue);
-
- done:
-	spin_unlock_irqrestore(mEp->lock, flags);
-	return retval;
-}
-
-/**
- * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
- *
- * Check usb_ep_dequeue() at "usb_gadget.h" for details
- */
-static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
-{
-	struct ci13xxx_ep  *mEp  = container_of(ep,  struct ci13xxx_ep, ep);
-	struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
-	unsigned long flags;
-
-	trace("%p, %p", ep, req);
-
-	if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
-		mEp->desc == NULL || list_empty(&mReq->queue) ||
-		list_empty(&mEp->qh.queue))
-		return -EINVAL;
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
-
-	hw_ep_flush(mEp->num, mEp->dir);
-
-	/* pop request */
-	list_del_init(&mReq->queue);
-	if (mReq->map) {
-		dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
-				 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-		mReq->req.dma = DMA_ADDR_INVALID;
-		mReq->map     = 0;
-	}
-	req->status = -ECONNRESET;
-
-	if (mReq->req.complete != NULL) {
-		spin_unlock(mEp->lock);
-		mReq->req.complete(&mEp->ep, &mReq->req);
-		spin_lock(mEp->lock);
-	}
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-	return 0;
-}
-
-/**
- * ep_set_halt: sets the endpoint halt feature
- *
- * Check usb_ep_set_halt() at "usb_gadget.h" for details
- */
-static int ep_set_halt(struct usb_ep *ep, int value)
-{
-	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
-	int direction, retval = 0;
-	unsigned long flags;
-
-	trace("%p, %i", ep, value);
-
-	if (ep == NULL || mEp->desc == NULL)
-		return -EINVAL;
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-#ifndef STALL_IN
-	/* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
-	if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
-	    !list_empty(&mEp->qh.queue)) {
-		spin_unlock_irqrestore(mEp->lock, flags);
-		return -EAGAIN;
-	}
-#endif
-
-	direction = mEp->dir;
-	do {
-		dbg_event(_usb_addr(mEp), "HALT", value);
-		retval |= hw_ep_set_halt(mEp->num, mEp->dir, value);
-
-		if (!value)
-			mEp->wedge = 0;
-
-		if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
-			mEp->dir = (mEp->dir == TX) ? RX : TX;
-
-	} while (mEp->dir != direction);
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-	return retval;
-}
-
-/**
- * ep_set_wedge: sets the halt feature and ignores clear requests
- *
- * Check usb_ep_set_wedge() at "usb_gadget.h" for details
- */
-static int ep_set_wedge(struct usb_ep *ep)
-{
-	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
-	unsigned long flags;
-
-	trace("%p", ep);
-
-	if (ep == NULL || mEp->desc == NULL)
-		return -EINVAL;
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	dbg_event(_usb_addr(mEp), "WEDGE", 0);
-	mEp->wedge = 1;
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-
-	return usb_ep_set_halt(ep);
-}
-
-/**
- * ep_fifo_flush: flushes contents of a fifo
- *
- * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
- */
-static void ep_fifo_flush(struct usb_ep *ep)
-{
-	struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
-	unsigned long flags;
-
-	trace("%p", ep);
-
-	if (ep == NULL) {
-		err("%02X: -EINVAL", _usb_addr(mEp));
-		return;
-	}
-
-	spin_lock_irqsave(mEp->lock, flags);
-
-	dbg_event(_usb_addr(mEp), "FFLUSH", 0);
-	hw_ep_flush(mEp->num, mEp->dir);
-
-	spin_unlock_irqrestore(mEp->lock, flags);
-}
-
-/**
- * Endpoint-specific part of the API to the USB controller hardware
- * Check "usb_gadget.h" for details
- */
-static const struct usb_ep_ops usb_ep_ops = {
-	.enable	       = ep_enable,
-	.disable       = ep_disable,
-	.alloc_request = ep_alloc_request,
-	.free_request  = ep_free_request,
-	.queue	       = ep_queue,
-	.dequeue       = ep_dequeue,
-	.set_halt      = ep_set_halt,
-	.set_wedge     = ep_set_wedge,
-	.fifo_flush    = ep_fifo_flush,
-};
-
-/******************************************************************************
- * GADGET block
- *****************************************************************************/
-static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
-{
-	struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
-	unsigned long flags;
-	int gadget_ready = 0;
-
-	if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
-		return -EOPNOTSUPP;
-
-	spin_lock_irqsave(udc->lock, flags);
-	udc->vbus_active = is_active;
-	if (udc->driver)
-		gadget_ready = 1;
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	if (gadget_ready) {
-		if (is_active) {
-			pm_runtime_get_sync(&_gadget->dev);
-			hw_device_reset(udc);
-			hw_device_state(udc->ep0out.qh.dma);
-		} else {
-			hw_device_state(0);
-			if (udc->udc_driver->notify_event)
-				udc->udc_driver->notify_event(udc,
-				CI13XXX_CONTROLLER_STOPPED_EVENT);
-			_gadget_stop_activity(&udc->gadget);
-			pm_runtime_put_sync(&_gadget->dev);
-		}
-	}
-
-	return 0;
-}
-
-static int ci13xxx_wakeup(struct usb_gadget *_gadget)
-{
-	struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
-	unsigned long flags;
-	int ret = 0;
-
-	trace();
-
-	spin_lock_irqsave(udc->lock, flags);
-	if (!udc->remote_wakeup) {
-		ret = -EOPNOTSUPP;
-		trace("remote wakeup feature is not enabled\n");
-		goto out;
-	}
-	if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
-		ret = -EINVAL;
-		trace("port is not suspended\n");
-		goto out;
-	}
-	hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
-out:
-	spin_unlock_irqrestore(udc->lock, flags);
-	return ret;
-}
-
-static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
-{
-	struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
-
-	if (udc->transceiver)
-		return usb_phy_set_power(udc->transceiver, mA);
-	return -ENOTSUPP;
-}
-
-static int ci13xxx_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *));
-static int ci13xxx_stop(struct usb_gadget_driver *driver);
-/**
- * Device operations part of the API to the USB controller hardware,
- * which don't involve endpoints (or i/o)
- * Check  "usb_gadget.h" for details
- */
-static const struct usb_gadget_ops usb_gadget_ops = {
-	.vbus_session	= ci13xxx_vbus_session,
-	.wakeup		= ci13xxx_wakeup,
-	.vbus_draw	= ci13xxx_vbus_draw,
-	.start		= ci13xxx_start,
-	.stop		= ci13xxx_stop,
-};
-
-/**
- * ci13xxx_start: 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.
- * Interrupts are enabled here.
- */
-static int ci13xxx_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
-{
-	struct ci13xxx *udc = _udc;
-	unsigned long flags;
-	int i, j;
-	int retval = -ENOMEM;
-
-	trace("%p", driver);
-
-	if (driver             == NULL ||
-	    bind               == NULL ||
-	    driver->setup      == NULL ||
-	    driver->disconnect == NULL)
-		return -EINVAL;
-	else if (udc         == NULL)
-		return -ENODEV;
-	else if (udc->driver != NULL)
-		return -EBUSY;
-
-	/* alloc resources */
-	udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
-				       sizeof(struct ci13xxx_qh),
-				       64, CI13XXX_PAGE_SIZE);
-	if (udc->qh_pool == NULL)
-		return -ENOMEM;
-
-	udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
-				       sizeof(struct ci13xxx_td),
-				       64, CI13XXX_PAGE_SIZE);
-	if (udc->td_pool == NULL) {
-		dma_pool_destroy(udc->qh_pool);
-		udc->qh_pool = NULL;
-		return -ENOMEM;
-	}
-
-	spin_lock_irqsave(udc->lock, flags);
-
-	info("hw_ep_max = %d", hw_ep_max);
-
-	udc->gadget.dev.driver = NULL;
-
-	retval = 0;
-	for (i = 0; i < hw_ep_max/2; i++) {
-		for (j = RX; j <= TX; j++) {
-			int k = i + j * hw_ep_max/2;
-			struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
-
-			scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
-					(j == TX)  ? "in" : "out");
-
-			mEp->lock         = udc->lock;
-			mEp->device       = &udc->gadget.dev;
-			mEp->td_pool      = udc->td_pool;
-
-			mEp->ep.name      = mEp->name;
-			mEp->ep.ops       = &usb_ep_ops;
-			mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
-
-			INIT_LIST_HEAD(&mEp->qh.queue);
-			spin_unlock_irqrestore(udc->lock, flags);
-			mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
-					&mEp->qh.dma);
-			spin_lock_irqsave(udc->lock, flags);
-			if (mEp->qh.ptr == NULL)
-				retval = -ENOMEM;
-			else
-				memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
-
-			/* skip ep0 out and in endpoints */
-			if (i == 0)
-				continue;
-
-			list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
-		}
-	}
-	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);
-	if (retval)
-		return retval;
-
-	udc->ep0in.ep.desc = &ctrl_endpt_in_desc;
-	retval = usb_ep_enable(&udc->ep0in.ep);
-	if (retval)
-		return retval;
-	spin_lock_irqsave(udc->lock, flags);
-
-	udc->gadget.ep0 = &udc->ep0in.ep;
-	/* bind gadget */
-	driver->driver.bus     = NULL;
-	udc->gadget.dev.driver = &driver->driver;
-
-	spin_unlock_irqrestore(udc->lock, flags);
-	retval = bind(&udc->gadget);                /* MAY SLEEP */
-	spin_lock_irqsave(udc->lock, flags);
-
-	if (retval) {
-		udc->gadget.dev.driver = NULL;
-		goto done;
-	}
-
-	udc->driver = driver;
-	pm_runtime_get_sync(&udc->gadget.dev);
-	if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
-		if (udc->vbus_active) {
-			if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
-				hw_device_reset(udc);
-		} else {
-			pm_runtime_put_sync(&udc->gadget.dev);
-			goto done;
-		}
-	}
-
-	retval = hw_device_state(udc->ep0out.qh.dma);
-	if (retval)
-		pm_runtime_put_sync(&udc->gadget.dev);
-
- done:
-	spin_unlock_irqrestore(udc->lock, flags);
-	return retval;
-}
-
-/**
- * ci13xxx_stop: unregister a gadget driver
- *
- * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
- */
-static int ci13xxx_stop(struct usb_gadget_driver *driver)
-{
-	struct ci13xxx *udc = _udc;
-	unsigned long i, flags;
-
-	trace("%p", driver);
-
-	if (driver             == NULL ||
-	    driver->unbind     == NULL ||
-	    driver->setup      == NULL ||
-	    driver->disconnect == NULL ||
-	    driver             != udc->driver)
-		return -EINVAL;
-
-	spin_lock_irqsave(udc->lock, flags);
-
-	if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
-			udc->vbus_active) {
-		hw_device_state(0);
-		if (udc->udc_driver->notify_event)
-			udc->udc_driver->notify_event(udc,
-			CI13XXX_CONTROLLER_STOPPED_EVENT);
-		spin_unlock_irqrestore(udc->lock, flags);
-		_gadget_stop_activity(&udc->gadget);
-		spin_lock_irqsave(udc->lock, flags);
-		pm_runtime_put(&udc->gadget.dev);
-	}
-
-	/* unbind gadget */
-	spin_unlock_irqrestore(udc->lock, flags);
-	driver->unbind(&udc->gadget);               /* MAY SLEEP */
-	spin_lock_irqsave(udc->lock, flags);
-
-	udc->gadget.dev.driver = NULL;
-
-	/* free resources */
-	for (i = 0; i < hw_ep_max; i++) {
-		struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
-
-		if (!list_empty(&mEp->ep.ep_list))
-			list_del_init(&mEp->ep.ep_list);
-
-		if (mEp->qh.ptr != NULL)
-			dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
-	}
-
-	udc->gadget.ep0 = NULL;
-	udc->driver = NULL;
-
-	spin_unlock_irqrestore(udc->lock, flags);
-
-	if (udc->td_pool != NULL) {
-		dma_pool_destroy(udc->td_pool);
-		udc->td_pool = NULL;
-	}
-	if (udc->qh_pool != NULL) {
-		dma_pool_destroy(udc->qh_pool);
-		udc->qh_pool = NULL;
-	}
-
-	return 0;
-}
-
-/******************************************************************************
- * BUS block
- *****************************************************************************/
-/**
- * udc_irq: global interrupt handler
- *
- * This function returns IRQ_HANDLED if the IRQ has been handled
- * It locks access to registers
- */
-static irqreturn_t udc_irq(void)
-{
-	struct ci13xxx *udc = _udc;
-	irqreturn_t retval;
-	u32 intr;
-
-	trace();
-
-	if (udc == NULL) {
-		err("ENODEV");
-		return IRQ_HANDLED;
-	}
-
-	spin_lock(udc->lock);
-
-	if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
-		if (hw_cread(CAP_USBMODE, USBMODE_CM) !=
-				USBMODE_CM_DEVICE) {
-			spin_unlock(udc->lock);
-			return IRQ_NONE;
-		}
-	}
-	intr = hw_test_and_clear_intr_active();
-	if (intr) {
-		isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
-		isr_statistics.hndl.idx &= ISR_MASK;
-		isr_statistics.hndl.cnt++;
-
-		/* order defines priority - do NOT change it */
-		if (USBi_URI & intr) {
-			isr_statistics.uri++;
-			isr_reset_handler(udc);
-		}
-		if (USBi_PCI & intr) {
-			isr_statistics.pci++;
-			udc->gadget.speed = hw_port_is_high_speed() ?
-				USB_SPEED_HIGH : USB_SPEED_FULL;
-			if (udc->suspended && udc->driver->resume) {
-				spin_unlock(udc->lock);
-				udc->driver->resume(&udc->gadget);
-				spin_lock(udc->lock);
-				udc->suspended = 0;
-			}
-		}
-		if (USBi_UEI & intr)
-			isr_statistics.uei++;
-		if (USBi_UI  & intr) {
-			isr_statistics.ui++;
-			isr_tr_complete_handler(udc);
-		}
-		if (USBi_SLI & intr) {
-			if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
-			    udc->driver->suspend) {
-				udc->suspended = 1;
-				spin_unlock(udc->lock);
-				udc->driver->suspend(&udc->gadget);
-				spin_lock(udc->lock);
-			}
-			isr_statistics.sli++;
-		}
-		retval = IRQ_HANDLED;
-	} else {
-		isr_statistics.none++;
-		retval = IRQ_NONE;
-	}
-	spin_unlock(udc->lock);
-
-	return retval;
-}
-
-/**
- * udc_release: driver release function
- * @dev: device
- *
- * Currently does nothing
- */
-static void udc_release(struct device *dev)
-{
-	trace("%p", dev);
-
-	if (dev == NULL)
-		err("EINVAL");
-}
-
-/**
- * udc_probe: parent probe must call this to initialize UDC
- * @dev:  parent device
- * @regs: registers base address
- * @name: driver name
- *
- * This function returns an error code
- * No interrupts active, the IRQ has not been requested yet
- * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
- */
-static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
-		void __iomem *regs)
-{
-	struct ci13xxx *udc;
-	int retval = 0;
-
-	trace("%p, %p, %p", dev, regs, driver->name);
-
-	if (dev == NULL || regs == NULL || driver == NULL ||
-			driver->name == NULL)
-		return -EINVAL;
-
-	udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
-	if (udc == NULL)
-		return -ENOMEM;
-
-	udc->lock = &udc_lock;
-	udc->regs = regs;
-	udc->udc_driver = driver;
-
-	udc->gadget.ops          = &usb_gadget_ops;
-	udc->gadget.speed        = USB_SPEED_UNKNOWN;
-	udc->gadget.max_speed    = USB_SPEED_HIGH;
-	udc->gadget.is_otg       = 0;
-	udc->gadget.name         = driver->name;
-
-	INIT_LIST_HEAD(&udc->gadget.ep_list);
-	udc->gadget.ep0 = NULL;
-
-	dev_set_name(&udc->gadget.dev, "gadget");
-	udc->gadget.dev.dma_mask = dev->dma_mask;
-	udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
-	udc->gadget.dev.parent   = dev;
-	udc->gadget.dev.release  = udc_release;
-
-	retval = hw_device_init(regs);
-	if (retval < 0)
-		goto free_udc;
-
-	udc->transceiver = usb_get_transceiver();
-
-	if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
-		if (udc->transceiver == NULL) {
-			retval = -ENODEV;
-			goto free_udc;
-		}
-	}
-
-	if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
-		retval = hw_device_reset(udc);
-		if (retval)
-			goto put_transceiver;
-	}
-
-	retval = device_register(&udc->gadget.dev);
-	if (retval) {
-		put_device(&udc->gadget.dev);
-		goto put_transceiver;
-	}
-
-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
-	retval = dbg_create_files(&udc->gadget.dev);
-#endif
-	if (retval)
-		goto unreg_device;
-
-	if (udc->transceiver) {
-		retval = otg_set_peripheral(udc->transceiver->otg,
-						&udc->gadget);
-		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->otg, &udc->gadget);
-		usb_put_transceiver(udc->transceiver);
-	}
-
-	err("error = %i", retval);
-remove_dbg:
-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
-	dbg_remove_files(&udc->gadget.dev);
-#endif
-unreg_device:
-	device_unregister(&udc->gadget.dev);
-put_transceiver:
-	if (udc->transceiver)
-		usb_put_transceiver(udc->transceiver);
-free_udc:
-	kfree(udc);
-	_udc = NULL;
-	return retval;
-}
-
-/**
- * udc_remove: parent remove must call this to remove UDC
- *
- * No interrupts active, the IRQ has been released
- */
-static void udc_remove(void)
-{
-	struct ci13xxx *udc = _udc;
-
-	if (udc == NULL) {
-		err("EINVAL");
-		return;
-	}
-	usb_del_gadget_udc(&udc->gadget);
-
-	if (udc->transceiver) {
-		otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
-		usb_put_transceiver(udc->transceiver);
-	}
-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
-	dbg_remove_files(&udc->gadget.dev);
-#endif
-	device_unregister(&udc->gadget.dev);
-
-	kfree(udc);
-	_udc = NULL;
-}
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
deleted file mode 100644
index 0d31af5..0000000
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * ci13xxx_udc.h - structures, registers, and macros MIPS USB IP core
- *
- * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
- *
- * Author: David Lopo
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Description: MIPS USB IP core family device controller
- *              Structures, registers and logging macros
- */
-
-#ifndef _CI13XXX_h_
-#define _CI13XXX_h_
-
-/******************************************************************************
- * DEFINE
- *****************************************************************************/
-#define CI13XXX_PAGE_SIZE  4096ul /* page size for TD's */
-#define ENDPT_MAX          (32)
-#define CTRL_PAYLOAD_MAX   (64)
-#define RX        (0)  /* similar to USB_DIR_OUT but can be used as an index */
-#define TX        (1)  /* similar to USB_DIR_IN  but can be used as an index */
-
-/******************************************************************************
- * STRUCTURES
- *****************************************************************************/
-/* DMA layout of transfer descriptors */
-struct ci13xxx_td {
-	/* 0 */
-	u32 next;
-#define TD_TERMINATE          BIT(0)
-#define TD_ADDR_MASK          (0xFFFFFFEUL << 5)
-	/* 1 */
-	u32 token;
-#define TD_STATUS             (0x00FFUL <<  0)
-#define TD_STATUS_TR_ERR      BIT(3)
-#define TD_STATUS_DT_ERR      BIT(5)
-#define TD_STATUS_HALTED      BIT(6)
-#define TD_STATUS_ACTIVE      BIT(7)
-#define TD_MULTO              (0x0003UL << 10)
-#define TD_IOC                BIT(15)
-#define TD_TOTAL_BYTES        (0x7FFFUL << 16)
-	/* 2 */
-	u32 page[5];
-#define TD_CURR_OFFSET        (0x0FFFUL <<  0)
-#define TD_FRAME_NUM          (0x07FFUL <<  0)
-#define TD_RESERVED_MASK      (0x0FFFUL <<  0)
-} __attribute__ ((packed));
-
-/* DMA layout of queue heads */
-struct ci13xxx_qh {
-	/* 0 */
-	u32 cap;
-#define QH_IOS                BIT(15)
-#define QH_MAX_PKT            (0x07FFUL << 16)
-#define QH_ZLT                BIT(29)
-#define QH_MULT               (0x0003UL << 30)
-	/* 1 */
-	u32 curr;
-	/* 2 - 8 */
-	struct ci13xxx_td        td;
-	/* 9 */
-	u32 RESERVED;
-	struct usb_ctrlrequest   setup;
-} __attribute__ ((packed));
-
-/* Extension of usb_request */
-struct ci13xxx_req {
-	struct usb_request   req;
-	unsigned             map;
-	struct list_head     queue;
-	struct ci13xxx_td   *ptr;
-	dma_addr_t           dma;
-	struct ci13xxx_td   *zptr;
-	dma_addr_t           zdma;
-};
-
-/* Extension of usb_ep */
-struct ci13xxx_ep {
-	struct usb_ep                          ep;
-	const struct usb_endpoint_descriptor  *desc;
-	u8                                     dir;
-	u8                                     num;
-	u8                                     type;
-	char                                   name[16];
-	struct {
-		struct list_head   queue;
-		struct ci13xxx_qh *ptr;
-		dma_addr_t         dma;
-	}                                      qh;
-	int                                    wedge;
-
-	/* global resources */
-	spinlock_t                            *lock;
-	struct device                         *device;
-	struct dma_pool                       *td_pool;
-};
-
-struct ci13xxx;
-struct ci13xxx_udc_driver {
-	const char	*name;
-	unsigned long	 flags;
-#define CI13XXX_REGS_SHARED		BIT(0)
-#define CI13XXX_REQUIRE_TRANSCEIVER	BIT(1)
-#define CI13XXX_PULLUP_ON_VBUS		BIT(2)
-#define CI13XXX_DISABLE_STREAMING	BIT(3)
-
-#define CI13XXX_CONTROLLER_RESET_EVENT		0
-#define CI13XXX_CONTROLLER_STOPPED_EVENT	1
-	void	(*notify_event) (struct ci13xxx *udc, unsigned event);
-};
-
-/* CI13XXX UDC descriptor & global resources */
-struct ci13xxx {
-	spinlock_t		  *lock;      /* ctrl register bank access */
-	void __iomem              *regs;      /* registers address space */
-
-	struct dma_pool           *qh_pool;   /* DMA pool for queue heads */
-	struct dma_pool           *td_pool;   /* DMA pool for transfer descs */
-	struct usb_request        *status;    /* ep0 status request */
-
-	struct usb_gadget          gadget;     /* USB slave device */
-	struct ci13xxx_ep          ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
-	u32                        ep0_dir;    /* ep0 direction */
-#define ep0out ci13xxx_ep[0]
-#define ep0in  ci13xxx_ep[hw_ep_max / 2]
-	u8                         remote_wakeup; /* Is remote wakeup feature
-							enabled by the host? */
-	u8                         suspended;  /* suspended by the host */
-	u8                         test_mode;  /* the selected test mode */
-
-	struct usb_gadget_driver  *driver;     /* 3rd party gadget driver */
-	struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
-	int                        vbus_active; /* is VBUS active */
-	struct usb_phy            *transceiver; /* Transceiver struct */
-};
-
-/******************************************************************************
- * REGISTERS
- *****************************************************************************/
-/* register size */
-#define REG_BITS   (32)
-
-/* HCCPARAMS */
-#define HCCPARAMS_LEN         BIT(17)
-
-/* DCCPARAMS */
-#define DCCPARAMS_DEN         (0x1F << 0)
-#define DCCPARAMS_DC          BIT(7)
-
-/* TESTMODE */
-#define TESTMODE_FORCE        BIT(0)
-
-/* USBCMD */
-#define USBCMD_RS             BIT(0)
-#define USBCMD_RST            BIT(1)
-#define USBCMD_SUTW           BIT(13)
-#define USBCMD_ATDTW          BIT(14)
-
-/* USBSTS & USBINTR */
-#define USBi_UI               BIT(0)
-#define USBi_UEI              BIT(1)
-#define USBi_PCI              BIT(2)
-#define USBi_URI              BIT(6)
-#define USBi_SLI              BIT(8)
-
-/* DEVICEADDR */
-#define DEVICEADDR_USBADRA    BIT(24)
-#define DEVICEADDR_USBADR     (0x7FUL << 25)
-
-/* PORTSC */
-#define PORTSC_FPR            BIT(6)
-#define PORTSC_SUSP           BIT(7)
-#define PORTSC_HSP            BIT(9)
-#define PORTSC_PTC            (0x0FUL << 16)
-
-/* DEVLC */
-#define DEVLC_PSPD            (0x03UL << 25)
-#define    DEVLC_PSPD_HS      (0x02UL << 25)
-
-/* USBMODE */
-#define USBMODE_CM            (0x03UL <<  0)
-#define    USBMODE_CM_IDLE    (0x00UL <<  0)
-#define    USBMODE_CM_DEVICE  (0x02UL <<  0)
-#define    USBMODE_CM_HOST    (0x03UL <<  0)
-#define USBMODE_SLOM          BIT(3)
-#define USBMODE_SDIS          BIT(4)
-
-/* ENDPTCTRL */
-#define ENDPTCTRL_RXS         BIT(0)
-#define ENDPTCTRL_RXT         (0x03UL <<  2)
-#define ENDPTCTRL_RXR         BIT(6)         /* reserved for port 0 */
-#define ENDPTCTRL_RXE         BIT(7)
-#define ENDPTCTRL_TXS         BIT(16)
-#define ENDPTCTRL_TXT         (0x03UL << 18)
-#define ENDPTCTRL_TXR         BIT(22)        /* reserved for port 0 */
-#define ENDPTCTRL_TXE         BIT(23)
-
-/******************************************************************************
- * LOGGING
- *****************************************************************************/
-#define ci13xxx_printk(level, format, args...) \
-do { \
-	if (_udc == NULL) \
-		printk(level "[%s] " format "\n", __func__, ## args); \
-	else \
-		dev_printk(level, _udc->gadget.dev.parent, \
-			   "[%s] " format "\n", __func__, ## args); \
-} while (0)
-
-#define err(format, args...)    ci13xxx_printk(KERN_ERR, format, ## args)
-#define warn(format, args...)   ci13xxx_printk(KERN_WARNING, format, ## args)
-#define info(format, args...)   ci13xxx_printk(KERN_INFO, format, ## args)
-
-#ifdef TRACE
-#define trace(format, args...)      ci13xxx_printk(KERN_DEBUG, format, ## args)
-#define dbg_trace(format, args...)  dev_dbg(dev, format, ##args)
-#else
-#define trace(format, args...)      do {} while (0)
-#define dbg_trace(format, args...)  do {} while (0)
-#endif
-
-#endif	/* _CI13XXX_h_ */
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index baaebf2..390749b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -40,27 +40,27 @@
  */
 
 static ushort idVendor;
-module_param(idVendor, ushort, 0);
+module_param(idVendor, ushort, 0644);
 MODULE_PARM_DESC(idVendor, "USB Vendor ID");
 
 static ushort idProduct;
-module_param(idProduct, ushort, 0);
+module_param(idProduct, ushort, 0644);
 MODULE_PARM_DESC(idProduct, "USB Product ID");
 
 static ushort bcdDevice;
-module_param(bcdDevice, ushort, 0);
+module_param(bcdDevice, ushort, 0644);
 MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
 
 static char *iManufacturer;
-module_param(iManufacturer, charp, 0);
+module_param(iManufacturer, charp, 0644);
 MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
 
 static char *iProduct;
-module_param(iProduct, charp, 0);
+module_param(iProduct, charp, 0644);
 MODULE_PARM_DESC(iProduct, "USB Product string");
 
 static char *iSerialNumber;
-module_param(iSerialNumber, charp, 0);
+module_param(iSerialNumber, charp, 0644);
 MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
 
 static char composite_manufacturer[50];
@@ -734,9 +734,23 @@
 
 	INIT_LIST_HEAD(&config->functions);
 	config->next_interface_id = 0;
+	memset(config->interface, 0, sizeof(config->interface));
 
 	status = bind(config);
 	if (status < 0) {
+		while (!list_empty(&config->functions)) {
+			struct usb_function		*f;
+
+			f = list_first_entry(&config->functions,
+					struct usb_function, list);
+			list_del(&f->list);
+			if (f->unbind) {
+				DBG(cdev, "unbind function '%s'/%p\n",
+					f->name, f);
+				f->unbind(config, f);
+				/* may free memory for "f" */
+			}
+		}
 		list_del(&config->list);
 		config->cdev = NULL;
 	} else {
@@ -774,6 +788,53 @@
 	return status;
 }
 
+static void remove_config(struct usb_composite_dev *cdev,
+			      struct usb_configuration *config)
+{
+	while (!list_empty(&config->functions)) {
+		struct usb_function		*f;
+
+		f = list_first_entry(&config->functions,
+				struct usb_function, list);
+		list_del(&f->list);
+		if (f->unbind) {
+			DBG(cdev, "unbind function '%s'/%p\n", f->name, f);
+			f->unbind(config, f);
+			/* may free memory for "f" */
+		}
+	}
+	list_del(&config->list);
+	if (config->unbind) {
+		DBG(cdev, "unbind config '%s'/%p\n", config->label, config);
+		config->unbind(config);
+			/* may free memory for "c" */
+	}
+}
+
+/**
+ * usb_remove_config() - remove a configuration from a device.
+ * @cdev: wraps the USB gadget
+ * @config: the configuration
+ *
+ * Drivers must call usb_gadget_disconnect before calling this function
+ * to disconnect the device from the host and make sure the host will not
+ * try to enumerate the device while we are changing the config list.
+ */
+void usb_remove_config(struct usb_composite_dev *cdev,
+		      struct usb_configuration *config)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&cdev->lock, flags);
+
+	if (cdev->config == config)
+		reset_config(cdev);
+
+	spin_unlock_irqrestore(&cdev->lock, flags);
+
+	remove_config(cdev, config);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* We support strings in multiple languages ... string descriptor zero
@@ -785,7 +846,7 @@
 static void collect_langs(struct usb_gadget_strings **sp, __le16 *buf)
 {
 	const struct usb_gadget_strings	*s;
-	u16				language;
+	__le16				language;
 	__le16				*tmp;
 
 	while (*sp) {
@@ -877,7 +938,7 @@
 	else if (cdev->product_override == id)
 		str = iProduct ?: composite->iProduct;
 	else if (cdev->serial_override == id)
-		str = iSerialNumber;
+		str = iSerialNumber ?: composite->iSerialNumber;
 	else
 		str = NULL;
 	if (str) {
@@ -1328,28 +1389,9 @@
 
 	while (!list_empty(&cdev->configs)) {
 		struct usb_configuration	*c;
-
 		c = list_first_entry(&cdev->configs,
 				struct usb_configuration, list);
-		while (!list_empty(&c->functions)) {
-			struct usb_function		*f;
-
-			f = list_first_entry(&c->functions,
-					struct usb_function, list);
-			list_del(&f->list);
-			if (f->unbind) {
-				DBG(cdev, "unbind function '%s'/%p\n",
-						f->name, f);
-				f->unbind(c, f);
-				/* may free memory for "f" */
-			}
-		}
-		list_del(&c->list);
-		if (c->unbind) {
-			DBG(cdev, "unbind config '%s'/%p\n", c->label, c);
-			c->unbind(c);
-			/* may free memory for "c" */
-		}
+		remove_config(cdev, c);
 	}
 	if (composite->unbind)
 		composite->unbind(cdev);
@@ -1431,10 +1473,16 @@
 	/* standardized runtime overrides for device ID data */
 	if (idVendor)
 		cdev->desc.idVendor = cpu_to_le16(idVendor);
+	else
+		idVendor = le16_to_cpu(cdev->desc.idVendor);
 	if (idProduct)
 		cdev->desc.idProduct = cpu_to_le16(idProduct);
+	else
+		idProduct = le16_to_cpu(cdev->desc.idProduct);
 	if (bcdDevice)
 		cdev->desc.bcdDevice = cpu_to_le16(bcdDevice);
+	else
+		bcdDevice = le16_to_cpu(cdev->desc.bcdDevice);
 
 	/* string overrides */
 	if (iManufacturer || !cdev->desc.iManufacturer) {
@@ -1455,7 +1503,8 @@
 		cdev->product_override =
 			override_id(cdev, &cdev->desc.iProduct);
 
-	if (iSerialNumber)
+	if (iSerialNumber ||
+	    (!cdev->desc.iSerialNumber && composite->iSerialNumber))
 		cdev->serial_override =
 			override_id(cdev, &cdev->desc.iSerialNumber);
 
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 170cbe8..b799106 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -595,14 +595,12 @@
 
 static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req)
 {
-	struct dummy_ep		*ep;
 	struct dummy_request	*req;
 
-	if (!_ep || !_req)
+	if (!_ep || !_req) {
+		WARN_ON(1);
 		return;
-	ep = usb_ep_to_dummy_ep(_ep);
-	if (!ep->desc && _ep->name != ep0name)
-		return;
+	}
 
 	req = usb_request_to_dummy_request(_req);
 	WARN_ON(!list_empty(&req->queue));
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index f52cb1a..dcd1c7f 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1031,6 +1031,12 @@
 	struct ffs_file_perms perms;
 	umode_t root_mode;
 	const char *dev_name;
+	union {
+		/* set by ffs_fs_mount(), read by ffs_sb_fill() */
+		void *private_data;
+		/* set by ffs_sb_fill(), read by ffs_fs_mount */
+		struct ffs_data *ffs_data;
+	};
 };
 
 static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
@@ -1047,8 +1053,14 @@
 		goto Enomem;
 
 	ffs->sb              = sb;
-	ffs->dev_name        = data->dev_name;
+	ffs->dev_name        = kstrdup(data->dev_name, GFP_KERNEL);
+	if (unlikely(!ffs->dev_name))
+		goto Enomem;
 	ffs->file_perms      = data->perms;
+	ffs->private_data    = data->private_data;
+
+	/* used by the caller of this function */
+	data->ffs_data       = ffs;
 
 	sb->s_fs_info        = ffs;
 	sb->s_blocksize      = PAGE_CACHE_SIZE;
@@ -1167,20 +1179,29 @@
 		},
 		.root_mode = S_IFDIR | 0500,
 	};
+	struct dentry *rv;
 	int ret;
+	void *ffs_dev;
 
 	ENTER();
 
-	ret = functionfs_check_dev_callback(dev_name);
-	if (unlikely(ret < 0))
-		return ERR_PTR(ret);
-
 	ret = ffs_fs_parse_opts(&data, opts);
 	if (unlikely(ret < 0))
 		return ERR_PTR(ret);
 
+	ffs_dev = functionfs_acquire_dev_callback(dev_name);
+	if (IS_ERR(ffs_dev))
+		return ffs_dev;
+
 	data.dev_name = dev_name;
-	return mount_single(t, flags, &data, ffs_sb_fill);
+	data.private_data = ffs_dev;
+	rv = mount_nodev(t, flags, &data, ffs_sb_fill);
+
+	/* data.ffs_data is set by ffs_sb_fill */
+	if (IS_ERR(rv))
+		functionfs_release_dev_callback(data.ffs_data);
+
+	return rv;
 }
 
 static void
@@ -1189,8 +1210,10 @@
 	ENTER();
 
 	kill_litter_super(sb);
-	if (sb->s_fs_info)
+	if (sb->s_fs_info) {
+		functionfs_release_dev_callback(sb->s_fs_info);
 		ffs_data_put(sb->s_fs_info);
+	}
 }
 
 static struct file_system_type ffs_fs_type = {
@@ -1256,6 +1279,7 @@
 		ffs_data_clear(ffs);
 		BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
 		       waitqueue_active(&ffs->ep0req_completion.wait));
+		kfree(ffs->dev_name);
 		kfree(ffs);
 	}
 }
@@ -1473,8 +1497,22 @@
 
 static void ffs_func_free(struct ffs_function *func)
 {
+	struct ffs_ep *ep         = func->eps;
+	unsigned count            = func->ffs->eps_count;
+	unsigned long flags;
+
 	ENTER();
 
+	/* cleanup after autoconfig */
+	spin_lock_irqsave(&func->ffs->eps_lock, flags);
+	do {
+		if (ep->ep && ep->req)
+			usb_ep_free_request(ep->ep, ep->req);
+		ep->req = NULL;
+		++ep;
+	} while (--count);
+	spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
+
 	ffs_data_put(func->ffs);
 
 	kfree(func->eps);
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index b211342..3b3932c 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -374,7 +374,7 @@
 			break;
 
 		default:
-			VDBG(cdev, "Unknown decriptor request 0x%x\n",
+			VDBG(cdev, "Unknown descriptor request 0x%x\n",
 				 value >> 8);
 			goto stall;
 			break;
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 2c0cd82..7275706 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -286,7 +286,7 @@
 	struct usb_composite_dev	*cdev;
 
 	cdev = loop->function.config->cdev;
-	disable_endpoints(cdev, loop->in_ep, loop->out_ep);
+	disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL);
 	VDBG(cdev, "%s disabled\n", loop->function.name);
 }
 
@@ -329,7 +329,7 @@
 	 * than 'buflen' bytes each.
 	 */
 	for (i = 0; i < qlen && result == 0; i++) {
-		req = alloc_ep_req(ep);
+		req = alloc_ep_req(ep, 0);
 		if (req) {
 			req->complete = loopback_complete;
 			result = usb_ep_queue(ep, req, GFP_ATOMIC);
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index cb8c162..f67b453 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -3110,13 +3110,6 @@
 	return rc;
 }
 
-static inline int __deprecated __maybe_unused
-fsg_add(struct usb_composite_dev *cdev, struct usb_configuration *c,
-	struct fsg_common *common)
-{
-	return fsg_bind_config(cdev, c, common);
-}
-
 
 /************************* Module parameters *************************/
 
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 5234365..a476122 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -71,6 +71,8 @@
 	struct gether			port;
 	u8				ctrl_id, data_id;
 	u8				ethaddr[ETH_ALEN];
+	u32				vendorID;
+	const char			*manufacturer;
 	int				config;
 
 	struct usb_ep			*notify;
@@ -768,12 +770,10 @@
 	rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0);
 	rndis_set_host_mac(rndis->config, rndis->ethaddr);
 
-#if 0
-// FIXME
-	if (rndis_set_param_vendor(rndis->config, vendorID,
-				manufacturer))
-		goto fail0;
-#endif
+	if (rndis->manufacturer && rndis->vendorID &&
+			rndis_set_param_vendor(rndis->config, rndis->vendorID,
+					       rndis->manufacturer))
+		goto fail;
 
 	/* NOTE:  all that is done without knowing or caring about
 	 * the network link ... which is unavailable to this code
@@ -820,6 +820,7 @@
 
 	rndis_deregister(rndis->config);
 	rndis_exit();
+	rndis_string_defs[0].id = 0;
 
 	if (gadget_is_superspeed(c->cdev->gadget))
 		usb_free_descriptors(f->ss_descriptors);
@@ -840,20 +841,9 @@
 	return true;
 }
 
-/**
- * rndis_bind_config - add RNDIS network link to a configuration
- * @c: the configuration to support the network link
- * @ethaddr: a buffer in which the ethernet address of the host side
- *	side of the link was recorded
- * Context: single threaded during gadget setup
- *
- * Returns zero on success, else negative errno.
- *
- * Caller must have called @gether_setup().  Caller is also responsible
- * for calling @gether_cleanup() before module unload.
- */
 int
-rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				u32 vendorID, const char *manufacturer)
 {
 	struct f_rndis	*rndis;
 	int		status;
@@ -898,6 +888,8 @@
 		goto fail;
 
 	memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
+	rndis->vendorID = vendorID;
+	rndis->manufacturer = manufacturer;
 
 	/* RNDIS activates when the host changes this filter */
 	rndis->port.cdc_filter = 0;
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index 7aa7ac8..5c1b68b 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -51,6 +51,9 @@
 
 	struct usb_ep		*in_ep;
 	struct usb_ep		*out_ep;
+	struct usb_ep		*iso_in_ep;
+	struct usb_ep		*iso_out_ep;
+	int			cur_alt;
 };
 
 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -59,18 +62,45 @@
 }
 
 static unsigned pattern;
-module_param(pattern, uint, 0);
-MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
+module_param(pattern, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none");
+
+static unsigned isoc_interval = 4;
+module_param(isoc_interval, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(isoc_interval, "1 - 16");
+
+static unsigned isoc_maxpacket = 1024;
+module_param(isoc_maxpacket, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
+
+static unsigned isoc_mult;
+module_param(isoc_mult, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)");
+
+static unsigned isoc_maxburst;
+module_param(isoc_maxburst, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
 
 /*-------------------------------------------------------------------------*/
 
-static struct usb_interface_descriptor source_sink_intf = {
-	.bLength =		sizeof source_sink_intf,
+static struct usb_interface_descriptor source_sink_intf_alt0 = {
+	.bLength =		USB_DT_INTERFACE_SIZE,
 	.bDescriptorType =	USB_DT_INTERFACE,
 
+	.bAlternateSetting =	0,
 	.bNumEndpoints =	2,
 	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
-	/* .iInterface = DYNAMIC */
+	/* .iInterface		= DYNAMIC */
+};
+
+static struct usb_interface_descriptor source_sink_intf_alt1 = {
+	.bLength =		USB_DT_INTERFACE_SIZE,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bAlternateSetting =	1,
+	.bNumEndpoints =	4,
+	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
+	/* .iInterface		= DYNAMIC */
 };
 
 /* full speed support: */
@@ -91,10 +121,36 @@
 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 };
 
+static struct usb_endpoint_descriptor fs_iso_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
+	.wMaxPacketSize =	cpu_to_le16(1023),
+	.bInterval =		4,
+};
+
+static struct usb_endpoint_descriptor fs_iso_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_OUT,
+	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
+	.wMaxPacketSize =	cpu_to_le16(1023),
+	.bInterval =		4,
+};
+
 static struct usb_descriptor_header *fs_source_sink_descs[] = {
-	(struct usb_descriptor_header *) &source_sink_intf,
+	(struct usb_descriptor_header *) &source_sink_intf_alt0,
 	(struct usb_descriptor_header *) &fs_sink_desc,
 	(struct usb_descriptor_header *) &fs_source_desc,
+	(struct usb_descriptor_header *) &source_sink_intf_alt1,
+#define FS_ALT_IFC_1_OFFSET	3
+	(struct usb_descriptor_header *) &fs_sink_desc,
+	(struct usb_descriptor_header *) &fs_source_desc,
+	(struct usb_descriptor_header *) &fs_iso_sink_desc,
+	(struct usb_descriptor_header *) &fs_iso_source_desc,
 	NULL,
 };
 
@@ -116,10 +172,34 @@
 	.wMaxPacketSize =	cpu_to_le16(512),
 };
 
+static struct usb_endpoint_descriptor hs_iso_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
+	.wMaxPacketSize =	cpu_to_le16(1024),
+	.bInterval =		4,
+};
+
+static struct usb_endpoint_descriptor hs_iso_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
+	.wMaxPacketSize =	cpu_to_le16(1024),
+	.bInterval =		4,
+};
+
 static struct usb_descriptor_header *hs_source_sink_descs[] = {
-	(struct usb_descriptor_header *) &source_sink_intf,
+	(struct usb_descriptor_header *) &source_sink_intf_alt0,
 	(struct usb_descriptor_header *) &hs_source_desc,
 	(struct usb_descriptor_header *) &hs_sink_desc,
+	(struct usb_descriptor_header *) &source_sink_intf_alt1,
+#define HS_ALT_IFC_1_OFFSET	3
+	(struct usb_descriptor_header *) &hs_source_desc,
+	(struct usb_descriptor_header *) &hs_sink_desc,
+	(struct usb_descriptor_header *) &hs_iso_source_desc,
+	(struct usb_descriptor_header *) &hs_iso_sink_desc,
 	NULL,
 };
 
@@ -136,6 +216,7 @@
 struct usb_ss_ep_comp_descriptor ss_source_comp_desc = {
 	.bLength =		USB_DT_SS_EP_COMP_SIZE,
 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
+
 	.bMaxBurst =		0,
 	.bmAttributes =		0,
 	.wBytesPerInterval =	0,
@@ -152,17 +233,64 @@
 struct usb_ss_ep_comp_descriptor ss_sink_comp_desc = {
 	.bLength =		USB_DT_SS_EP_COMP_SIZE,
 	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
+
 	.bMaxBurst =		0,
 	.bmAttributes =		0,
 	.wBytesPerInterval =	0,
 };
 
+static struct usb_endpoint_descriptor ss_iso_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
+	.wMaxPacketSize =	cpu_to_le16(1024),
+	.bInterval =		4,
+};
+
+struct usb_ss_ep_comp_descriptor ss_iso_source_comp_desc = {
+	.bLength =		USB_DT_SS_EP_COMP_SIZE,
+	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
+
+	.bMaxBurst =		0,
+	.bmAttributes =		0,
+	.wBytesPerInterval =	cpu_to_le16(1024),
+};
+
+static struct usb_endpoint_descriptor ss_iso_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bmAttributes =		USB_ENDPOINT_XFER_ISOC,
+	.wMaxPacketSize =	cpu_to_le16(1024),
+	.bInterval =		4,
+};
+
+struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
+	.bLength =		USB_DT_SS_EP_COMP_SIZE,
+	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
+
+	.bMaxBurst =		0,
+	.bmAttributes =		0,
+	.wBytesPerInterval =	cpu_to_le16(1024),
+};
+
 static struct usb_descriptor_header *ss_source_sink_descs[] = {
-	(struct usb_descriptor_header *) &source_sink_intf,
+	(struct usb_descriptor_header *) &source_sink_intf_alt0,
 	(struct usb_descriptor_header *) &ss_source_desc,
 	(struct usb_descriptor_header *) &ss_source_comp_desc,
 	(struct usb_descriptor_header *) &ss_sink_desc,
 	(struct usb_descriptor_header *) &ss_sink_comp_desc,
+	(struct usb_descriptor_header *) &source_sink_intf_alt1,
+#define SS_ALT_IFC_1_OFFSET	5
+	(struct usb_descriptor_header *) &ss_source_desc,
+	(struct usb_descriptor_header *) &ss_source_comp_desc,
+	(struct usb_descriptor_header *) &ss_sink_desc,
+	(struct usb_descriptor_header *) &ss_sink_comp_desc,
+	(struct usb_descriptor_header *) &ss_iso_source_desc,
+	(struct usb_descriptor_header *) &ss_iso_source_comp_desc,
+	(struct usb_descriptor_header *) &ss_iso_sink_desc,
+	(struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
 	NULL,
 };
 
@@ -196,9 +324,10 @@
 	id = usb_interface_id(c, f);
 	if (id < 0)
 		return id;
-	source_sink_intf.bInterfaceNumber = id;
+	source_sink_intf_alt0.bInterfaceNumber = id;
+	source_sink_intf_alt1.bInterfaceNumber = id;
 
-	/* allocate endpoints */
+	/* allocate bulk endpoints */
 	ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
 	if (!ss->in_ep) {
 autoconf_fail:
@@ -213,12 +342,74 @@
 		goto autoconf_fail;
 	ss->out_ep->driver_data = cdev;	/* claim */
 
+	/* sanity check the isoc module parameters */
+	if (isoc_interval < 1)
+		isoc_interval = 1;
+	if (isoc_interval > 16)
+		isoc_interval = 16;
+	if (isoc_mult > 2)
+		isoc_mult = 2;
+	if (isoc_maxburst > 15)
+		isoc_maxburst = 15;
+
+	/* fill in the FS isoc descriptors from the module parameters */
+	fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
+						1023 : isoc_maxpacket;
+	fs_iso_source_desc.bInterval = isoc_interval;
+	fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
+						1023 : isoc_maxpacket;
+	fs_iso_sink_desc.bInterval = isoc_interval;
+
+	/* allocate iso endpoints */
+	ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
+	if (!ss->iso_in_ep)
+		goto no_iso;
+	ss->iso_in_ep->driver_data = cdev;	/* claim */
+
+	ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc);
+	if (ss->iso_out_ep) {
+		ss->iso_out_ep->driver_data = cdev;	/* claim */
+	} else {
+		ss->iso_in_ep->driver_data = NULL;
+		ss->iso_in_ep = NULL;
+no_iso:
+		/*
+		 * We still want to work even if the UDC doesn't have isoc
+		 * endpoints, so null out the alt interface that contains
+		 * them and continue.
+		 */
+		fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL;
+		hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL;
+		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
+	}
+
+	if (isoc_maxpacket > 1024)
+		isoc_maxpacket = 1024;
+
 	/* support high speed hardware */
 	if (gadget_is_dualspeed(c->cdev->gadget)) {
 		hs_source_desc.bEndpointAddress =
 				fs_source_desc.bEndpointAddress;
 		hs_sink_desc.bEndpointAddress =
 				fs_sink_desc.bEndpointAddress;
+
+		/*
+		 * Fill in the HS isoc descriptors from the module parameters.
+		 * We assume that the user knows what they are doing and won't
+		 * give parameters that their UDC doesn't support.
+		 */
+		hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
+		hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
+		hs_iso_source_desc.bInterval = isoc_interval;
+		hs_iso_source_desc.bEndpointAddress =
+				fs_iso_source_desc.bEndpointAddress;
+
+		hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
+		hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
+		hs_iso_sink_desc.bInterval = isoc_interval;
+		hs_iso_sink_desc.bEndpointAddress =
+				fs_iso_sink_desc.bEndpointAddress;
+
 		f->hs_descriptors = hs_source_sink_descs;
 	}
 
@@ -228,13 +419,39 @@
 				fs_source_desc.bEndpointAddress;
 		ss_sink_desc.bEndpointAddress =
 				fs_sink_desc.bEndpointAddress;
+
+		/*
+		 * Fill in the SS isoc descriptors from the module parameters.
+		 * We assume that the user knows what they are doing and won't
+		 * give parameters that their UDC doesn't support.
+		 */
+		ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
+		ss_iso_source_desc.bInterval = isoc_interval;
+		ss_iso_source_comp_desc.bmAttributes = isoc_mult;
+		ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
+		ss_iso_source_comp_desc.wBytesPerInterval =
+			isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+		ss_iso_source_desc.bEndpointAddress =
+				fs_iso_source_desc.bEndpointAddress;
+
+		ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
+		ss_iso_sink_desc.bInterval = isoc_interval;
+		ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
+		ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
+		ss_iso_sink_comp_desc.wBytesPerInterval =
+			isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+		ss_iso_sink_desc.bEndpointAddress =
+				fs_iso_sink_desc.bEndpointAddress;
+
 		f->ss_descriptors = ss_source_sink_descs;
 	}
 
-	DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
+	DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
 	    (gadget_is_superspeed(c->cdev->gadget) ? "super" :
 	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
-			f->name, ss->in_ep->name, ss->out_ep->name);
+			f->name, ss->in_ep->name, ss->out_ep->name,
+			ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
+			ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
 	return 0;
 }
 
@@ -251,6 +468,9 @@
 	u8			*buf = req->buf;
 	struct usb_composite_dev *cdev = ss->function.config->cdev;
 
+	if (pattern == 2)
+		return 0;
+
 	for (i = 0; i < req->actual; i++, buf++) {
 		switch (pattern) {
 
@@ -265,7 +485,7 @@
 		 * each usb transfer request should be.  Resync is done
 		 * with set_interface or set_config.  (We *WANT* it to
 		 * get quickly out of sync if controllers or their drivers
-		 * stutter for any reason, including buffer duplcation...)
+		 * stutter for any reason, including buffer duplication...)
 		 */
 		case 1:
 			if (*buf == (u8)(i % 63))
@@ -292,21 +512,30 @@
 		for  (i = 0; i < req->length; i++)
 			*buf++ = (u8) (i % 63);
 		break;
+	case 2:
+		break;
 	}
 }
 
 static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
 {
-	struct f_sourcesink	*ss = ep->driver_data;
-	struct usb_composite_dev *cdev = ss->function.config->cdev;
-	int			status = req->status;
+	struct usb_composite_dev	*cdev;
+	struct f_sourcesink		*ss = ep->driver_data;
+	int				status = req->status;
+
+	/* driver_data will be null if ep has been disabled */
+	if (!ss)
+		return;
+
+	cdev = ss->function.config->cdev;
 
 	switch (status) {
 
 	case 0:				/* normal completion? */
 		if (ep == ss->out_ep) {
 			check_read_data(ss, req);
-			memset(req->buf, 0x55, req->length);
+			if (pattern != 2)
+				memset(req->buf, 0x55, req->length);
 		} else
 			reinit_write_data(ep, req);
 		break;
@@ -344,32 +573,57 @@
 	}
 }
 
-static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in)
+static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
+		bool is_iso, int speed)
 {
 	struct usb_ep		*ep;
 	struct usb_request	*req;
-	int			status;
+	int			i, size, status;
 
-	ep = is_in ? ss->in_ep : ss->out_ep;
-	req = alloc_ep_req(ep);
-	if (!req)
-		return -ENOMEM;
+	for (i = 0; i < 8; i++) {
+		if (is_iso) {
+			switch (speed) {
+			case USB_SPEED_SUPER:
+				size = isoc_maxpacket * (isoc_mult + 1) *
+						(isoc_maxburst + 1);
+				break;
+			case USB_SPEED_HIGH:
+				size = isoc_maxpacket * (isoc_mult + 1);
+				break;
+			default:
+				size = isoc_maxpacket > 1023 ?
+						1023 : isoc_maxpacket;
+				break;
+			}
+			ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
+			req = alloc_ep_req(ep, size);
+		} else {
+			ep = is_in ? ss->in_ep : ss->out_ep;
+			req = alloc_ep_req(ep, 0);
+		}
 
-	req->complete = source_sink_complete;
-	if (is_in)
-		reinit_write_data(ep, req);
-	else
-		memset(req->buf, 0x55, req->length);
+		if (!req)
+			return -ENOMEM;
 
-	status = usb_ep_queue(ep, req, GFP_ATOMIC);
-	if (status) {
-		struct usb_composite_dev	*cdev;
+		req->complete = source_sink_complete;
+		if (is_in)
+			reinit_write_data(ep, req);
+		else if (pattern != 2)
+			memset(req->buf, 0x55, req->length);
 
-		cdev = ss->function.config->cdev;
-		ERROR(cdev, "start %s %s --> %d\n",
-				is_in ? "IN" : "OUT",
-				ep->name, status);
-		free_ep_req(ep, req);
+		status = usb_ep_queue(ep, req, GFP_ATOMIC);
+		if (status) {
+			struct usb_composite_dev	*cdev;
+
+			cdev = ss->function.config->cdev;
+			ERROR(cdev, "start %s%s %s --> %d\n",
+			      is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
+			      ep->name, status);
+			free_ep_req(ep, req);
+		}
+
+		if (!is_iso)
+			break;
 	}
 
 	return status;
@@ -380,17 +634,20 @@
 	struct usb_composite_dev	*cdev;
 
 	cdev = ss->function.config->cdev;
-	disable_endpoints(cdev, ss->in_ep, ss->out_ep);
+	disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
+			ss->iso_out_ep);
 	VDBG(cdev, "%s disabled\n", ss->function.name);
 }
 
 static int
-enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
+enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
+		int alt)
 {
 	int					result = 0;
+	int					speed = cdev->gadget->speed;
 	struct usb_ep				*ep;
 
-	/* one endpoint writes (sources) zeroes IN (to the host) */
+	/* one bulk endpoint writes (sources) zeroes IN (to the host) */
 	ep = ss->in_ep;
 	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
 	if (result)
@@ -400,7 +657,7 @@
 		return result;
 	ep->driver_data = ss;
 
-	result = source_sink_start_ep(ss, true);
+	result = source_sink_start_ep(ss, true, false, speed);
 	if (result < 0) {
 fail:
 		ep = ss->in_ep;
@@ -409,7 +666,7 @@
 		return result;
 	}
 
-	/* one endpoint reads (sinks) anything OUT (from the host) */
+	/* one bulk endpoint reads (sinks) anything OUT (from the host) */
 	ep = ss->out_ep;
 	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
 	if (result)
@@ -419,27 +676,82 @@
 		goto fail;
 	ep->driver_data = ss;
 
-	result = source_sink_start_ep(ss, false);
+	result = source_sink_start_ep(ss, false, false, speed);
 	if (result < 0) {
+fail2:
+		ep = ss->out_ep;
 		usb_ep_disable(ep);
 		ep->driver_data = NULL;
 		goto fail;
 	}
 
-	DBG(cdev, "%s enabled\n", ss->function.name);
+	if (alt == 0)
+		goto out;
+
+	/* one iso endpoint writes (sources) zeroes IN (to the host) */
+	ep = ss->iso_in_ep;
+	if (ep) {
+		result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
+		if (result)
+			goto fail2;
+		result = usb_ep_enable(ep);
+		if (result < 0)
+			goto fail2;
+		ep->driver_data = ss;
+
+		result = source_sink_start_ep(ss, true, true, speed);
+		if (result < 0) {
+fail3:
+			ep = ss->iso_in_ep;
+			if (ep) {
+				usb_ep_disable(ep);
+				ep->driver_data = NULL;
+			}
+			goto fail2;
+		}
+	}
+
+	/* one iso endpoint reads (sinks) anything OUT (from the host) */
+	ep = ss->iso_out_ep;
+	if (ep) {
+		result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
+		if (result)
+			goto fail3;
+		result = usb_ep_enable(ep);
+		if (result < 0)
+			goto fail3;
+		ep->driver_data = ss;
+
+		result = source_sink_start_ep(ss, false, true, speed);
+		if (result < 0) {
+			usb_ep_disable(ep);
+			ep->driver_data = NULL;
+			goto fail3;
+		}
+	}
+out:
+	ss->cur_alt = alt;
+
+	DBG(cdev, "%s enabled, alt intf %d\n", ss->function.name, alt);
 	return result;
 }
 
 static int sourcesink_set_alt(struct usb_function *f,
 		unsigned intf, unsigned alt)
 {
-	struct f_sourcesink	*ss = func_to_ss(f);
-	struct usb_composite_dev *cdev = f->config->cdev;
+	struct f_sourcesink		*ss = func_to_ss(f);
+	struct usb_composite_dev	*cdev = f->config->cdev;
 
-	/* we know alt is zero */
 	if (ss->in_ep->driver_data)
 		disable_source_sink(ss);
-	return enable_source_sink(cdev, ss);
+	return enable_source_sink(cdev, ss, alt);
+}
+
+static int sourcesink_get_alt(struct usb_function *f, unsigned intf)
+{
+	struct f_sourcesink		*ss = func_to_ss(f);
+
+	return ss->cur_alt;
 }
 
 static void sourcesink_disable(struct usb_function *f)
@@ -465,6 +777,7 @@
 	ss->function.bind = sourcesink_bind;
 	ss->function.unbind = sourcesink_unbind;
 	ss->function.set_alt = sourcesink_set_alt;
+	ss->function.get_alt = sourcesink_get_alt;
 	ss->function.disable = sourcesink_disable;
 
 	status = usb_add_function(c, &ss->function);
@@ -536,7 +849,7 @@
 		req->length = value;
 		value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
 		if (value < 0)
-			ERROR(c->cdev, "source/sinkc response, err %d\n",
+			ERROR(c->cdev, "source/sink response, err %d\n",
 					value);
 	}
 
@@ -545,12 +858,12 @@
 }
 
 static struct usb_configuration sourcesink_driver = {
-	.label		= "source/sink",
-	.strings	= sourcesink_strings,
-	.setup		= sourcesink_setup,
-	.bConfigurationValue = 3,
-	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	/* .iConfiguration = DYNAMIC */
+	.label			= "source/sink",
+	.strings		= sourcesink_strings,
+	.setup			= sourcesink_setup,
+	.bConfigurationValue	= 3,
+	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
+	/* .iConfiguration	= DYNAMIC */
 };
 
 /**
@@ -567,7 +880,8 @@
 		return id;
 	strings_sourcesink[0].id = id;
 
-	source_sink_intf.iInterface = id;
+	source_sink_intf_alt0.iInterface = id;
+	source_sink_intf_alt1.iInterface = id;
 	sourcesink_driver.iConfiguration = id;
 
 	/* support autoresume for remote wakeup testing */
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index 877a2c4..51881f3 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -71,9 +71,6 @@
 	.wMaxPacketSize =	USB_MAX_CTRL_PAYLOAD,
 };
 
-/* it is initialized in probe()  */
-static struct qe_udc *udc_controller;
-
 /********************************************************************
  *      Internal Used Function Start
 ********************************************************************/
@@ -188,8 +185,8 @@
 {
 	qe_eptx_stall_change(&udc->eps[0], 1);
 	qe_eprx_stall_change(&udc->eps[0], 1);
-	udc_controller->ep0_state = WAIT_FOR_SETUP;
-	udc_controller->ep0_dir = 0;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = 0;
 	return 0;
 }
 
@@ -450,13 +447,13 @@
 
 	ep->rxbuf_d = virt_to_phys((void *)ep->rxbuffer);
 	if (ep->rxbuf_d == DMA_ADDR_INVALID) {
-		ep->rxbuf_d = dma_map_single(udc_controller->gadget.dev.parent,
+		ep->rxbuf_d = dma_map_single(ep->udc->gadget.dev.parent,
 					ep->rxbuffer,
 					size,
 					DMA_FROM_DEVICE);
 		ep->rxbufmap = 1;
 	} else {
-		dma_sync_single_for_device(udc_controller->gadget.dev.parent,
+		dma_sync_single_for_device(ep->udc->gadget.dev.parent,
 					ep->rxbuf_d, size,
 					DMA_FROM_DEVICE);
 		ep->rxbufmap = 0;
@@ -489,10 +486,10 @@
 	epparam = udc->ep_param[pipe_num];
 
 	usep = 0;
-	logepnum = (ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+	logepnum = (ep->ep.desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
 	usep |= (logepnum << USB_EPNUM_SHIFT);
 
-	switch (ep->desc->bmAttributes & 0x03) {
+	switch (ep->ep.desc->bmAttributes & 0x03) {
 	case USB_ENDPOINT_XFER_BULK:
 		usep |= USB_TRANS_BULK;
 		break;
@@ -644,7 +641,7 @@
 	/* initialize ep structure */
 	ep->ep.maxpacket = max;
 	ep->tm = (u8)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->stopped = 0;
 	ep->init = 1;
 
@@ -698,14 +695,14 @@
 	return -ENODEV;
 }
 
-static inline void qe_usb_enable(void)
+static inline void qe_usb_enable(struct qe_udc *udc)
 {
-	setbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
+	setbits8(&udc->usb_regs->usb_usmod, USB_MODE_EN);
 }
 
-static inline void qe_usb_disable(void)
+static inline void qe_usb_disable(struct qe_udc *udc)
 {
-	clrbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
+	clrbits8(&udc->usb_regs->usb_usmod, USB_MODE_EN);
 }
 
 /*----------------------------------------------------------------------------*
@@ -1599,7 +1596,7 @@
 	ep = container_of(_ep, struct qe_ep, ep);
 
 	/* catch various bogus parameters */
-	if (!_ep || !desc || ep->desc || _ep->name == ep_name[0] ||
+	if (!_ep || !desc || ep->ep.desc || _ep->name == ep_name[0] ||
 			(desc->bDescriptorType != USB_DT_ENDPOINT))
 		return -EINVAL;
 
@@ -1629,7 +1626,7 @@
 	ep = container_of(_ep, struct qe_ep, ep);
 	udc = ep->udc;
 
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		dev_dbg(udc->dev, "%s not enabled\n", _ep ? ep->ep.name : NULL);
 		return -EINVAL;
 	}
@@ -1637,7 +1634,6 @@
 	spin_lock_irqsave(&udc->lock, flags);
 	/* Nuke all pending requests (does flush) */
 	nuke(ep, -ESHUTDOWN);
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->stopped = 1;
 	ep->tx_req = NULL;
@@ -1656,13 +1652,13 @@
 	if (ep->dir != USB_DIR_IN) {
 		kfree(ep->rxframe);
 		if (ep->rxbufmap) {
-			dma_unmap_single(udc_controller->gadget.dev.parent,
+			dma_unmap_single(udc->gadget.dev.parent,
 					ep->rxbuf_d, size,
 					DMA_FROM_DEVICE);
 			ep->rxbuf_d = DMA_ADDR_INVALID;
 		} else {
 			dma_sync_single_for_cpu(
-					udc_controller->gadget.dev.parent,
+					udc->gadget.dev.parent,
 					ep->rxbuf_d, size,
 					DMA_FROM_DEVICE);
 		}
@@ -1715,7 +1711,7 @@
 		dev_dbg(udc->dev, "bad params\n");
 		return -EINVAL;
 	}
-	if (!_ep || (!ep->desc && ep_index(ep))) {
+	if (!_ep || (!ep->ep.desc && ep_index(ep))) {
 		dev_dbg(udc->dev, "bad ep\n");
 		return -EINVAL;
 	}
@@ -1826,7 +1822,7 @@
 	struct qe_udc *udc;
 
 	ep = container_of(_ep, struct qe_ep, ep);
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		status = -EINVAL;
 		goto out;
 	}
@@ -1880,9 +1876,10 @@
 /* Get the current frame number */
 static int qe_get_frame(struct usb_gadget *gadget)
 {
+	struct qe_udc *udc = container_of(gadget, struct qe_udc, gadget);
 	u16 tmp;
 
-	tmp = in_be16(&udc_controller->usb_param->frame_n);
+	tmp = in_be16(&udc->usb_param->frame_n);
 	if (tmp & 0x8000)
 		tmp = tmp & 0x07ff;
 	else
@@ -1891,57 +1888,16 @@
 	return (int)tmp;
 }
 
-/* Tries to wake up the host connected to this gadget
- *
- * Return : 0-success
- * Negative-this feature not enabled by host or not supported by device hw
- */
-static int qe_wakeup(struct usb_gadget *gadget)
-{
-	return -ENOTSUPP;
-}
-
-/* Notify controller that VBUS is powered, Called by whatever
-   detects VBUS sessions */
-static int qe_vbus_session(struct usb_gadget *gadget, int is_active)
-{
-	return -ENOTSUPP;
-}
-
-/* constrain controller's VBUS power usage
- * This call is used by gadget drivers during SET_CONFIGURATION calls,
- * reporting how much power the device may consume.  For example, this
- * could affect how quickly batteries are recharged.
- *
- * Returns zero on success, else negative errno.
- */
-static int qe_vbus_draw(struct usb_gadget *gadget, unsigned mA)
-{
-	return -ENOTSUPP;
-}
-
-/* Change Data+ pullup status
- * this func is used by usb_gadget_connect/disconnect
- */
-static int qe_pullup(struct usb_gadget *gadget, int is_on)
-{
-	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);
+static int fsl_qe_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
+static int fsl_qe_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
 
 /* defined in usb_gadget.h */
 static struct usb_gadget_ops qe_gadget_ops = {
 	.get_frame = qe_get_frame,
-	.wakeup = qe_wakeup,
-/*	.set_selfpowered = qe_set_selfpowered,*/ /* always selfpowered */
-	.vbus_session = qe_vbus_session,
-	.vbus_draw = qe_vbus_draw,
-	.pullup = qe_pullup,
-	.start = fsl_qe_start,
-	.stop = fsl_qe_stop,
+	.udc_start = fsl_qe_start,
+	.udc_stop = fsl_qe_stop,
 };
 
 /*-------------------------------------------------------------------------
@@ -2015,7 +1971,7 @@
 		u16 usep;
 
 		/* stall if endpoint doesn't exist */
-		if (!target_ep->desc)
+		if (!target_ep->ep.desc)
 			goto stall;
 
 		usep = in_be16(&udc->usb_regs->usb_usep[pipe]);
@@ -2190,7 +2146,7 @@
 	if (udc->usb_state == USB_STATE_DEFAULT)
 		return 0;
 
-	qe_usb_disable();
+	qe_usb_disable(udc);
 	out_8(&udc->usb_regs->usb_usadr, 0);
 
 	for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
@@ -2202,7 +2158,7 @@
 	udc->usb_state = USB_STATE_DEFAULT;
 	udc->ep0_state = WAIT_FOR_SETUP;
 	udc->ep0_dir = USB_DIR_OUT;
-	qe_usb_enable();
+	qe_usb_enable(udc);
 	return 0;
 }
 
@@ -2327,92 +2283,65 @@
 /*-------------------------------------------------------------------------
 	Gadget driver probe and unregister.
  --------------------------------------------------------------------------*/
-static int fsl_qe_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
+static int fsl_qe_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	int retval;
-	unsigned long flags = 0;
+	struct qe_udc *udc;
+	unsigned long flags;
 
-	/* standard operations */
-	if (!udc_controller)
-		return -ENODEV;
-
-	if (!driver || driver->max_speed < USB_SPEED_FULL
-			|| !bind || !driver->disconnect || !driver->setup)
-		return -EINVAL;
-
-	if (udc_controller->driver)
-		return -EBUSY;
-
+	udc = container_of(gadget, struct qe_udc, gadget);
 	/* lock is needed but whether should use this lock or another */
-	spin_lock_irqsave(&udc_controller->lock, flags);
+	spin_lock_irqsave(&udc->lock, flags);
 
 	driver->driver.bus = NULL;
 	/* hook up the driver */
-	udc_controller->driver = driver;
-	udc_controller->gadget.dev.driver = &driver->driver;
-	udc_controller->gadget.speed = driver->max_speed;
-	spin_unlock_irqrestore(&udc_controller->lock, flags);
-
-	retval = bind(&udc_controller->gadget);
-	if (retval) {
-		dev_err(udc_controller->dev, "bind to %s --> %d",
-				driver->driver.name, retval);
-		udc_controller->gadget.dev.driver = NULL;
-		udc_controller->driver = NULL;
-		return retval;
-	}
+	udc->driver = driver;
+	udc->gadget.dev.driver = &driver->driver;
+	udc->gadget.speed = driver->max_speed;
 
 	/* Enable IRQ reg and Set usbcmd reg EN bit */
-	qe_usb_enable();
+	qe_usb_enable(udc);
 
-	out_be16(&udc_controller->usb_regs->usb_usber, 0xffff);
-	out_be16(&udc_controller->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
-	udc_controller->usb_state = USB_STATE_ATTACHED;
-	udc_controller->ep0_state = WAIT_FOR_SETUP;
-	udc_controller->ep0_dir = USB_DIR_OUT;
-	dev_info(udc_controller->dev, "%s bind to driver %s \n",
-		udc_controller->gadget.name, driver->driver.name);
+	out_be16(&udc->usb_regs->usb_usber, 0xffff);
+	out_be16(&udc->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
+	udc->usb_state = USB_STATE_ATTACHED;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = USB_DIR_OUT;
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	dev_info(udc->dev, "%s bind to driver %s\n", udc->gadget.name,
+			driver->driver.name);
 	return 0;
 }
 
-static int fsl_qe_stop(struct usb_gadget_driver *driver)
+static int fsl_qe_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
+	struct qe_udc *udc;
 	struct qe_ep *loop_ep;
 	unsigned long flags;
 
-	if (!udc_controller)
-		return -ENODEV;
-
-	if (!driver || driver != udc_controller->driver)
-		return -EINVAL;
-
+	udc = container_of(gadget, struct qe_udc, gadget);
 	/* stop usb controller, disable intr */
-	qe_usb_disable();
+	qe_usb_disable(udc);
 
 	/* in fact, no needed */
-	udc_controller->usb_state = USB_STATE_ATTACHED;
-	udc_controller->ep0_state = WAIT_FOR_SETUP;
-	udc_controller->ep0_dir = 0;
+	udc->usb_state = USB_STATE_ATTACHED;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = 0;
 
 	/* stand operation */
-	spin_lock_irqsave(&udc_controller->lock, flags);
-	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
-	nuke(&udc_controller->eps[0], -ESHUTDOWN);
-	list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
-				ep.ep_list)
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	nuke(&udc->eps[0], -ESHUTDOWN);
+	list_for_each_entry(loop_ep, &udc->gadget.ep_list, ep.ep_list)
 		nuke(loop_ep, -ESHUTDOWN);
-	spin_unlock_irqrestore(&udc_controller->lock, flags);
+	spin_unlock_irqrestore(&udc->lock, flags);
 
-	/* report disconnect; the controller is already quiesced */
-	driver->disconnect(&udc_controller->gadget);
+	udc->gadget.dev.driver = NULL;
+	udc->driver = NULL;
 
-	/* unbind gadget and unhook driver. */
-	driver->unbind(&udc_controller->gadget);
-	udc_controller->gadget.dev.driver = NULL;
-	udc_controller->driver = NULL;
-
-	dev_info(udc_controller->dev, "unregistered gadget driver '%s'\r\n",
+	dev_info(udc->dev, "unregistered gadget driver '%s'\r\n",
 			driver->driver.name);
 	return 0;
 }
@@ -2502,7 +2431,7 @@
 	ep->ep.ops = &qe_ep_ops;
 	ep->stopped = 1;
 	ep->ep.maxpacket = (unsigned short) ~0;
-	ep->desc = NULL;
+	ep->ep.desc = NULL;
 	ep->dir = 0xff;
 	ep->epnum = (u8)pipe_num;
 	ep->sent = 0;
@@ -2531,21 +2460,22 @@
  *----------------------------------------------------------------------*/
 static void qe_udc_release(struct device *dev)
 {
-	int i = 0;
+	struct qe_udc *udc = container_of(dev, struct qe_udc, gadget.dev);
+	int i;
 
-	complete(udc_controller->done);
-	cpm_muram_free(cpm_muram_offset(udc_controller->ep_param[0]));
+	complete(udc->done);
+	cpm_muram_free(cpm_muram_offset(udc->ep_param[0]));
 	for (i = 0; i < USB_MAX_ENDPOINTS; i++)
-		udc_controller->ep_param[i] = NULL;
+		udc->ep_param[i] = NULL;
 
-	kfree(udc_controller);
-	udc_controller = NULL;
+	kfree(udc);
 }
 
 /* Driver probe functions */
 static const struct of_device_id qe_udc_match[];
 static int __devinit qe_udc_probe(struct platform_device *ofdev)
 {
+	struct qe_udc *udc;
 	const struct of_device_id *match;
 	struct device_node *np = ofdev->dev.of_node;
 	struct qe_ep *ep;
@@ -2562,44 +2492,44 @@
 		return -ENODEV;
 
 	/* Initialize the udc structure including QH member and other member */
-	udc_controller = qe_udc_config(ofdev);
-	if (!udc_controller) {
+	udc = qe_udc_config(ofdev);
+	if (!udc) {
 		dev_err(&ofdev->dev, "failed to initialize\n");
 		return -ENOMEM;
 	}
 
-	udc_controller->soc_type = (unsigned long)match->data;
-	udc_controller->usb_regs = of_iomap(np, 0);
-	if (!udc_controller->usb_regs) {
+	udc->soc_type = (unsigned long)match->data;
+	udc->usb_regs = of_iomap(np, 0);
+	if (!udc->usb_regs) {
 		ret = -ENOMEM;
 		goto err1;
 	}
 
 	/* initialize usb hw reg except for regs for EP,
 	 * leave usbintr reg untouched*/
-	qe_udc_reg_init(udc_controller);
+	qe_udc_reg_init(udc);
 
 	/* here comes the stand operations for probe
 	 * set the qe_udc->gadget.xxx */
-	udc_controller->gadget.ops = &qe_gadget_ops;
+	udc->gadget.ops = &qe_gadget_ops;
 
 	/* gadget.ep0 is a pointer */
-	udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
+	udc->gadget.ep0 = &udc->eps[0].ep;
 
-	INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
 
 	/* modify in register gadget process */
-	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
 
 	/* name: Identifies the controller hardware type. */
-	udc_controller->gadget.name = driver_name;
+	udc->gadget.name = driver_name;
 
-	device_initialize(&udc_controller->gadget.dev);
+	device_initialize(&udc->gadget.dev);
 
-	dev_set_name(&udc_controller->gadget.dev, "gadget");
+	dev_set_name(&udc->gadget.dev, "gadget");
 
-	udc_controller->gadget.dev.release = qe_udc_release;
-	udc_controller->gadget.dev.parent = &ofdev->dev;
+	udc->gadget.dev.release = qe_udc_release;
+	udc->gadget.dev.parent = &ofdev->dev;
 
 	/* initialize qe_ep struct */
 	for (i = 0; i < USB_MAX_ENDPOINTS ; i++) {
@@ -2608,104 +2538,104 @@
 
 		/* setup the qe_ep struct and link ep.ep.list
 		 * into gadget.ep_list */
-		qe_ep_config(udc_controller, (unsigned char)i);
+		qe_ep_config(udc, (unsigned char)i);
 	}
 
 	/* ep0 initialization in here */
-	ret = qe_ep_init(udc_controller, 0, &qe_ep0_desc);
+	ret = qe_ep_init(udc, 0, &qe_ep0_desc);
 	if (ret)
 		goto err2;
 
 	/* create a buf for ZLP send, need to remain zeroed */
-	udc_controller->nullbuf = kzalloc(256, GFP_KERNEL);
-	if (udc_controller->nullbuf == NULL) {
-		dev_err(udc_controller->dev, "cannot alloc nullbuf\n");
+	udc->nullbuf = kzalloc(256, GFP_KERNEL);
+	if (udc->nullbuf == NULL) {
+		dev_err(udc->dev, "cannot alloc nullbuf\n");
 		ret = -ENOMEM;
 		goto err3;
 	}
 
 	/* buffer for data of get_status request */
-	udc_controller->statusbuf = kzalloc(2, GFP_KERNEL);
-	if (udc_controller->statusbuf == NULL) {
+	udc->statusbuf = kzalloc(2, GFP_KERNEL);
+	if (udc->statusbuf == NULL) {
 		ret = -ENOMEM;
 		goto err4;
 	}
 
-	udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf);
-	if (udc_controller->nullp == DMA_ADDR_INVALID) {
-		udc_controller->nullp = dma_map_single(
-					udc_controller->gadget.dev.parent,
-					udc_controller->nullbuf,
+	udc->nullp = virt_to_phys((void *)udc->nullbuf);
+	if (udc->nullp == DMA_ADDR_INVALID) {
+		udc->nullp = dma_map_single(
+					udc->gadget.dev.parent,
+					udc->nullbuf,
 					256,
 					DMA_TO_DEVICE);
-		udc_controller->nullmap = 1;
+		udc->nullmap = 1;
 	} else {
-		dma_sync_single_for_device(udc_controller->gadget.dev.parent,
-					udc_controller->nullp, 256,
+		dma_sync_single_for_device(udc->gadget.dev.parent,
+					udc->nullp, 256,
 					DMA_TO_DEVICE);
 	}
 
-	tasklet_init(&udc_controller->rx_tasklet, ep_rx_tasklet,
-			(unsigned long)udc_controller);
+	tasklet_init(&udc->rx_tasklet, ep_rx_tasklet,
+			(unsigned long)udc);
 	/* request irq and disable DR  */
-	udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
-	if (!udc_controller->usb_irq) {
+	udc->usb_irq = irq_of_parse_and_map(np, 0);
+	if (!udc->usb_irq) {
 		ret = -EINVAL;
 		goto err_noirq;
 	}
 
-	ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
-				driver_name, udc_controller);
+	ret = request_irq(udc->usb_irq, qe_udc_irq, 0,
+				driver_name, udc);
 	if (ret) {
-		dev_err(udc_controller->dev, "cannot request irq %d err %d \n",
-			udc_controller->usb_irq, ret);
+		dev_err(udc->dev, "cannot request irq %d err %d\n",
+				udc->usb_irq, ret);
 		goto err5;
 	}
 
-	ret = device_add(&udc_controller->gadget.dev);
+	ret = device_add(&udc->gadget.dev);
 	if (ret)
 		goto err6;
 
-	ret = usb_add_gadget_udc(&ofdev->dev, &udc_controller->gadget);
+	ret = usb_add_gadget_udc(&ofdev->dev, &udc->gadget);
 	if (ret)
 		goto err7;
 
-	dev_info(udc_controller->dev,
+	dev_set_drvdata(&ofdev->dev, udc);
+	dev_info(udc->dev,
 			"%s USB controller initialized as device\n",
-			(udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
+			(udc->soc_type == PORT_QE) ? "QE" : "CPM");
 	return 0;
 
 err7:
-	device_unregister(&udc_controller->gadget.dev);
+	device_unregister(&udc->gadget.dev);
 err6:
-	free_irq(udc_controller->usb_irq, udc_controller);
+	free_irq(udc->usb_irq, udc);
 err5:
-	irq_dispose_mapping(udc_controller->usb_irq);
+	irq_dispose_mapping(udc->usb_irq);
 err_noirq:
-	if (udc_controller->nullmap) {
-		dma_unmap_single(udc_controller->gadget.dev.parent,
-			udc_controller->nullp, 256,
+	if (udc->nullmap) {
+		dma_unmap_single(udc->gadget.dev.parent,
+			udc->nullp, 256,
 				DMA_TO_DEVICE);
-			udc_controller->nullp = DMA_ADDR_INVALID;
+			udc->nullp = DMA_ADDR_INVALID;
 	} else {
-		dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
-			udc_controller->nullp, 256,
+		dma_sync_single_for_cpu(udc->gadget.dev.parent,
+			udc->nullp, 256,
 				DMA_TO_DEVICE);
 	}
-	kfree(udc_controller->statusbuf);
+	kfree(udc->statusbuf);
 err4:
-	kfree(udc_controller->nullbuf);
+	kfree(udc->nullbuf);
 err3:
-	ep = &udc_controller->eps[0];
+	ep = &udc->eps[0];
 	cpm_muram_free(cpm_muram_offset(ep->rxbase));
 	kfree(ep->rxframe);
 	kfree(ep->rxbuffer);
 	kfree(ep->txframe);
 err2:
-	iounmap(udc_controller->usb_regs);
+	iounmap(udc->usb_regs);
 err1:
-	kfree(udc_controller);
-	udc_controller = NULL;
+	kfree(udc);
 	return ret;
 }
 
@@ -2723,44 +2653,41 @@
 
 static int __devexit qe_udc_remove(struct platform_device *ofdev)
 {
+	struct qe_udc *udc = dev_get_drvdata(&ofdev->dev);
 	struct qe_ep *ep;
 	unsigned int size;
-
 	DECLARE_COMPLETION(done);
 
-	if (!udc_controller)
-		return -ENODEV;
+	usb_del_gadget_udc(&udc->gadget);
 
-	usb_del_gadget_udc(&udc_controller->gadget);
+	udc->done = &done;
+	tasklet_disable(&udc->rx_tasklet);
 
-	udc_controller->done = &done;
-	tasklet_disable(&udc_controller->rx_tasklet);
-
-	if (udc_controller->nullmap) {
-		dma_unmap_single(udc_controller->gadget.dev.parent,
-			udc_controller->nullp, 256,
+	if (udc->nullmap) {
+		dma_unmap_single(udc->gadget.dev.parent,
+			udc->nullp, 256,
 				DMA_TO_DEVICE);
-			udc_controller->nullp = DMA_ADDR_INVALID;
+			udc->nullp = DMA_ADDR_INVALID;
 	} else {
-		dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
-			udc_controller->nullp, 256,
+		dma_sync_single_for_cpu(udc->gadget.dev.parent,
+			udc->nullp, 256,
 				DMA_TO_DEVICE);
 	}
-	kfree(udc_controller->statusbuf);
-	kfree(udc_controller->nullbuf);
+	kfree(udc->statusbuf);
+	kfree(udc->nullbuf);
 
-	ep = &udc_controller->eps[0];
+	ep = &udc->eps[0];
 	cpm_muram_free(cpm_muram_offset(ep->rxbase));
 	size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (USB_BDRING_LEN + 1);
 
 	kfree(ep->rxframe);
 	if (ep->rxbufmap) {
-		dma_unmap_single(udc_controller->gadget.dev.parent,
+		dma_unmap_single(udc->gadget.dev.parent,
 				ep->rxbuf_d, size,
 				DMA_FROM_DEVICE);
 		ep->rxbuf_d = DMA_ADDR_INVALID;
 	} else {
-		dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+		dma_sync_single_for_cpu(udc->gadget.dev.parent,
 				ep->rxbuf_d, size,
 				DMA_FROM_DEVICE);
 	}
@@ -2768,14 +2695,14 @@
 	kfree(ep->rxbuffer);
 	kfree(ep->txframe);
 
-	free_irq(udc_controller->usb_irq, udc_controller);
-	irq_dispose_mapping(udc_controller->usb_irq);
+	free_irq(udc->usb_irq, udc);
+	irq_dispose_mapping(udc->usb_irq);
 
-	tasklet_kill(&udc_controller->rx_tasklet);
+	tasklet_kill(&udc->rx_tasklet);
 
-	iounmap(udc_controller->usb_regs);
+	iounmap(udc->usb_regs);
 
-	device_unregister(&udc_controller->gadget.dev);
+	device_unregister(&udc->gadget.dev);
 	/* wait for release() of gadget.dev to free udc */
 	wait_for_completion(&done);
 
diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h
index 1da5fb0..4c07ca9 100644
--- a/drivers/usb/gadget/fsl_qe_udc.h
+++ b/drivers/usb/gadget/fsl_qe_udc.h
@@ -266,7 +266,6 @@
 	struct usb_ep ep;
 	struct list_head queue;
 	struct qe_udc *udc;
-	const struct usb_endpoint_descriptor *desc;
 	struct usb_gadget *gadget;
 
 	u8 state;
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 55abfb6..2831685 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2007,2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007,2011-2012 Freescale Semiconductor, Inc.
  * All rights reserved.
  *
  * Author: Li Yang <leoli@freescale.com>
@@ -58,9 +58,8 @@
 static const char driver_desc[] = DRIVER_DESC;
 
 static struct usb_dr_device *dr_regs;
-#ifndef CONFIG_ARCH_MXC
+
 static struct usb_sys_interface *usb_sys_regs;
-#endif
 
 /* it is initialized in probe()  */
 static struct fsl_udc *udc_controller = NULL;
@@ -244,10 +243,9 @@
 {
 	unsigned int tmp, portctrl, ep_num;
 	unsigned int max_no_of_ep;
-#ifndef CONFIG_ARCH_MXC
 	unsigned int ctrl;
-#endif
 	unsigned long timeout;
+
 #define FSL_UDC_RESET_TIMEOUT 1000
 
 	/* Config PHY interface */
@@ -255,12 +253,32 @@
 	portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH);
 	switch (udc->phy_mode) {
 	case FSL_USB2_PHY_ULPI:
+		if (udc->pdata->have_sysif_regs) {
+			if (udc->pdata->controller_ver) {
+				/* controller version 1.6 or above */
+				ctrl = __raw_readl(&usb_sys_regs->control);
+				ctrl &= ~USB_CTRL_UTMI_PHY_EN;
+				ctrl |= USB_CTRL_USB_EN;
+				__raw_writel(ctrl, &usb_sys_regs->control);
+			}
+		}
 		portctrl |= PORTSCX_PTS_ULPI;
 		break;
 	case FSL_USB2_PHY_UTMI_WIDE:
 		portctrl |= PORTSCX_PTW_16BIT;
 		/* fall through */
 	case FSL_USB2_PHY_UTMI:
+		if (udc->pdata->have_sysif_regs) {
+			if (udc->pdata->controller_ver) {
+				/* controller version 1.6 or above */
+				ctrl = __raw_readl(&usb_sys_regs->control);
+				ctrl |= (USB_CTRL_UTMI_PHY_EN |
+					USB_CTRL_USB_EN);
+				__raw_writel(ctrl, &usb_sys_regs->control);
+				mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI
+					PHY CLK to become stable - 10ms*/
+			}
+		}
 		portctrl |= PORTSCX_PTS_UTMI;
 		break;
 	case FSL_USB2_PHY_SERIAL:
@@ -549,7 +567,7 @@
 	ep = container_of(_ep, struct fsl_ep, ep);
 
 	/* catch various bogus parameters */
-	if (!_ep || !desc || ep->desc
+	if (!_ep || !desc || ep->ep.desc
 			|| (desc->bDescriptorType != USB_DT_ENDPOINT))
 		return -EINVAL;
 
@@ -590,7 +608,7 @@
 
 	spin_lock_irqsave(&udc->lock, flags);
 	ep->ep.maxpacket = max;
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->stopped = 0;
 
 	/* Controller related setup */
@@ -614,7 +632,7 @@
 	retval = 0;
 
 	VDBG("enabled %s (ep%d%s) maxpacket %d",ep->ep.name,
-			ep->desc->bEndpointAddress & 0x0f,
+			ep->ep.desc->bEndpointAddress & 0x0f,
 			(desc->bEndpointAddress & USB_DIR_IN)
 				? "in" : "out", max);
 en_done:
@@ -634,7 +652,7 @@
 	int ep_num;
 
 	ep = container_of(_ep, struct fsl_ep, ep);
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		VDBG("%s not enabled", _ep ? ep->ep.name : NULL);
 		return -EINVAL;
 	}
@@ -657,7 +675,6 @@
 	/* nuke all pending requests (does flush) */
 	nuke(ep, -ESHUTDOWN);
 
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->stopped = 1;
 	spin_unlock_irqrestore(&udc->lock, flags);
@@ -736,6 +753,8 @@
 		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
 		lastreq->tail->next_td_ptr =
 			cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
+		/* Ensure dTD's next dtd pointer to be updated */
+		wmb();
 		/* Read prime bit, if 1 goto done */
 		if (fsl_readl(&dr_regs->endpointprime) & bitmask)
 			return;
@@ -874,11 +893,11 @@
 		VDBG("%s, bad params", __func__);
 		return -EINVAL;
 	}
-	if (unlikely(!_ep || !ep->desc)) {
+	if (unlikely(!_ep || !ep->ep.desc)) {
 		VDBG("%s, bad ep", __func__);
 		return -EINVAL;
 	}
-	if (usb_endpoint_xfer_isoc(ep->desc)) {
+	if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
 		if (req->req.length > ep->ep.maxpacket)
 			return -EMSGSIZE;
 	}
@@ -1017,12 +1036,12 @@
 
 	ep = container_of(_ep, struct fsl_ep, ep);
 	udc = ep->udc;
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		status = -EINVAL;
 		goto out;
 	}
 
-	if (usb_endpoint_xfer_isoc(ep->desc)) {
+	if (usb_endpoint_xfer_isoc(ep->ep.desc)) {
 		status = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1061,7 +1080,7 @@
 	struct ep_queue_head *qh;
 
 	ep = container_of(_ep, struct fsl_ep, ep);
-	if (!_ep || (!ep->desc && ep_index(ep) != 0))
+	if (!_ep || (!ep->ep.desc && ep_index(ep) != 0))
 		return -ENODEV;
 
 	udc = (struct fsl_udc *)ep->udc;
@@ -1094,7 +1113,7 @@
 		return;
 	} else {
 		ep = container_of(_ep, struct fsl_ep, ep);
-		if (!ep->desc)
+		if (!ep->ep.desc)
 			return;
 	}
 	ep_num = ep_index(ep);
@@ -1349,7 +1368,7 @@
 		target_ep = get_ep_by_pipe(udc, get_pipe_by_windex(index));
 
 		/* stall if endpoint doesn't exist */
-		if (!target_ep->desc)
+		if (!target_ep->ep.desc)
 			goto stall;
 		tmp = dr_ep_get_stall(ep_index(target_ep), ep_is_in(target_ep))
 				<< USB_ENDPOINT_HALT;
@@ -2259,7 +2278,7 @@
 	}
 	/* other gadget->eplist ep */
 	list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
-		if (ep->desc) {
+		if (ep->ep.desc) {
 			t = scnprintf(next, size,
 					"\nFor %s Maxpkt is 0x%x "
 					"index is 0x%x\n",
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index e651469..5cd7b7e 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -1,4 +1,12 @@
 /*
+ * Copyright (C) 2004,2012 Freescale Semiconductor, Inc
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
  * Freescale USB device/endpoint management registers
  */
 #ifndef __FSL_USB2_UDC_H
@@ -348,6 +356,9 @@
 /* control Register Bit Masks */
 #define  USB_CTRL_IOENB                       0x00000004
 #define  USB_CTRL_ULPI_INT0EN                 0x00000001
+#define USB_CTRL_UTMI_PHY_EN		      0x00000200
+#define USB_CTRL_USB_EN			      0x00000004
+#define USB_CTRL_ULPI_PHY_CLK_SEL	      0x00000400
 
 /* Endpoint Queue Head data struct
  * Rem: all the variables of qh are LittleEndian Mode
@@ -450,7 +461,6 @@
 	struct list_head queue;
 	struct fsl_udc *udc;
 	struct ep_queue_head *qh;
-	const struct usb_endpoint_descriptor *desc;
 	struct usb_gadget *gadget;
 
 	char name[14];
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c
index 5831cb4..cdd9454 100644
--- a/drivers/usb/gadget/fusb300_udc.c
+++ b/drivers/usb/gadget/fusb300_udc.c
@@ -203,7 +203,7 @@
 	struct fusb300 *fusb300 = ep->fusb300;
 	struct fusb300_ep_info info;
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 
 	info.interval = 0;
 	info.addrofs = 0;
@@ -443,7 +443,7 @@
 	req->req.actual = 0;
 	req->req.status = -EINPROGRESS;
 
-	if (ep->desc == NULL) /* ep0 */
+	if (ep->ep.desc == NULL) /* ep0 */
 		ep0_queue(ep, req);
 	else if (request && !ep->stall)
 		enable_fifo_int(ep);
diff --git a/drivers/usb/gadget/fusb300_udc.h b/drivers/usb/gadget/fusb300_udc.h
index 92745bd..542cd83 100644
--- a/drivers/usb/gadget/fusb300_udc.h
+++ b/drivers/usb/gadget/fusb300_udc.h
@@ -650,7 +650,6 @@
 
 	unsigned char		epnum;
 	unsigned char		type;
-	const struct usb_endpoint_descriptor	*desc;
 };
 
 struct fusb300 {
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index a85eaf4..d3ace90 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -67,6 +67,15 @@
 #define GFS_VENDOR_ID	0x1d6b	/* Linux Foundation */
 #define GFS_PRODUCT_ID	0x0105	/* FunctionFS Gadget */
 
+#define GFS_MAX_DEVS	10
+
+struct gfs_ffs_obj {
+	const char *name;
+	bool mounted;
+	bool desc_ready;
+	struct ffs_data *ffs_data;
+};
+
 static struct usb_device_descriptor gfs_dev_desc = {
 	.bLength		= sizeof gfs_dev_desc,
 	.bDescriptorType	= USB_DT_DEVICE,
@@ -78,12 +87,17 @@
 	.idProduct		= cpu_to_le16(GFS_PRODUCT_ID),
 };
 
+static char *func_names[GFS_MAX_DEVS];
+static unsigned int func_num;
+
 module_param_named(bDeviceClass,    gfs_dev_desc.bDeviceClass,    byte,   0644);
 MODULE_PARM_DESC(bDeviceClass, "USB Device class");
 module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte,   0644);
 MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass");
 module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte,   0644);
 MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol");
+module_param_array_named(functions, func_names, charp, &func_num, 0);
+MODULE_PARM_DESC(functions, "USB Functions list");
 
 static const struct usb_descriptor_header *gfs_otg_desc[] = {
 	(const struct usb_descriptor_header *)
@@ -158,13 +172,34 @@
 	.iProduct	= DRIVER_DESC,
 };
 
-static struct ffs_data *gfs_ffs_data;
-static unsigned long gfs_registered;
+static DEFINE_MUTEX(gfs_lock);
+static unsigned int missing_funcs;
+static bool gfs_ether_setup;
+static bool gfs_registered;
+static bool gfs_single_func;
+static struct gfs_ffs_obj *ffs_tab;
 
 static int __init gfs_init(void)
 {
+	int i;
+
 	ENTER();
 
+	if (!func_num) {
+		gfs_single_func = true;
+		func_num = 1;
+	}
+
+	ffs_tab = kcalloc(func_num, sizeof *ffs_tab, GFP_KERNEL);
+	if (!ffs_tab)
+		return -ENOMEM;
+
+	if (!gfs_single_func)
+		for (i = 0; i < func_num; i++)
+			ffs_tab[i].name = func_names[i];
+
+	missing_funcs = func_num;
+
 	return functionfs_init();
 }
 module_init(gfs_init);
@@ -172,63 +207,165 @@
 static void __exit gfs_exit(void)
 {
 	ENTER();
+	mutex_lock(&gfs_lock);
 
-	if (test_and_clear_bit(0, &gfs_registered))
+	if (gfs_registered)
 		usb_composite_unregister(&gfs_driver);
+	gfs_registered = false;
 
 	functionfs_cleanup();
+
+	mutex_unlock(&gfs_lock);
+	kfree(ffs_tab);
 }
 module_exit(gfs_exit);
 
-static int functionfs_ready_callback(struct ffs_data *ffs)
+static struct gfs_ffs_obj *gfs_find_dev(const char *dev_name)
 {
-	int ret;
+	int i;
 
 	ENTER();
 
-	if (WARN_ON(test_and_set_bit(0, &gfs_registered)))
-		return -EBUSY;
+	if (gfs_single_func)
+		return &ffs_tab[0];
 
-	gfs_ffs_data = ffs;
+	for (i = 0; i < func_num; i++)
+		if (strcmp(ffs_tab[i].name, dev_name) == 0)
+			return &ffs_tab[i];
+
+	return NULL;
+}
+
+static int functionfs_ready_callback(struct ffs_data *ffs)
+{
+	struct gfs_ffs_obj *ffs_obj;
+	int ret;
+
+	ENTER();
+	mutex_lock(&gfs_lock);
+
+	ffs_obj = ffs->private_data;
+	if (!ffs_obj) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (WARN_ON(ffs_obj->desc_ready)) {
+		ret = -EBUSY;
+		goto done;
+	}
+	ffs_obj->desc_ready = true;
+	ffs_obj->ffs_data = ffs;
+
+	if (--missing_funcs) {
+		ret = 0;
+		goto done;
+	}
+
+	if (gfs_registered) {
+		ret = -EBUSY;
+		goto done;
+	}
+	gfs_registered = true;
+
 	ret = usb_composite_probe(&gfs_driver, gfs_bind);
 	if (unlikely(ret < 0))
-		clear_bit(0, &gfs_registered);
+		gfs_registered = false;
+
+done:
+	mutex_unlock(&gfs_lock);
 	return ret;
 }
 
 static void functionfs_closed_callback(struct ffs_data *ffs)
 {
+	struct gfs_ffs_obj *ffs_obj;
+
 	ENTER();
+	mutex_lock(&gfs_lock);
 
-	if (test_and_clear_bit(0, &gfs_registered))
+	ffs_obj = ffs->private_data;
+	if (!ffs_obj)
+		goto done;
+
+	ffs_obj->desc_ready = false;
+	missing_funcs++;
+
+	if (gfs_registered)
 		usb_composite_unregister(&gfs_driver);
+	gfs_registered = false;
+
+done:
+	mutex_unlock(&gfs_lock);
 }
 
-static int functionfs_check_dev_callback(const char *dev_name)
+static void *functionfs_acquire_dev_callback(const char *dev_name)
 {
-	return 0;
+	struct gfs_ffs_obj *ffs_dev;
+
+	ENTER();
+	mutex_lock(&gfs_lock);
+
+	ffs_dev = gfs_find_dev(dev_name);
+	if (!ffs_dev) {
+		ffs_dev = ERR_PTR(-ENODEV);
+		goto done;
+	}
+
+	if (ffs_dev->mounted) {
+		ffs_dev = ERR_PTR(-EBUSY);
+		goto done;
+	}
+	ffs_dev->mounted = true;
+
+done:
+	mutex_unlock(&gfs_lock);
+	return ffs_dev;
 }
 
+static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+{
+	struct gfs_ffs_obj *ffs_dev;
+
+	ENTER();
+	mutex_lock(&gfs_lock);
+
+	ffs_dev = ffs_data->private_data;
+	if (ffs_dev)
+		ffs_dev->mounted = false;
+
+	mutex_unlock(&gfs_lock);
+}
+
+/*
+ * It is assumed that gfs_bind is called from a context where gfs_lock is held
+ */
 static int gfs_bind(struct usb_composite_dev *cdev)
 {
 	int ret, i;
 
 	ENTER();
 
-	if (WARN_ON(!gfs_ffs_data))
+	if (missing_funcs)
 		return -ENODEV;
 
 	ret = gether_setup(cdev->gadget, gfs_hostaddr);
 	if (unlikely(ret < 0))
 		goto error_quick;
+	gfs_ether_setup = true;
 
 	ret = usb_string_ids_tab(cdev, gfs_strings);
 	if (unlikely(ret < 0))
 		goto error;
 
-	ret = functionfs_bind(gfs_ffs_data, cdev);
-	if (unlikely(ret < 0))
-		goto error;
+	for (i = func_num; --i; ) {
+		ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
+		if (unlikely(ret < 0)) {
+			while (++i < func_num)
+				functionfs_unbind(ffs_tab[i].ffs_data);
+			goto error;
+		}
+	}
 
 	for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
 		struct gfs_configuration *c = gfs_configurations + i;
@@ -246,16 +383,22 @@
 	return 0;
 
 error_unbind:
-	functionfs_unbind(gfs_ffs_data);
+	for (i = 0; i < func_num; i++)
+		functionfs_unbind(ffs_tab[i].ffs_data);
 error:
 	gether_cleanup();
 error_quick:
-	gfs_ffs_data = NULL;
+	gfs_ether_setup = false;
 	return ret;
 }
 
+/*
+ * It is assumed that gfs_unbind is called from a context where gfs_lock is held
+ */
 static int gfs_unbind(struct usb_composite_dev *cdev)
 {
+	int i;
+
 	ENTER();
 
 	/*
@@ -266,22 +409,29 @@
 	 * from composite on orror recovery, but what you're gonna
 	 * do...?
 	 */
-	if (gfs_ffs_data) {
+	if (gfs_ether_setup)
 		gether_cleanup();
-		functionfs_unbind(gfs_ffs_data);
-		gfs_ffs_data = NULL;
-	}
+	gfs_ether_setup = false;
+
+	for (i = func_num; --i; )
+		if (ffs_tab[i].ffs_data)
+			functionfs_unbind(ffs_tab[i].ffs_data);
 
 	return 0;
 }
 
+/*
+ * It is assumed that gfs_do_config is called from a context where
+ * gfs_lock is held
+ */
 static int gfs_do_config(struct usb_configuration *c)
 {
 	struct gfs_configuration *gc =
 		container_of(c, struct gfs_configuration, c);
+	int i;
 	int ret;
 
-	if (WARN_ON(!gfs_ffs_data))
+	if (missing_funcs)
 		return -ENODEV;
 
 	if (gadget_is_otg(c->cdev->gadget)) {
@@ -295,9 +445,11 @@
 			return ret;
 	}
 
-	ret = functionfs_bind_config(c->cdev, c, gfs_ffs_data);
-	if (unlikely(ret < 0))
-		return ret;
+	for (i = 0; i < func_num; i++) {
+		ret = functionfs_bind_config(c->cdev, c, ffs_tab[i].ffs_data);
+		if (unlikely(ret < 0))
+			return ret;
+	}
 
 	/*
 	 * After previous do_configs there may be some invalid
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
index e84b3c4..71ca193 100644
--- a/drivers/usb/gadget/g_zero.h
+++ b/drivers/usb/gadget/g_zero.h
@@ -13,10 +13,11 @@
 extern const struct usb_descriptor_header *otg_desc[];
 
 /* common utilities */
-struct usb_request *alloc_ep_req(struct usb_ep *ep);
+struct usb_request *alloc_ep_req(struct usb_ep *ep, int len);
 void free_ep_req(struct usb_ep *ep, struct usb_request *req);
 void disable_endpoints(struct usb_composite_dev *cdev,
-		struct usb_ep *in, struct usb_ep *out);
+		struct usb_ep *in, struct usb_ep *out,
+		struct usb_ep *iso_in, struct usb_ep *iso_out);
 
 /* configuration-specific linkup */
 int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index a8855d0..b8b3a34 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -37,6 +37,7 @@
 #define gadget_is_goku(g)		(!strcmp("goku_udc", (g)->name))
 #define gadget_is_imx(g)		(!strcmp("imx_udc", (g)->name))
 #define gadget_is_langwell(g)		(!strcmp("langwell_udc", (g)->name))
+#define gadget_is_lpc32xx(g)		(!strcmp("lpc32xx_udc", (g)->name))
 #define gadget_is_m66592(g)		(!strcmp("m66592_udc", (g)->name))
 #define gadget_is_musbhdrc(g)		(!strcmp("musb-hdrc", (g)->name))
 #define gadget_is_net2272(g)		(!strcmp("net2272", (g)->name))
@@ -118,6 +119,8 @@
 		return 0x31;
 	else if (gadget_is_dwc3(gadget))
 		return 0x32;
+	else if (gadget_is_lpc32xx(gadget))
+		return 0x33;
 
 	return -ENOENT;
 }
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index e151d6b..b241e6c 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -102,7 +102,7 @@
 	unsigned long	flags;
 
 	ep = container_of(_ep, struct goku_ep, ep);
-	if (!_ep || !desc || ep->desc
+	if (!_ep || !desc || ep->ep.desc
 			|| desc->bDescriptorType != USB_DT_ENDPOINT)
 		return -EINVAL;
 	dev = ep->dev;
@@ -176,7 +176,7 @@
 	command(ep->dev->regs, COMMAND_RESET, ep->num);
 	ep->ep.maxpacket = max;
 	ep->stopped = 0;
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	spin_unlock_irqrestore(&ep->dev->lock, flags);
 
 	DBG(dev, "enable %s %s %s maxpacket %u\n", ep->ep.name,
@@ -233,7 +233,6 @@
 	}
 
 	ep->ep.maxpacket = MAX_FIFO_SIZE;
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->stopped = 1;
 	ep->irqs = 0;
@@ -247,7 +246,7 @@
 	unsigned long	flags;
 
 	ep = container_of(_ep, struct goku_ep, ep);
-	if (!_ep || !ep->desc)
+	if (!_ep || !ep->ep.desc)
 		return -ENODEV;
 	dev = ep->dev;
 	if (dev->ep0state == EP0_SUSPEND)
@@ -722,7 +721,7 @@
 			|| !_req->buf || !list_empty(&req->queue)))
 		return -EINVAL;
 	ep = container_of(_ep, struct goku_ep, ep);
-	if (unlikely(!_ep || (!ep->desc && ep->num != 0)))
+	if (unlikely(!_ep || (!ep->ep.desc && ep->num != 0)))
 		return -EINVAL;
 	dev = ep->dev;
 	if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN))
@@ -815,7 +814,7 @@
 	unsigned long		flags;
 
 	ep = container_of(_ep, struct goku_ep, ep);
-	if (!_ep || !_req || (!ep->desc && ep->num != 0))
+	if (!_ep || !_req || (!ep->ep.desc && ep->num != 0))
 		return -EINVAL;
 	dev = ep->dev;
 	if (!dev->driver)
@@ -896,7 +895,7 @@
 			return -EINVAL;
 
 	/* don't change EPxSTATUS_EP_INVALID to READY */
-	} else if (!ep->desc) {
+	} else if (!ep->ep.desc) {
 		DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name);
 		return -EINVAL;
 	}
@@ -955,7 +954,7 @@
 	VDBG(ep->dev, "%s %s\n", __func__, ep->ep.name);
 
 	/* don't change EPxSTATUS_EP_INVALID to READY */
-	if (!ep->desc && ep->num != 0) {
+	if (!ep->ep.desc && ep->num != 0) {
 		DBG(ep->dev, "%s %s inactive?\n", __func__, ep->ep.name);
 		return;
 	}
@@ -1152,7 +1151,7 @@
 		struct goku_ep		*ep = &dev->ep [i];
 		struct goku_request	*req;
 
-		if (i && !ep->desc)
+		if (i && !ep->ep.desc)
 			continue;
 
 		tmp = readl(ep->reg_status);
@@ -1473,7 +1472,8 @@
 			case USB_RECIP_ENDPOINT:
 				tmp = le16_to_cpu(ctrl.wIndex) & 0x0f;
 				/* active endpoint */
-				if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
+				if (tmp > 3 ||
+				    (!dev->ep[tmp].ep.desc && tmp != 0))
 					goto stall;
 				if (ctrl.wIndex & cpu_to_le16(
 						USB_DIR_IN)) {
@@ -1895,14 +1895,4 @@
 	/* FIXME add power management support */
 };
 
-static int __init init (void)
-{
-	return pci_register_driver (&goku_pci_driver);
-}
-module_init (init);
-
-static void __exit cleanup (void)
-{
-	pci_unregister_driver (&goku_pci_driver);
-}
-module_exit (cleanup);
+module_pci_driver(goku_pci_driver);
diff --git a/drivers/usb/gadget/goku_udc.h b/drivers/usb/gadget/goku_udc.h
index e7e0c69..85cdce0 100644
--- a/drivers/usb/gadget/goku_udc.h
+++ b/drivers/usb/gadget/goku_udc.h
@@ -216,7 +216,6 @@
 
 	/* analogous to a host-side qh */
 	struct list_head			queue;
-	const struct usb_endpoint_descriptor	*desc;
 
 	u32 __iomem				*reg_fifo;
 	u32 __iomem				*reg_mode;
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index 8d1c75a..54034f8 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1237,14 +1237,15 @@
  *******************************************************************************
  */
 
-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 int imx_udc_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver);
+static int imx_udc_stop(struct usb_gadget *gadget,
+		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,
+	.get_frame	= imx_udc_get_frame,
+	.wakeup		= imx_udc_wakeup,
+	.udc_start	= imx_udc_start,
+	.udc_stop	= imx_udc_stop,
 };
 
 static struct imx_udc_struct controller = {
@@ -1329,23 +1330,13 @@
  * USB gadget driver functions
  *******************************************************************************
  */
-static int imx_udc_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
+static int imx_udc_start(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	struct imx_udc_struct *imx_usb = &controller;
+	struct imx_udc_struct *imx_usb;
 	int retval;
 
-	if (!driver
-		|| driver->max_speed < USB_SPEED_FULL
-		|| !bind
-		|| !driver->disconnect
-		|| !driver->setup)
-			return -EINVAL;
-	if (!imx_usb)
-		return -ENODEV;
-	if (imx_usb->driver)
-		return -EBUSY;
-
+	imx_usb = container_of(gadget, struct imx_udc_struct, gadget);
 	/* first hook up the driver ... */
 	imx_usb->driver = driver;
 	imx_usb->gadget.dev.driver = &driver->driver;
@@ -1353,14 +1344,6 @@
 	retval = device_add(&imx_usb->gadget.dev);
 	if (retval)
 		goto fail;
-	retval = bind(&imx_usb->gadget);
-	if (retval) {
-		D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n",
-			__func__, driver->driver.name, retval);
-		device_del(&imx_usb->gadget.dev);
-
-		goto fail;
-	}
 
 	D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n",
 		__func__, driver->driver.name);
@@ -1374,20 +1357,16 @@
 	return retval;
 }
 
-static int imx_udc_stop(struct usb_gadget_driver *driver)
+static int imx_udc_stop(struct usb_gadget *gadget,
+		struct usb_gadget_driver *driver)
 {
-	struct imx_udc_struct *imx_usb = &controller;
-
-	if (!imx_usb)
-		return -ENODEV;
-	if (!driver || driver != imx_usb->driver || !driver->unbind)
-		return -EINVAL;
+	struct imx_udc_struct *imx_usb = container_of(gadget,
+			struct imx_udc_struct, gadget);
 
 	udc_stop_activity(imx_usb, driver);
 	imx_udc_disable(imx_usb);
 	del_timer(&imx_usb->timer);
 
-	driver->unbind(&imx_usb->gadget);
 	imx_usb->gadget.dev.driver = NULL;
 	imx_usb->driver = NULL;
 
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
deleted file mode 100644
index f9cedd5..0000000
--- a/drivers/usb/gadget/langwell_udc.c
+++ /dev/null
@@ -1,3434 +0,0 @@
-/*
- * Intel Langwell USB Device Controller driver
- * Copyright (C) 2008-2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- */
-
-
-/* #undef	DEBUG */
-/* #undef	VERBOSE_DEBUG */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/timer.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb/otg.h>
-#include <linux/pm.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <asm/unaligned.h>
-
-#include "langwell_udc.h"
-
-
-#define	DRIVER_DESC		"Intel Langwell USB Device Controller driver"
-#define	DRIVER_VERSION		"16 May 2009"
-
-static const char driver_name[] = "langwell_udc";
-static const char driver_desc[] = DRIVER_DESC;
-
-
-/* for endpoint 0 operations */
-static const struct usb_endpoint_descriptor
-langwell_ep0_desc = {
-	.bLength =		USB_DT_ENDPOINT_SIZE,
-	.bDescriptorType =	USB_DT_ENDPOINT,
-	.bEndpointAddress =	0,
-	.bmAttributes =		USB_ENDPOINT_XFER_CONTROL,
-	.wMaxPacketSize =	EP0_MAX_PKT_SIZE,
-};
-
-
-/*-------------------------------------------------------------------------*/
-/* debugging */
-
-#ifdef	VERBOSE_DEBUG
-static inline void print_all_registers(struct langwell_udc *dev)
-{
-	int	i;
-
-	/* Capability Registers */
-	dev_dbg(&dev->pdev->dev,
-		"Capability Registers (offset: 0x%04x, length: 0x%08x)\n",
-		CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs));
-	dev_dbg(&dev->pdev->dev, "caplength=0x%02x\n",
-			readb(&dev->cap_regs->caplength));
-	dev_dbg(&dev->pdev->dev, "hciversion=0x%04x\n",
-			readw(&dev->cap_regs->hciversion));
-	dev_dbg(&dev->pdev->dev, "hcsparams=0x%08x\n",
-			readl(&dev->cap_regs->hcsparams));
-	dev_dbg(&dev->pdev->dev, "hccparams=0x%08x\n",
-			readl(&dev->cap_regs->hccparams));
-	dev_dbg(&dev->pdev->dev, "dciversion=0x%04x\n",
-			readw(&dev->cap_regs->dciversion));
-	dev_dbg(&dev->pdev->dev, "dccparams=0x%08x\n",
-			readl(&dev->cap_regs->dccparams));
-
-	/* Operational Registers */
-	dev_dbg(&dev->pdev->dev,
-		"Operational Registers (offset: 0x%04x, length: 0x%08x)\n",
-		OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs));
-	dev_dbg(&dev->pdev->dev, "extsts=0x%08x\n",
-			readl(&dev->op_regs->extsts));
-	dev_dbg(&dev->pdev->dev, "extintr=0x%08x\n",
-			readl(&dev->op_regs->extintr));
-	dev_dbg(&dev->pdev->dev, "usbcmd=0x%08x\n",
-			readl(&dev->op_regs->usbcmd));
-	dev_dbg(&dev->pdev->dev, "usbsts=0x%08x\n",
-			readl(&dev->op_regs->usbsts));
-	dev_dbg(&dev->pdev->dev, "usbintr=0x%08x\n",
-			readl(&dev->op_regs->usbintr));
-	dev_dbg(&dev->pdev->dev, "frindex=0x%08x\n",
-			readl(&dev->op_regs->frindex));
-	dev_dbg(&dev->pdev->dev, "ctrldssegment=0x%08x\n",
-			readl(&dev->op_regs->ctrldssegment));
-	dev_dbg(&dev->pdev->dev, "deviceaddr=0x%08x\n",
-			readl(&dev->op_regs->deviceaddr));
-	dev_dbg(&dev->pdev->dev, "endpointlistaddr=0x%08x\n",
-			readl(&dev->op_regs->endpointlistaddr));
-	dev_dbg(&dev->pdev->dev, "ttctrl=0x%08x\n",
-			readl(&dev->op_regs->ttctrl));
-	dev_dbg(&dev->pdev->dev, "burstsize=0x%08x\n",
-			readl(&dev->op_regs->burstsize));
-	dev_dbg(&dev->pdev->dev, "txfilltuning=0x%08x\n",
-			readl(&dev->op_regs->txfilltuning));
-	dev_dbg(&dev->pdev->dev, "txttfilltuning=0x%08x\n",
-			readl(&dev->op_regs->txttfilltuning));
-	dev_dbg(&dev->pdev->dev, "ic_usb=0x%08x\n",
-			readl(&dev->op_regs->ic_usb));
-	dev_dbg(&dev->pdev->dev, "ulpi_viewport=0x%08x\n",
-			readl(&dev->op_regs->ulpi_viewport));
-	dev_dbg(&dev->pdev->dev, "configflag=0x%08x\n",
-			readl(&dev->op_regs->configflag));
-	dev_dbg(&dev->pdev->dev, "portsc1=0x%08x\n",
-			readl(&dev->op_regs->portsc1));
-	dev_dbg(&dev->pdev->dev, "devlc=0x%08x\n",
-			readl(&dev->op_regs->devlc));
-	dev_dbg(&dev->pdev->dev, "otgsc=0x%08x\n",
-			readl(&dev->op_regs->otgsc));
-	dev_dbg(&dev->pdev->dev, "usbmode=0x%08x\n",
-			readl(&dev->op_regs->usbmode));
-	dev_dbg(&dev->pdev->dev, "endptnak=0x%08x\n",
-			readl(&dev->op_regs->endptnak));
-	dev_dbg(&dev->pdev->dev, "endptnaken=0x%08x\n",
-			readl(&dev->op_regs->endptnaken));
-	dev_dbg(&dev->pdev->dev, "endptsetupstat=0x%08x\n",
-			readl(&dev->op_regs->endptsetupstat));
-	dev_dbg(&dev->pdev->dev, "endptprime=0x%08x\n",
-			readl(&dev->op_regs->endptprime));
-	dev_dbg(&dev->pdev->dev, "endptflush=0x%08x\n",
-			readl(&dev->op_regs->endptflush));
-	dev_dbg(&dev->pdev->dev, "endptstat=0x%08x\n",
-			readl(&dev->op_regs->endptstat));
-	dev_dbg(&dev->pdev->dev, "endptcomplete=0x%08x\n",
-			readl(&dev->op_regs->endptcomplete));
-
-	for (i = 0; i < dev->ep_max / 2; i++) {
-		dev_dbg(&dev->pdev->dev, "endptctrl[%d]=0x%08x\n",
-				i, readl(&dev->op_regs->endptctrl[i]));
-	}
-}
-#else
-
-#define	print_all_registers(dev)	do { } while (0)
-
-#endif /* VERBOSE_DEBUG */
-
-
-/*-------------------------------------------------------------------------*/
-
-#define	is_in(ep)	(((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir ==	\
-			USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc)))
-
-#define	DIR_STRING(ep)	(is_in(ep) ? "in" : "out")
-
-
-static char *type_string(const struct usb_endpoint_descriptor *desc)
-{
-	switch (usb_endpoint_type(desc)) {
-	case USB_ENDPOINT_XFER_BULK:
-		return "bulk";
-	case USB_ENDPOINT_XFER_ISOC:
-		return "iso";
-	case USB_ENDPOINT_XFER_INT:
-		return "int";
-	};
-
-	return "control";
-}
-
-
-/* configure endpoint control registers */
-static void ep_reset(struct langwell_ep *ep, unsigned char ep_num,
-		unsigned char is_in, unsigned char ep_type)
-{
-	struct langwell_udc	*dev;
-	u32			endptctrl;
-
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-	if (is_in) {	/* TX */
-		if (ep_num)
-			endptctrl |= EPCTRL_TXR;
-		endptctrl |= EPCTRL_TXE;
-		endptctrl |= ep_type << EPCTRL_TXT_SHIFT;
-	} else {	/* RX */
-		if (ep_num)
-			endptctrl |= EPCTRL_RXR;
-		endptctrl |= EPCTRL_RXE;
-		endptctrl |= ep_type << EPCTRL_RXT_SHIFT;
-	}
-
-	writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* reset ep0 dQH and endptctrl */
-static void ep0_reset(struct langwell_udc *dev)
-{
-	struct langwell_ep	*ep;
-	int			i;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* ep0 in and out */
-	for (i = 0; i < 2; i++) {
-		ep = &dev->ep[i];
-		ep->dev = dev;
-
-		/* ep0 dQH */
-		ep->dqh = &dev->ep_dqh[i];
-
-		/* configure ep0 endpoint capabilities in dQH */
-		ep->dqh->dqh_ios = 1;
-		ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE;
-
-		/* enable ep0-in HW zero length termination select */
-		if (is_in(ep))
-			ep->dqh->dqh_zlt = 0;
-		ep->dqh->dqh_mult = 0;
-
-		ep->dqh->dtd_next = DTD_TERM;
-
-		/* configure ep0 control registers */
-		ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL);
-	}
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* endpoints operations */
-
-/* configure endpoint, making it usable */
-static int langwell_ep_enable(struct usb_ep *_ep,
-		const struct usb_endpoint_descriptor *desc)
-{
-	struct langwell_udc	*dev;
-	struct langwell_ep	*ep;
-	u16			max = 0;
-	unsigned long		flags;
-	int			i, retval = 0;
-	unsigned char		zlt, ios = 0, mult = 0;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !desc || ep->desc
-			|| desc->bDescriptorType != USB_DT_ENDPOINT)
-		return -EINVAL;
-
-	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
-		return -ESHUTDOWN;
-
-	max = usb_endpoint_maxp(desc);
-
-	/*
-	 * disable HW zero length termination select
-	 * driver handles zero length packet through req->req.zero
-	 */
-	zlt = 1;
-
-	/*
-	 * sanity check type, direction, address, and then
-	 * initialize the endpoint capabilities fields in dQH
-	 */
-	switch (usb_endpoint_type(desc)) {
-	case USB_ENDPOINT_XFER_CONTROL:
-		ios = 1;
-		break;
-	case USB_ENDPOINT_XFER_BULK:
-		if ((dev->gadget.speed == USB_SPEED_HIGH
-					&& max != 512)
-				|| (dev->gadget.speed == USB_SPEED_FULL
-					&& max > 64)) {
-			goto done;
-		}
-		break;
-	case USB_ENDPOINT_XFER_INT:
-		if (strstr(ep->ep.name, "-iso")) /* bulk is ok */
-			goto done;
-
-		switch (dev->gadget.speed) {
-		case USB_SPEED_HIGH:
-			if (max <= 1024)
-				break;
-		case USB_SPEED_FULL:
-			if (max <= 64)
-				break;
-		default:
-			if (max <= 8)
-				break;
-			goto done;
-		}
-		break;
-	case USB_ENDPOINT_XFER_ISOC:
-		if (strstr(ep->ep.name, "-bulk")
-				|| strstr(ep->ep.name, "-int"))
-			goto done;
-
-		switch (dev->gadget.speed) {
-		case USB_SPEED_HIGH:
-			if (max <= 1024)
-				break;
-		case USB_SPEED_FULL:
-			if (max <= 1023)
-				break;
-		default:
-			goto done;
-		}
-		/*
-		 * FIXME:
-		 * calculate transactions needed for high bandwidth iso
-		 */
-		mult = (unsigned char)(1 + ((max >> 11) & 0x03));
-		max = max & 0x8ff;	/* bit 0~10 */
-		/* 3 transactions at most */
-		if (mult > 3)
-			goto done;
-		break;
-	default:
-		goto done;
-	}
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	ep->ep.maxpacket = max;
-	ep->desc = desc;
-	ep->stopped = 0;
-	ep->ep_num = usb_endpoint_num(desc);
-
-	/* ep_type */
-	ep->ep_type = usb_endpoint_type(desc);
-
-	/* configure endpoint control registers */
-	ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type);
-
-	/* configure endpoint capabilities in dQH */
-	i = ep->ep_num * 2 + is_in(ep);
-	ep->dqh = &dev->ep_dqh[i];
-	ep->dqh->dqh_ios = ios;
-	ep->dqh->dqh_mpl = cpu_to_le16(max);
-	ep->dqh->dqh_zlt = zlt;
-	ep->dqh->dqh_mult = mult;
-	ep->dqh->dtd_next = DTD_TERM;
-
-	dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n",
-			_ep->name,
-			ep->ep_num,
-			DIR_STRING(ep),
-			type_string(desc),
-			max);
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-done:
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return retval;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* retire a request */
-static void done(struct langwell_ep *ep, struct langwell_request *req,
-		int status)
-{
-	struct langwell_udc	*dev = ep->dev;
-	unsigned		stopped = ep->stopped;
-	struct langwell_dtd	*curr_dtd, *next_dtd;
-	int			i;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* remove the req from ep->queue */
-	list_del_init(&req->queue);
-
-	if (req->req.status == -EINPROGRESS)
-		req->req.status = status;
-	else
-		status = req->req.status;
-
-	/* free dTD for the request */
-	next_dtd = req->head;
-	for (i = 0; i < req->dtd_count; i++) {
-		curr_dtd = next_dtd;
-		if (i != req->dtd_count - 1)
-			next_dtd = curr_dtd->next_dtd_virt;
-		dma_pool_free(dev->dtd_pool, curr_dtd, curr_dtd->dtd_dma);
-	}
-
-	usb_gadget_unmap_request(&dev->gadget, &req->req, is_in(ep));
-
-	if (status != -ESHUTDOWN)
-		dev_dbg(&dev->pdev->dev,
-				"complete %s, req %p, stat %d, len %u/%u\n",
-				ep->ep.name, &req->req, status,
-				req->req.actual, req->req.length);
-
-	/* don't modify queue heads during completion callback */
-	ep->stopped = 1;
-
-	spin_unlock(&dev->lock);
-	/* complete routine from gadget driver */
-	if (req->req.complete)
-		req->req.complete(&ep->ep, &req->req);
-
-	spin_lock(&dev->lock);
-	ep->stopped = stopped;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-static void langwell_ep_fifo_flush(struct usb_ep *_ep);
-
-/* delete all endpoint requests, called with spinlock held */
-static void nuke(struct langwell_ep *ep, int status)
-{
-	/* called with spinlock held */
-	ep->stopped = 1;
-
-	/* endpoint fifo flush */
-	if (&ep->ep && ep->desc)
-		langwell_ep_fifo_flush(&ep->ep);
-
-	while (!list_empty(&ep->queue)) {
-		struct langwell_request	*req = NULL;
-		req = list_entry(ep->queue.next, struct langwell_request,
-				queue);
-		done(ep, req, status);
-	}
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* endpoint is no longer usable */
-static int langwell_ep_disable(struct usb_ep *_ep)
-{
-	struct langwell_ep	*ep;
-	unsigned long		flags;
-	struct langwell_udc	*dev;
-	int			ep_num;
-	u32			endptctrl;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !ep->desc)
-		return -EINVAL;
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	/* disable endpoint control register */
-	ep_num = ep->ep_num;
-	endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-	if (is_in(ep))
-		endptctrl &= ~EPCTRL_TXE;
-	else
-		endptctrl &= ~EPCTRL_RXE;
-	writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
-
-	/* nuke all pending requests (does flush) */
-	nuke(ep, -ESHUTDOWN);
-
-	ep->desc = NULL;
-	ep->ep.desc = NULL;
-	ep->stopped = 1;
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	dev_dbg(&dev->pdev->dev, "disabled %s\n", _ep->name);
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-
-	return 0;
-}
-
-
-/* allocate a request object to use with this endpoint */
-static struct usb_request *langwell_alloc_request(struct usb_ep *_ep,
-		gfp_t gfp_flags)
-{
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-	struct langwell_request	*req = NULL;
-
-	if (!_ep)
-		return NULL;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	req = kzalloc(sizeof(*req), gfp_flags);
-	if (!req)
-		return NULL;
-
-	req->req.dma = DMA_ADDR_INVALID;
-	INIT_LIST_HEAD(&req->queue);
-
-	dev_vdbg(&dev->pdev->dev, "alloc request for %s\n", _ep->name);
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return &req->req;
-}
-
-
-/* free a request object */
-static void langwell_free_request(struct usb_ep *_ep,
-		struct usb_request *_req)
-{
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-	struct langwell_request	*req = NULL;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !_req)
-		return;
-
-	req = container_of(_req, struct langwell_request, req);
-	WARN_ON(!list_empty(&req->queue));
-
-	if (_req)
-		kfree(req);
-
-	dev_vdbg(&dev->pdev->dev, "free request for %s\n", _ep->name);
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* queue dTD and PRIME endpoint */
-static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
-{
-	u32			bit_mask, usbcmd, endptstat, dtd_dma;
-	u8			dtd_status;
-	int			i;
-	struct langwell_dqh	*dqh;
-	struct langwell_udc	*dev;
-
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	i = ep->ep_num * 2 + is_in(ep);
-	dqh = &dev->ep_dqh[i];
-
-	if (ep->ep_num)
-		dev_vdbg(&dev->pdev->dev, "%s\n", ep->name);
-	else
-		/* ep0 */
-		dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep));
-
-	dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%p\n",
-			i, &(dev->ep_dqh[i]));
-
-	bit_mask = is_in(ep) ?
-		(1 << (ep->ep_num + 16)) : (1 << (ep->ep_num));
-
-	dev_vdbg(&dev->pdev->dev, "bit_mask = 0x%08x\n", bit_mask);
-
-	/* check if the pipe is empty */
-	if (!(list_empty(&ep->queue))) {
-		/* add dTD to the end of linked list */
-		struct langwell_request	*lastreq;
-		lastreq = list_entry(ep->queue.prev,
-				struct langwell_request, queue);
-
-		lastreq->tail->dtd_next =
-			cpu_to_le32(req->head->dtd_dma & DTD_NEXT_MASK);
-
-		/* read prime bit, if 1 goto out */
-		if (readl(&dev->op_regs->endptprime) & bit_mask)
-			goto out;
-
-		do {
-			/* set ATDTW bit in USBCMD */
-			usbcmd = readl(&dev->op_regs->usbcmd);
-			writel(usbcmd | CMD_ATDTW, &dev->op_regs->usbcmd);
-
-			/* read correct status bit */
-			endptstat = readl(&dev->op_regs->endptstat) & bit_mask;
-
-		} while (!(readl(&dev->op_regs->usbcmd) & CMD_ATDTW));
-
-		/* write ATDTW bit to 0 */
-		usbcmd = readl(&dev->op_regs->usbcmd);
-		writel(usbcmd & ~CMD_ATDTW, &dev->op_regs->usbcmd);
-
-		if (endptstat)
-			goto out;
-	}
-
-	/* write dQH next pointer and terminate bit to 0 */
-	dtd_dma = req->head->dtd_dma & DTD_NEXT_MASK;
-	dqh->dtd_next = cpu_to_le32(dtd_dma);
-
-	/* clear active and halt bit */
-	dtd_status = (u8) ~(DTD_STS_ACTIVE | DTD_STS_HALTED);
-	dqh->dtd_status &= dtd_status;
-	dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
-
-	/* ensure that updates to the dQH will occur before priming */
-	wmb();
-
-	/* write 1 to endptprime register to PRIME endpoint */
-	bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num);
-	dev_vdbg(&dev->pdev->dev, "endprime bit_mask = 0x%08x\n", bit_mask);
-	writel(bit_mask, &dev->op_regs->endptprime);
-out:
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* fill in the dTD structure to build a transfer descriptor */
-static struct langwell_dtd *build_dtd(struct langwell_request *req,
-		unsigned *length, dma_addr_t *dma, int *is_last)
-{
-	u32			 buf_ptr;
-	struct langwell_dtd	*dtd;
-	struct langwell_udc	*dev;
-	int			i;
-
-	dev = req->ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* the maximum transfer length, up to 16k bytes */
-	*length = min(req->req.length - req->req.actual,
-			(unsigned)DTD_MAX_TRANSFER_LENGTH);
-
-	/* create dTD dma_pool resource */
-	dtd = dma_pool_alloc(dev->dtd_pool, GFP_KERNEL, dma);
-	if (dtd == NULL)
-		return dtd;
-	dtd->dtd_dma = *dma;
-
-	/* initialize buffer page pointers */
-	buf_ptr = (u32)(req->req.dma + req->req.actual);
-	for (i = 0; i < 5; i++)
-		dtd->dtd_buf[i] = cpu_to_le32(buf_ptr + i * PAGE_SIZE);
-
-	req->req.actual += *length;
-
-	/* fill in total bytes with transfer size */
-	dtd->dtd_total = cpu_to_le16(*length);
-	dev_vdbg(&dev->pdev->dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
-
-	/* set is_last flag if req->req.zero is set or not */
-	if (req->req.zero) {
-		if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0)
-			*is_last = 1;
-		else
-			*is_last = 0;
-	} else if (req->req.length == req->req.actual) {
-		*is_last = 1;
-	} else
-		*is_last = 0;
-
-	if (*is_last == 0)
-		dev_vdbg(&dev->pdev->dev, "multi-dtd request!\n");
-
-	/* set interrupt on complete bit for the last dTD */
-	if (*is_last && !req->req.no_interrupt)
-		dtd->dtd_ioc = 1;
-
-	/* set multiplier override 0 for non-ISO and non-TX endpoint */
-	dtd->dtd_multo = 0;
-
-	/* set the active bit of status field to 1 */
-	dtd->dtd_status = DTD_STS_ACTIVE;
-	dev_vdbg(&dev->pdev->dev, "dtd->dtd_status = 0x%02x\n",
-			dtd->dtd_status);
-
-	dev_vdbg(&dev->pdev->dev, "length = %d, dma addr= 0x%08x\n",
-			*length, (int)*dma);
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return dtd;
-}
-
-
-/* generate dTD linked list for a request */
-static int req_to_dtd(struct langwell_request *req)
-{
-	unsigned		count;
-	int			is_last, is_first = 1;
-	struct langwell_dtd	*dtd, *last_dtd = NULL;
-	struct langwell_udc	*dev;
-	dma_addr_t		dma;
-
-	dev = req->ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-	do {
-		dtd = build_dtd(req, &count, &dma, &is_last);
-		if (dtd == NULL)
-			return -ENOMEM;
-
-		if (is_first) {
-			is_first = 0;
-			req->head = dtd;
-		} else {
-			last_dtd->dtd_next = cpu_to_le32(dma);
-			last_dtd->next_dtd_virt = dtd;
-		}
-		last_dtd = dtd;
-		req->dtd_count++;
-	} while (!is_last);
-
-	/* set terminate bit to 1 for the last dTD */
-	dtd->dtd_next = DTD_TERM;
-
-	req->tail = dtd;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* queue (submits) an I/O requests to an endpoint */
-static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
-		gfp_t gfp_flags)
-{
-	struct langwell_request	*req;
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-	unsigned long		flags;
-	int			is_iso = 0;
-	int			ret;
-
-	/* always require a cpu-view buffer */
-	req = container_of(_req, struct langwell_request, req);
-	ep = container_of(_ep, struct langwell_ep, ep);
-
-	if (!_req || !_req->complete || !_req->buf
-			|| !list_empty(&req->queue)) {
-		return -EINVAL;
-	}
-
-	if (unlikely(!_ep || !ep->desc))
-		return -EINVAL;
-
-	dev = ep->dev;
-	req->ep = ep;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (usb_endpoint_xfer_isoc(ep->desc)) {
-		if (req->req.length > ep->ep.maxpacket)
-			return -EMSGSIZE;
-		is_iso = 1;
-	}
-
-	if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN))
-		return -ESHUTDOWN;
-
-	/* set up dma mapping */
-	ret = usb_gadget_map_request(&dev->gadget, &req->req, is_in(ep));
-	if (ret)
-		return ret;
-
-	dev_dbg(&dev->pdev->dev,
-			"%s queue req %p, len %u, buf %p, dma 0x%08x\n",
-			_ep->name,
-			_req, _req->length, _req->buf, (int)_req->dma);
-
-	_req->status = -EINPROGRESS;
-	_req->actual = 0;
-	req->dtd_count = 0;
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	/* build and put dTDs to endpoint queue */
-	if (!req_to_dtd(req)) {
-		queue_dtd(ep, req);
-	} else {
-		spin_unlock_irqrestore(&dev->lock, flags);
-		return -ENOMEM;
-	}
-
-	/* update ep0 state */
-	if (ep->ep_num == 0)
-		dev->ep0_state = DATA_STATE_XMIT;
-
-	if (likely(req != NULL)) {
-		list_add_tail(&req->queue, &ep->queue);
-		dev_vdbg(&dev->pdev->dev, "list_add_tail()\n");
-	}
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* dequeue (cancels, unlinks) an I/O request from an endpoint */
-static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
-{
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-	struct langwell_request	*req;
-	unsigned long		flags;
-	int			stopped, ep_num, retval = 0;
-	u32			endptctrl;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !ep->desc || !_req)
-		return -EINVAL;
-
-	if (!dev->driver)
-		return -ESHUTDOWN;
-
-	spin_lock_irqsave(&dev->lock, flags);
-	stopped = ep->stopped;
-
-	/* quiesce dma while we patch the queue */
-	ep->stopped = 1;
-	ep_num = ep->ep_num;
-
-	/* disable endpoint control register */
-	endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-	if (is_in(ep))
-		endptctrl &= ~EPCTRL_TXE;
-	else
-		endptctrl &= ~EPCTRL_RXE;
-	writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
-
-	/* make sure it's still queued on this endpoint */
-	list_for_each_entry(req, &ep->queue, queue) {
-		if (&req->req == _req)
-			break;
-	}
-
-	if (&req->req != _req) {
-		retval = -EINVAL;
-		goto done;
-	}
-
-	/* queue head may be partially complete. */
-	if (ep->queue.next == &req->queue) {
-		dev_dbg(&dev->pdev->dev, "unlink (%s) dma\n", _ep->name);
-		_req->status = -ECONNRESET;
-		langwell_ep_fifo_flush(&ep->ep);
-
-		/* not the last request in endpoint queue */
-		if (likely(ep->queue.next == &req->queue)) {
-			struct langwell_dqh	*dqh;
-			struct langwell_request	*next_req;
-
-			dqh = ep->dqh;
-			next_req = list_entry(req->queue.next,
-					struct langwell_request, queue);
-
-			/* point the dQH to the first dTD of next request */
-			writel((u32) next_req->head, &dqh->dqh_current);
-		}
-	} else {
-		struct langwell_request	*prev_req;
-
-		prev_req = list_entry(req->queue.prev,
-				struct langwell_request, queue);
-		writel(readl(&req->tail->dtd_next),
-				&prev_req->tail->dtd_next);
-	}
-
-	done(ep, req, -ECONNRESET);
-
-done:
-	/* enable endpoint again */
-	endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-	if (is_in(ep))
-		endptctrl |= EPCTRL_TXE;
-	else
-		endptctrl |= EPCTRL_RXE;
-	writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
-
-	ep->stopped = stopped;
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return retval;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* endpoint set/clear halt */
-static void ep_set_halt(struct langwell_ep *ep, int value)
-{
-	u32			endptctrl = 0;
-	int			ep_num;
-	struct langwell_udc	*dev = ep->dev;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	ep_num = ep->ep_num;
-	endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
-
-	/* value: 1 - set halt, 0 - clear halt */
-	if (value) {
-		/* set the stall bit */
-		if (is_in(ep))
-			endptctrl |= EPCTRL_TXS;
-		else
-			endptctrl |= EPCTRL_RXS;
-	} else {
-		/* clear the stall bit and reset data toggle */
-		if (is_in(ep)) {
-			endptctrl &= ~EPCTRL_TXS;
-			endptctrl |= EPCTRL_TXR;
-		} else {
-			endptctrl &= ~EPCTRL_RXS;
-			endptctrl |= EPCTRL_RXR;
-		}
-	}
-
-	writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* set the endpoint halt feature */
-static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
-{
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-	unsigned long		flags;
-	int			retval = 0;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !ep->desc)
-		return -EINVAL;
-
-	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
-		return -ESHUTDOWN;
-
-	if (usb_endpoint_xfer_isoc(ep->desc))
-		return  -EOPNOTSUPP;
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	/*
-	 * attempt to halt IN ep will fail if any transfer requests
-	 * are still queue
-	 */
-	if (!list_empty(&ep->queue) && is_in(ep) && value) {
-		/* IN endpoint FIFO holds bytes */
-		dev_dbg(&dev->pdev->dev, "%s FIFO holds bytes\n", _ep->name);
-		retval = -EAGAIN;
-		goto done;
-	}
-
-	/* endpoint set/clear halt */
-	if (ep->ep_num) {
-		ep_set_halt(ep, value);
-	} else { /* endpoint 0 */
-		dev->ep0_state = WAIT_FOR_SETUP;
-		dev->ep0_dir = USB_DIR_OUT;
-	}
-done:
-	spin_unlock_irqrestore(&dev->lock, flags);
-	dev_dbg(&dev->pdev->dev, "%s %s halt\n",
-			_ep->name, value ? "set" : "clear");
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return retval;
-}
-
-
-/* set the halt feature and ignores clear requests */
-static int langwell_ep_set_wedge(struct usb_ep *_ep)
-{
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !ep->desc)
-		return -EINVAL;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return usb_ep_set_halt(_ep);
-}
-
-
-/* flush contents of a fifo */
-static void langwell_ep_fifo_flush(struct usb_ep *_ep)
-{
-	struct langwell_ep	*ep;
-	struct langwell_udc	*dev;
-	u32			flush_bit;
-	unsigned long		timeout;
-
-	ep = container_of(_ep, struct langwell_ep, ep);
-	dev = ep->dev;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (!_ep || !ep->desc) {
-		dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n");
-		dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-		return;
-	}
-
-	dev_vdbg(&dev->pdev->dev, "%s-%s fifo flush\n",
-			_ep->name, DIR_STRING(ep));
-
-	/* flush endpoint buffer */
-	if (ep->ep_num == 0)
-		flush_bit = (1 << 16) | 1;
-	else if (is_in(ep))
-		flush_bit = 1 << (ep->ep_num + 16);	/* TX */
-	else
-		flush_bit = 1 << ep->ep_num;		/* RX */
-
-	/* wait until flush complete */
-	timeout = jiffies + FLUSH_TIMEOUT;
-	do {
-		writel(flush_bit, &dev->op_regs->endptflush);
-		while (readl(&dev->op_regs->endptflush)) {
-			if (time_after(jiffies, timeout)) {
-				dev_err(&dev->pdev->dev, "ep flush timeout\n");
-				goto done;
-			}
-			cpu_relax();
-		}
-	} while (readl(&dev->op_regs->endptstat) & flush_bit);
-done:
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* endpoints operations structure */
-static const struct usb_ep_ops langwell_ep_ops = {
-
-	/* configure endpoint, making it usable */
-	.enable		= langwell_ep_enable,
-
-	/* endpoint is no longer usable */
-	.disable	= langwell_ep_disable,
-
-	/* allocate a request object to use with this endpoint */
-	.alloc_request	= langwell_alloc_request,
-
-	/* free a request object */
-	.free_request	= langwell_free_request,
-
-	/* queue (submits) an I/O requests to an endpoint */
-	.queue		= langwell_ep_queue,
-
-	/* dequeue (cancels, unlinks) an I/O request from an endpoint */
-	.dequeue	= langwell_ep_dequeue,
-
-	/* set the endpoint halt feature */
-	.set_halt	= langwell_ep_set_halt,
-
-	/* set the halt feature and ignores clear requests */
-	.set_wedge	= langwell_ep_set_wedge,
-
-	/* flush contents of a fifo */
-	.fifo_flush	= langwell_ep_fifo_flush,
-};
-
-
-/*-------------------------------------------------------------------------*/
-
-/* device controller usb_gadget_ops structure */
-
-/* returns the current frame number */
-static int langwell_get_frame(struct usb_gadget *_gadget)
-{
-	struct langwell_udc	*dev;
-	u16			retval;
-
-	if (!_gadget)
-		return -ENODEV;
-
-	dev = container_of(_gadget, struct langwell_udc, gadget);
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	retval = readl(&dev->op_regs->frindex) & FRINDEX_MASK;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return retval;
-}
-
-
-/* enter or exit PHY low power state */
-static void langwell_phy_low_power(struct langwell_udc *dev, bool flag)
-{
-	u32		devlc;
-	u8		devlc_byte2;
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	devlc = readl(&dev->op_regs->devlc);
-	dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
-
-	if (flag)
-		devlc |= LPM_PHCD;
-	else
-		devlc &= ~LPM_PHCD;
-
-	/* FIXME: workaround for Langwell A1/A2/A3 sighting */
-	devlc_byte2 = (devlc >> 16) & 0xff;
-	writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
-
-	devlc = readl(&dev->op_regs->devlc);
-	dev_vdbg(&dev->pdev->dev,
-			"%s PHY low power suspend, devlc = 0x%08x\n",
-			flag ? "enter" : "exit", devlc);
-}
-
-
-/* tries to wake up the host connected to this gadget */
-static int langwell_wakeup(struct usb_gadget *_gadget)
-{
-	struct langwell_udc	*dev;
-	u32			portsc1;
-	unsigned long		flags;
-
-	if (!_gadget)
-		return 0;
-
-	dev = container_of(_gadget, struct langwell_udc, gadget);
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* remote wakeup feature not enabled by host */
-	if (!dev->remote_wakeup) {
-		dev_info(&dev->pdev->dev, "remote wakeup is disabled\n");
-		return -ENOTSUPP;
-	}
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	portsc1 = readl(&dev->op_regs->portsc1);
-	if (!(portsc1 & PORTS_SUSP)) {
-		spin_unlock_irqrestore(&dev->lock, flags);
-		return 0;
-	}
-
-	/* LPM L1 to L0 or legacy remote wakeup */
-	if (dev->lpm && dev->lpm_state == LPM_L1)
-		dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n");
-	else
-		dev_info(&dev->pdev->dev, "device remote wakeup\n");
-
-	/* exit PHY low power suspend */
-	if (dev->pdev->device != 0x0829)
-		langwell_phy_low_power(dev, 0);
-
-	/* force port resume */
-	portsc1 |= PORTS_FPR;
-	writel(portsc1, &dev->op_regs->portsc1);
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* notify controller that VBUS is powered or not */
-static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active)
-{
-	struct langwell_udc	*dev;
-	unsigned long		flags;
-	u32			usbcmd;
-
-	if (!_gadget)
-		return -ENODEV;
-
-	dev = container_of(_gadget, struct langwell_udc, gadget);
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	spin_lock_irqsave(&dev->lock, flags);
-	dev_vdbg(&dev->pdev->dev, "VBUS status: %s\n",
-			is_active ? "on" : "off");
-
-	dev->vbus_active = (is_active != 0);
-	if (dev->driver && dev->softconnected && dev->vbus_active) {
-		usbcmd = readl(&dev->op_regs->usbcmd);
-		usbcmd |= CMD_RUNSTOP;
-		writel(usbcmd, &dev->op_regs->usbcmd);
-	} else {
-		usbcmd = readl(&dev->op_regs->usbcmd);
-		usbcmd &= ~CMD_RUNSTOP;
-		writel(usbcmd, &dev->op_regs->usbcmd);
-	}
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* constrain controller's VBUS power usage */
-static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
-{
-	struct langwell_udc	*dev;
-
-	if (!_gadget)
-		return -ENODEV;
-
-	dev = container_of(_gadget, struct langwell_udc, gadget);
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (dev->transceiver) {
-		dev_vdbg(&dev->pdev->dev, "usb_phy_set_power\n");
-		dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-		return usb_phy_set_power(dev->transceiver, mA);
-	}
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return -ENOTSUPP;
-}
-
-
-/* D+ pullup, software-controlled connect/disconnect to USB host */
-static int langwell_pullup(struct usb_gadget *_gadget, int is_on)
-{
-	struct langwell_udc	*dev;
-	u32			usbcmd;
-	unsigned long		flags;
-
-	if (!_gadget)
-		return -ENODEV;
-
-	dev = container_of(_gadget, struct langwell_udc, gadget);
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	spin_lock_irqsave(&dev->lock, flags);
-	dev->softconnected = (is_on != 0);
-
-	if (dev->driver && dev->softconnected && dev->vbus_active) {
-		usbcmd = readl(&dev->op_regs->usbcmd);
-		usbcmd |= CMD_RUNSTOP;
-		writel(usbcmd, &dev->op_regs->usbcmd);
-	} else {
-		usbcmd = readl(&dev->op_regs->usbcmd);
-		usbcmd &= ~CMD_RUNSTOP;
-		writel(usbcmd, &dev->op_regs->usbcmd);
-	}
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-static int langwell_start(struct usb_gadget *g,
-		struct usb_gadget_driver *driver);
-
-static int langwell_stop(struct usb_gadget *g,
-		struct usb_gadget_driver *driver);
-
-/* device controller usb_gadget_ops structure */
-static const struct usb_gadget_ops langwell_ops = {
-
-	/* returns the current frame number */
-	.get_frame	= langwell_get_frame,
-
-	/* tries to wake up the host connected to this gadget */
-	.wakeup		= langwell_wakeup,
-
-	/* set the device selfpowered feature, always selfpowered */
-	/* .set_selfpowered = langwell_set_selfpowered, */
-
-	/* notify controller that VBUS is powered or not */
-	.vbus_session	= langwell_vbus_session,
-
-	/* constrain controller's VBUS power usage */
-	.vbus_draw	= langwell_vbus_draw,
-
-	/* D+ pullup, software-controlled connect/disconnect to USB host */
-	.pullup		= langwell_pullup,
-
-	.udc_start	= langwell_start,
-	.udc_stop	= langwell_stop,
-};
-
-
-/*-------------------------------------------------------------------------*/
-
-/* device controller operations */
-
-/* reset device controller */
-static int langwell_udc_reset(struct langwell_udc *dev)
-{
-	u32		usbcmd, usbmode, devlc, endpointlistaddr;
-	u8		devlc_byte0, devlc_byte2;
-	unsigned long	timeout;
-
-	if (!dev)
-		return -EINVAL;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* set controller to stop state */
-	usbcmd = readl(&dev->op_regs->usbcmd);
-	usbcmd &= ~CMD_RUNSTOP;
-	writel(usbcmd, &dev->op_regs->usbcmd);
-
-	/* reset device controller */
-	usbcmd = readl(&dev->op_regs->usbcmd);
-	usbcmd |= CMD_RST;
-	writel(usbcmd, &dev->op_regs->usbcmd);
-
-	/* wait for reset to complete */
-	timeout = jiffies + RESET_TIMEOUT;
-	while (readl(&dev->op_regs->usbcmd) & CMD_RST) {
-		if (time_after(jiffies, timeout)) {
-			dev_err(&dev->pdev->dev, "device reset timeout\n");
-			return -ETIMEDOUT;
-		}
-		cpu_relax();
-	}
-
-	/* set controller to device mode */
-	usbmode = readl(&dev->op_regs->usbmode);
-	usbmode |= MODE_DEVICE;
-
-	/* turn setup lockout off, require setup tripwire in usbcmd */
-	usbmode |= MODE_SLOM;
-
-	writel(usbmode, &dev->op_regs->usbmode);
-	usbmode = readl(&dev->op_regs->usbmode);
-	dev_vdbg(&dev->pdev->dev, "usbmode=0x%08x\n", usbmode);
-
-	/* Write-Clear setup status */
-	writel(0, &dev->op_regs->usbsts);
-
-	/* if support USB LPM, ACK all LPM token */
-	if (dev->lpm) {
-		devlc = readl(&dev->op_regs->devlc);
-		dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
-		/* FIXME: workaround for Langwell A1/A2/A3 sighting */
-		devlc &= ~LPM_STL;	/* don't STALL LPM token */
-		devlc &= ~LPM_NYT_ACK;	/* ACK LPM token */
-		devlc_byte0 = devlc & 0xff;
-		devlc_byte2 = (devlc >> 16) & 0xff;
-		writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
-		writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
-		devlc = readl(&dev->op_regs->devlc);
-		dev_vdbg(&dev->pdev->dev,
-				"ACK LPM token, devlc = 0x%08x\n", devlc);
-	}
-
-	/* fill endpointlistaddr register */
-	endpointlistaddr = dev->ep_dqh_dma;
-	endpointlistaddr &= ENDPOINTLISTADDR_MASK;
-	writel(endpointlistaddr, &dev->op_regs->endpointlistaddr);
-
-	dev_vdbg(&dev->pdev->dev,
-		"dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
-		dev->ep_dqh, endpointlistaddr,
-		readl(&dev->op_regs->endpointlistaddr));
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* reinitialize device controller endpoints */
-static int eps_reinit(struct langwell_udc *dev)
-{
-	struct langwell_ep	*ep;
-	char			name[14];
-	int			i;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* initialize ep0 */
-	ep = &dev->ep[0];
-	ep->dev = dev;
-	strncpy(ep->name, "ep0", sizeof(ep->name));
-	ep->ep.name = ep->name;
-	ep->ep.ops = &langwell_ep_ops;
-	ep->stopped = 0;
-	ep->ep.maxpacket = EP0_MAX_PKT_SIZE;
-	ep->ep_num = 0;
-	ep->desc = &langwell_ep0_desc;
-	INIT_LIST_HEAD(&ep->queue);
-
-	ep->ep_type = USB_ENDPOINT_XFER_CONTROL;
-
-	/* initialize other endpoints */
-	for (i = 2; i < dev->ep_max; i++) {
-		ep = &dev->ep[i];
-		if (i % 2)
-			snprintf(name, sizeof(name), "ep%din", i / 2);
-		else
-			snprintf(name, sizeof(name), "ep%dout", i / 2);
-		ep->dev = dev;
-		strncpy(ep->name, name, sizeof(ep->name));
-		ep->ep.name = ep->name;
-
-		ep->ep.ops = &langwell_ep_ops;
-		ep->stopped = 0;
-		ep->ep.maxpacket = (unsigned short) ~0;
-		ep->ep_num = i / 2;
-
-		INIT_LIST_HEAD(&ep->queue);
-		list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
-	}
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* enable interrupt and set controller to run state */
-static void langwell_udc_start(struct langwell_udc *dev)
-{
-	u32	usbintr, usbcmd;
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* enable interrupts */
-	usbintr = INTR_ULPIE	/* ULPI */
-		| INTR_SLE	/* suspend */
-		/* | INTR_SRE	SOF received */
-		| INTR_URE	/* USB reset */
-		| INTR_AAE	/* async advance */
-		| INTR_SEE	/* system error */
-		| INTR_FRE	/* frame list rollover */
-		| INTR_PCE	/* port change detect */
-		| INTR_UEE	/* USB error interrupt */
-		| INTR_UE;	/* USB interrupt */
-	writel(usbintr, &dev->op_regs->usbintr);
-
-	/* clear stopped bit */
-	dev->stopped = 0;
-
-	/* set controller to run */
-	usbcmd = readl(&dev->op_regs->usbcmd);
-	usbcmd |= CMD_RUNSTOP;
-	writel(usbcmd, &dev->op_regs->usbcmd);
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* disable interrupt and set controller to stop state */
-static void langwell_udc_stop(struct langwell_udc *dev)
-{
-	u32	usbcmd;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* disable all interrupts */
-	writel(0, &dev->op_regs->usbintr);
-
-	/* set stopped bit */
-	dev->stopped = 1;
-
-	/* set controller to stop state */
-	usbcmd = readl(&dev->op_regs->usbcmd);
-	usbcmd &= ~CMD_RUNSTOP;
-	writel(usbcmd, &dev->op_regs->usbcmd);
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* stop all USB activities */
-static void stop_activity(struct langwell_udc *dev)
-{
-	struct langwell_ep	*ep;
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	nuke(&dev->ep[0], -ESHUTDOWN);
-
-	list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
-		nuke(ep, -ESHUTDOWN);
-	}
-
-	/* report disconnect; the driver is already quiesced */
-	if (dev->driver) {
-		spin_unlock(&dev->lock);
-		dev->driver->disconnect(&dev->gadget);
-		spin_lock(&dev->lock);
-	}
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* device "function" sysfs attribute file */
-static ssize_t show_function(struct device *_dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct langwell_udc	*dev = dev_get_drvdata(_dev);
-
-	if (!dev->driver || !dev->driver->function
-			|| strlen(dev->driver->function) > PAGE_SIZE)
-		return 0;
-
-	return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function);
-}
-static DEVICE_ATTR(function, S_IRUGO, show_function, NULL);
-
-
-static inline enum usb_device_speed lpm_device_speed(u32 reg)
-{
-	switch (LPM_PSPD(reg)) {
-	case LPM_SPEED_HIGH:
-		return USB_SPEED_HIGH;
-	case LPM_SPEED_FULL:
-		return USB_SPEED_FULL;
-	case LPM_SPEED_LOW:
-		return USB_SPEED_LOW;
-	default:
-		return USB_SPEED_UNKNOWN;
-	}
-}
-
-/* device "langwell_udc" sysfs attribute file */
-static ssize_t show_langwell_udc(struct device *_dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct langwell_udc	*dev = dev_get_drvdata(_dev);
-	struct langwell_request *req;
-	struct langwell_ep	*ep = NULL;
-	char			*next;
-	unsigned		size;
-	unsigned		t;
-	unsigned		i;
-	unsigned long		flags;
-	u32			tmp_reg;
-
-	next = buf;
-	size = PAGE_SIZE;
-	spin_lock_irqsave(&dev->lock, flags);
-
-	/* driver basic information */
-	t = scnprintf(next, size,
-			DRIVER_DESC "\n"
-			"%s version: %s\n"
-			"Gadget driver: %s\n\n",
-			driver_name, DRIVER_VERSION,
-			dev->driver ? dev->driver->driver.name : "(none)");
-	size -= t;
-	next += t;
-
-	/* device registers */
-	tmp_reg = readl(&dev->op_regs->usbcmd);
-	t = scnprintf(next, size,
-			"USBCMD reg:\n"
-			"SetupTW: %d\n"
-			"Run/Stop: %s\n\n",
-			(tmp_reg & CMD_SUTW) ? 1 : 0,
-			(tmp_reg & CMD_RUNSTOP) ? "Run" : "Stop");
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->usbsts);
-	t = scnprintf(next, size,
-			"USB Status Reg:\n"
-			"Device Suspend: %d\n"
-			"Reset Received: %d\n"
-			"System Error: %s\n"
-			"USB Error Interrupt: %s\n\n",
-			(tmp_reg & STS_SLI) ? 1 : 0,
-			(tmp_reg & STS_URI) ? 1 : 0,
-			(tmp_reg & STS_SEI) ? "Error" : "No error",
-			(tmp_reg & STS_UEI) ? "Error detected" : "No error");
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->usbintr);
-	t = scnprintf(next, size,
-			"USB Intrrupt Enable Reg:\n"
-			"Sleep Enable: %d\n"
-			"SOF Received Enable: %d\n"
-			"Reset Enable: %d\n"
-			"System Error Enable: %d\n"
-			"Port Change Dectected Enable: %d\n"
-			"USB Error Intr Enable: %d\n"
-			"USB Intr Enable: %d\n\n",
-			(tmp_reg & INTR_SLE) ? 1 : 0,
-			(tmp_reg & INTR_SRE) ? 1 : 0,
-			(tmp_reg & INTR_URE) ? 1 : 0,
-			(tmp_reg & INTR_SEE) ? 1 : 0,
-			(tmp_reg & INTR_PCE) ? 1 : 0,
-			(tmp_reg & INTR_UEE) ? 1 : 0,
-			(tmp_reg & INTR_UE) ? 1 : 0);
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->frindex);
-	t = scnprintf(next, size,
-			"USB Frame Index Reg:\n"
-			"Frame Number is 0x%08x\n\n",
-			(tmp_reg & FRINDEX_MASK));
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->deviceaddr);
-	t = scnprintf(next, size,
-			"USB Device Address Reg:\n"
-			"Device Addr is 0x%x\n\n",
-			USBADR(tmp_reg));
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->endpointlistaddr);
-	t = scnprintf(next, size,
-			"USB Endpoint List Address Reg:\n"
-			"Endpoint List Pointer is 0x%x\n\n",
-			EPBASE(tmp_reg));
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->portsc1);
-	t = scnprintf(next, size,
-		"USB Port Status & Control Reg:\n"
-		"Port Reset: %s\n"
-		"Port Suspend Mode: %s\n"
-		"Over-current Change: %s\n"
-		"Port Enable/Disable Change: %s\n"
-		"Port Enabled/Disabled: %s\n"
-		"Current Connect Status: %s\n"
-		"LPM Suspend Status: %s\n\n",
-		(tmp_reg & PORTS_PR) ? "Reset" : "Not Reset",
-		(tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend",
-		(tmp_reg & PORTS_OCC) ? "Detected" : "No",
-		(tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed",
-		(tmp_reg & PORTS_PE) ? "Enable" : "Not Correct",
-		(tmp_reg & PORTS_CCS) ?  "Attached" : "Not Attached",
-		(tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0");
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->devlc);
-	t = scnprintf(next, size,
-		"Device LPM Control Reg:\n"
-		"Parallel Transceiver : %d\n"
-		"Serial Transceiver : %d\n"
-		"Port Speed: %s\n"
-		"Port Force Full Speed Connenct: %s\n"
-		"PHY Low Power Suspend Clock: %s\n"
-		"BmAttributes: %d\n\n",
-		LPM_PTS(tmp_reg),
-		(tmp_reg & LPM_STS) ? 1 : 0,
-		usb_speed_string(lpm_device_speed(tmp_reg)),
-		(tmp_reg & LPM_PFSC) ? "Force Full Speed" : "Not Force",
-		(tmp_reg & LPM_PHCD) ? "Disabled" : "Enabled",
-		LPM_BA(tmp_reg));
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->usbmode);
-	t = scnprintf(next, size,
-			"USB Mode Reg:\n"
-			"Controller Mode is : %s\n\n", ({
-				char *s;
-				switch (MODE_CM(tmp_reg)) {
-				case MODE_IDLE:
-					s = "Idle"; break;
-				case MODE_DEVICE:
-					s = "Device Controller"; break;
-				case MODE_HOST:
-					s = "Host Controller"; break;
-				default:
-					s = "None"; break;
-				}
-				s;
-			}));
-	size -= t;
-	next += t;
-
-	tmp_reg = readl(&dev->op_regs->endptsetupstat);
-	t = scnprintf(next, size,
-			"Endpoint Setup Status Reg:\n"
-			"SETUP on ep 0x%04x\n\n",
-			tmp_reg & SETUPSTAT_MASK);
-	size -= t;
-	next += t;
-
-	for (i = 0; i < dev->ep_max / 2; i++) {
-		tmp_reg = readl(&dev->op_regs->endptctrl[i]);
-		t = scnprintf(next, size, "EP Ctrl Reg [%d]: 0x%08x\n",
-				i, tmp_reg);
-		size -= t;
-		next += t;
-	}
-	tmp_reg = readl(&dev->op_regs->endptprime);
-	t = scnprintf(next, size, "EP Prime Reg: 0x%08x\n\n", tmp_reg);
-	size -= t;
-	next += t;
-
-	/* langwell_udc, langwell_ep, langwell_request structure information */
-	ep = &dev->ep[0];
-	t = scnprintf(next, size, "%s MaxPacketSize: 0x%x, ep_num: %d\n",
-			ep->ep.name, ep->ep.maxpacket, ep->ep_num);
-	size -= t;
-	next += t;
-
-	if (list_empty(&ep->queue)) {
-		t = scnprintf(next, size, "its req queue is empty\n\n");
-		size -= t;
-		next += t;
-	} else {
-		list_for_each_entry(req, &ep->queue, queue) {
-			t = scnprintf(next, size,
-				"req %p actual 0x%x length 0x%x  buf %p\n",
-				&req->req, req->req.actual,
-				req->req.length, req->req.buf);
-			size -= t;
-			next += t;
-		}
-	}
-	/* other gadget->eplist ep */
-	list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
-		if (ep->desc) {
-			t = scnprintf(next, size,
-					"\n%s MaxPacketSize: 0x%x, "
-					"ep_num: %d\n",
-					ep->ep.name, ep->ep.maxpacket,
-					ep->ep_num);
-			size -= t;
-			next += t;
-
-			if (list_empty(&ep->queue)) {
-				t = scnprintf(next, size,
-						"its req queue is empty\n\n");
-				size -= t;
-				next += t;
-			} else {
-				list_for_each_entry(req, &ep->queue, queue) {
-					t = scnprintf(next, size,
-						"req %p actual 0x%x length "
-						"0x%x  buf %p\n",
-						&req->req, req->req.actual,
-						req->req.length, req->req.buf);
-					size -= t;
-					next += t;
-				}
-			}
-		}
-	}
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-	return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
-
-
-/* device "remote_wakeup" sysfs attribute file */
-static ssize_t store_remote_wakeup(struct device *_dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct langwell_udc	*dev = dev_get_drvdata(_dev);
-	unsigned long		flags;
-	ssize_t			rc = count;
-
-	if (count > 2)
-		return -EINVAL;
-
-	if (count > 0 && buf[count-1] == '\n')
-		((char *) buf)[count-1] = 0;
-
-	if (buf[0] != '1')
-		return -EINVAL;
-
-	/* force remote wakeup enabled in case gadget driver doesn't support */
-	spin_lock_irqsave(&dev->lock, flags);
-	dev->remote_wakeup = 1;
-	dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP);
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	langwell_wakeup(&dev->gadget);
-
-	return rc;
-}
-static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup);
-
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * when a driver is successfully registered, it will receive
- * control requests including set_configuration(), which enables
- * non-control requests.  then usb traffic follows until a
- * disconnect is reported.  then a host may connect again, or
- * the driver might get unbound.
- */
-
-static int langwell_start(struct usb_gadget *g,
-		struct usb_gadget_driver *driver)
-{
-	struct langwell_udc	*dev = gadget_to_langwell(g);
-	unsigned long		flags;
-	int			retval;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	/* hook up the driver ... */
-	driver->driver.bus = NULL;
-	dev->driver = driver;
-	dev->gadget.dev.driver = &driver->driver;
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	retval = device_create_file(&dev->pdev->dev, &dev_attr_function);
-	if (retval)
-		goto err;
-
-	dev->usb_state = USB_STATE_ATTACHED;
-	dev->ep0_state = WAIT_FOR_SETUP;
-	dev->ep0_dir = USB_DIR_OUT;
-
-	/* enable interrupt and set controller to run state */
-	if (dev->got_irq)
-		langwell_udc_start(dev);
-
-	dev_vdbg(&dev->pdev->dev,
-			"After langwell_udc_start(), print all registers:\n");
-	print_all_registers(dev);
-
-	dev_info(&dev->pdev->dev, "register driver: %s\n",
-			driver->driver.name);
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-
-	return 0;
-
-err:
-	dev->gadget.dev.driver = NULL;
-	dev->driver = NULL;
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-
-	return retval;
-}
-
-/* unregister gadget driver */
-static int langwell_stop(struct usb_gadget *g,
-		struct usb_gadget_driver *driver)
-{
-	struct langwell_udc	*dev = gadget_to_langwell(g);
-	unsigned long		flags;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* exit PHY low power suspend */
-	if (dev->pdev->device != 0x0829)
-		langwell_phy_low_power(dev, 0);
-
-	/* unbind OTG transceiver */
-	if (dev->transceiver)
-		(void)otg_set_peripheral(dev->transceiver->otg, 0);
-
-	/* disable interrupt and set controller to stop state */
-	langwell_udc_stop(dev);
-
-	dev->usb_state = USB_STATE_ATTACHED;
-	dev->ep0_state = WAIT_FOR_SETUP;
-	dev->ep0_dir = USB_DIR_OUT;
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	/* stop all usb activities */
-	dev->gadget.speed = USB_SPEED_UNKNOWN;
-	dev->gadget.dev.driver = NULL;
-	dev->driver = NULL;
-	stop_activity(dev);
-	spin_unlock_irqrestore(&dev->lock, flags);
-
-	device_remove_file(&dev->pdev->dev, &dev_attr_function);
-
-	dev_info(&dev->pdev->dev, "unregistered driver '%s'\n",
-			driver->driver.name);
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * setup tripwire is used as a semaphore to ensure that the setup data
- * payload is extracted from a dQH without being corrupted
- */
-static void setup_tripwire(struct langwell_udc *dev)
-{
-	u32			usbcmd,
-				endptsetupstat;
-	unsigned long		timeout;
-	struct langwell_dqh	*dqh;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* ep0 OUT dQH */
-	dqh = &dev->ep_dqh[EP_DIR_OUT];
-
-	/* Write-Clear endptsetupstat */
-	endptsetupstat = readl(&dev->op_regs->endptsetupstat);
-	writel(endptsetupstat, &dev->op_regs->endptsetupstat);
-
-	/* wait until endptsetupstat is cleared */
-	timeout = jiffies + SETUPSTAT_TIMEOUT;
-	while (readl(&dev->op_regs->endptsetupstat)) {
-		if (time_after(jiffies, timeout)) {
-			dev_err(&dev->pdev->dev, "setup_tripwire timeout\n");
-			break;
-		}
-		cpu_relax();
-	}
-
-	/* while a hazard exists when setup packet arrives */
-	do {
-		/* set setup tripwire bit */
-		usbcmd = readl(&dev->op_regs->usbcmd);
-		writel(usbcmd | CMD_SUTW, &dev->op_regs->usbcmd);
-
-		/* copy the setup packet to local buffer */
-		memcpy(&dev->local_setup_buff, &dqh->dqh_setup, 8);
-	} while (!(readl(&dev->op_regs->usbcmd) & CMD_SUTW));
-
-	/* Write-Clear setup tripwire bit */
-	usbcmd = readl(&dev->op_regs->usbcmd);
-	writel(usbcmd & ~CMD_SUTW, &dev->op_regs->usbcmd);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* protocol ep0 stall, will automatically be cleared on new transaction */
-static void ep0_stall(struct langwell_udc *dev)
-{
-	u32	endptctrl;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* set TX and RX to stall */
-	endptctrl = readl(&dev->op_regs->endptctrl[0]);
-	endptctrl |= EPCTRL_TXS | EPCTRL_RXS;
-	writel(endptctrl, &dev->op_regs->endptctrl[0]);
-
-	/* update ep0 state */
-	dev->ep0_state = WAIT_FOR_SETUP;
-	dev->ep0_dir = USB_DIR_OUT;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* PRIME a status phase for ep0 */
-static int prime_status_phase(struct langwell_udc *dev, int dir)
-{
-	struct langwell_request	*req;
-	struct langwell_ep	*ep;
-	int			status = 0;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (dir == EP_DIR_IN)
-		dev->ep0_dir = USB_DIR_IN;
-	else
-		dev->ep0_dir = USB_DIR_OUT;
-
-	ep = &dev->ep[0];
-	dev->ep0_state = WAIT_FOR_OUT_STATUS;
-
-	req = dev->status_req;
-
-	req->ep = ep;
-	req->req.length = 0;
-	req->req.status = -EINPROGRESS;
-	req->req.actual = 0;
-	req->req.complete = NULL;
-	req->dtd_count = 0;
-
-	if (!req_to_dtd(req))
-		status = queue_dtd(ep, req);
-	else
-		return -ENOMEM;
-
-	if (status)
-		dev_err(&dev->pdev->dev, "can't queue ep0 status request\n");
-
-	list_add_tail(&req->queue, &ep->queue);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return status;
-}
-
-
-/* SET_ADDRESS request routine */
-static void set_address(struct langwell_udc *dev, u16 value,
-		u16 index, u16 length)
-{
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* save the new address to device struct */
-	dev->dev_addr = (u8) value;
-	dev_vdbg(&dev->pdev->dev, "dev->dev_addr = %d\n", dev->dev_addr);
-
-	/* update usb state */
-	dev->usb_state = USB_STATE_ADDRESS;
-
-	/* STATUS phase */
-	if (prime_status_phase(dev, EP_DIR_IN))
-		ep0_stall(dev);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* return endpoint by windex */
-static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev,
-		u16 wIndex)
-{
-	struct langwell_ep		*ep;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
-		return &dev->ep[0];
-
-	list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
-		u8	bEndpointAddress;
-		if (!ep->desc)
-			continue;
-
-		bEndpointAddress = ep->desc->bEndpointAddress;
-		if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
-			continue;
-
-		if ((wIndex & USB_ENDPOINT_NUMBER_MASK)
-			== (bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))
-			return ep;
-	}
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return NULL;
-}
-
-
-/* return whether endpoint is stalled, 0: not stalled; 1: stalled */
-static int ep_is_stall(struct langwell_ep *ep)
-{
-	struct langwell_udc	*dev = ep->dev;
-	u32			endptctrl;
-	int			retval;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	endptctrl = readl(&dev->op_regs->endptctrl[ep->ep_num]);
-	if (is_in(ep))
-		retval = endptctrl & EPCTRL_TXS ? 1 : 0;
-	else
-		retval = endptctrl & EPCTRL_RXS ? 1 : 0;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return retval;
-}
-
-
-/* GET_STATUS request routine */
-static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
-		u16 index, u16 length)
-{
-	struct langwell_request	*req;
-	struct langwell_ep	*ep;
-	u16	status_data = 0;	/* 16 bits cpu view status data */
-	int	status = 0;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	ep = &dev->ep[0];
-
-	if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
-		/* get device status */
-		status_data = dev->dev_status;
-	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
-		/* get interface status */
-		status_data = 0;
-	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
-		/* get endpoint status */
-		struct langwell_ep	*epn;
-		epn = get_ep_by_windex(dev, index);
-		/* stall if endpoint doesn't exist */
-		if (!epn)
-			goto stall;
-
-		status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT;
-	}
-
-	dev_dbg(&dev->pdev->dev, "get status data: 0x%04x\n", status_data);
-
-	dev->ep0_dir = USB_DIR_IN;
-
-	/* borrow the per device status_req */
-	req = dev->status_req;
-
-	/* fill in the reqest structure */
-	*((u16 *) req->req.buf) = cpu_to_le16(status_data);
-	req->ep = ep;
-	req->req.length = 2;
-	req->req.status = -EINPROGRESS;
-	req->req.actual = 0;
-	req->req.complete = NULL;
-	req->dtd_count = 0;
-
-	/* prime the data phase */
-	if (!req_to_dtd(req))
-		status = queue_dtd(ep, req);
-	else			/* no mem */
-		goto stall;
-
-	if (status) {
-		dev_err(&dev->pdev->dev,
-				"response error on GET_STATUS request\n");
-		goto stall;
-	}
-
-	list_add_tail(&req->queue, &ep->queue);
-	dev->ep0_state = DATA_STATE_XMIT;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return;
-stall:
-	ep0_stall(dev);
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* setup packet interrupt handler */
-static void handle_setup_packet(struct langwell_udc *dev,
-		struct usb_ctrlrequest *setup)
-{
-	u16	wValue = le16_to_cpu(setup->wValue);
-	u16	wIndex = le16_to_cpu(setup->wIndex);
-	u16	wLength = le16_to_cpu(setup->wLength);
-	u32	portsc1;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* ep0 fifo flush */
-	nuke(&dev->ep[0], -ESHUTDOWN);
-
-	dev_dbg(&dev->pdev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
-			setup->bRequestType, setup->bRequest,
-			wValue, wIndex, wLength);
-
-	/* RNDIS gadget delegate */
-	if ((setup->bRequestType == 0x21) && (setup->bRequest == 0x00)) {
-		/* USB_CDC_SEND_ENCAPSULATED_COMMAND */
-		goto delegate;
-	}
-
-	/* USB_CDC_GET_ENCAPSULATED_RESPONSE */
-	if ((setup->bRequestType == 0xa1) && (setup->bRequest == 0x01)) {
-		/* USB_CDC_GET_ENCAPSULATED_RESPONSE */
-		goto delegate;
-	}
-
-	/* We process some stardard setup requests here */
-	switch (setup->bRequest) {
-	case USB_REQ_GET_STATUS:
-		dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_GET_STATUS\n");
-		/* get status, DATA and STATUS phase */
-		if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
-					!= (USB_DIR_IN | USB_TYPE_STANDARD))
-			break;
-		get_status(dev, setup->bRequestType, wValue, wIndex, wLength);
-		goto end;
-
-	case USB_REQ_SET_ADDRESS:
-		dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_SET_ADDRESS\n");
-		/* STATUS phase */
-		if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
-						| USB_RECIP_DEVICE))
-			break;
-		set_address(dev, wValue, wIndex, wLength);
-		goto end;
-
-	case USB_REQ_CLEAR_FEATURE:
-	case USB_REQ_SET_FEATURE:
-		/* STATUS phase */
-	{
-		int rc = -EOPNOTSUPP;
-		if (setup->bRequest == USB_REQ_SET_FEATURE)
-			dev_dbg(&dev->pdev->dev,
-					"SETUP: USB_REQ_SET_FEATURE\n");
-		else if (setup->bRequest == USB_REQ_CLEAR_FEATURE)
-			dev_dbg(&dev->pdev->dev,
-					"SETUP: USB_REQ_CLEAR_FEATURE\n");
-
-		if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
-				== (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
-			struct langwell_ep	*epn;
-			epn = get_ep_by_windex(dev, wIndex);
-			/* stall if endpoint doesn't exist */
-			if (!epn) {
-				ep0_stall(dev);
-				goto end;
-			}
-
-			if (wValue != 0 || wLength != 0
-					|| epn->ep_num > dev->ep_max)
-				break;
-
-			spin_unlock(&dev->lock);
-			rc = langwell_ep_set_halt(&epn->ep,
-				(setup->bRequest == USB_REQ_SET_FEATURE)
-				? 1 : 0);
-			spin_lock(&dev->lock);
-
-		} else if ((setup->bRequestType & (USB_RECIP_MASK
-				| USB_TYPE_MASK)) == (USB_RECIP_DEVICE
-				| USB_TYPE_STANDARD)) {
-			rc = 0;
-			switch (wValue) {
-			case USB_DEVICE_REMOTE_WAKEUP:
-				if (setup->bRequest == USB_REQ_SET_FEATURE) {
-					dev->remote_wakeup = 1;
-					dev->dev_status |= (1 << wValue);
-				} else {
-					dev->remote_wakeup = 0;
-					dev->dev_status &= ~(1 << wValue);
-				}
-				break;
-			case USB_DEVICE_TEST_MODE:
-				dev_dbg(&dev->pdev->dev, "SETUP: TEST MODE\n");
-				if ((wIndex & 0xff) ||
-					(dev->gadget.speed != USB_SPEED_HIGH))
-					ep0_stall(dev);
-
-				switch (wIndex >> 8) {
-				case TEST_J:
-				case TEST_K:
-				case TEST_SE0_NAK:
-				case TEST_PACKET:
-				case TEST_FORCE_EN:
-					if (prime_status_phase(dev, EP_DIR_IN))
-						ep0_stall(dev);
-					portsc1 = readl(&dev->op_regs->portsc1);
-					portsc1 |= (wIndex & 0xf00) << 8;
-					writel(portsc1, &dev->op_regs->portsc1);
-					goto end;
-				default:
-					rc = -EOPNOTSUPP;
-				}
-				break;
-			default:
-				rc = -EOPNOTSUPP;
-				break;
-			}
-
-			if (!gadget_is_otg(&dev->gadget))
-				break;
-			else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE)
-				dev->gadget.b_hnp_enable = 1;
-			else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT)
-				dev->gadget.a_hnp_support = 1;
-			else if (setup->bRequest ==
-					USB_DEVICE_A_ALT_HNP_SUPPORT)
-				dev->gadget.a_alt_hnp_support = 1;
-			else
-				break;
-		} else
-			break;
-
-		if (rc == 0) {
-			if (prime_status_phase(dev, EP_DIR_IN))
-				ep0_stall(dev);
-		}
-		goto end;
-	}
-
-	case USB_REQ_GET_DESCRIPTOR:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_GET_DESCRIPTOR\n");
-		goto delegate;
-
-	case USB_REQ_SET_DESCRIPTOR:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
-		goto delegate;
-
-	case USB_REQ_GET_CONFIGURATION:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_GET_CONFIGURATION\n");
-		goto delegate;
-
-	case USB_REQ_SET_CONFIGURATION:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_SET_CONFIGURATION\n");
-		goto delegate;
-
-	case USB_REQ_GET_INTERFACE:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_GET_INTERFACE\n");
-		goto delegate;
-
-	case USB_REQ_SET_INTERFACE:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_SET_INTERFACE\n");
-		goto delegate;
-
-	case USB_REQ_SYNCH_FRAME:
-		dev_dbg(&dev->pdev->dev,
-				"SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
-		goto delegate;
-
-	default:
-		/* delegate USB standard requests to the gadget driver */
-		goto delegate;
-delegate:
-		/* USB requests handled by gadget */
-		if (wLength) {
-			/* DATA phase from gadget, STATUS phase from udc */
-			dev->ep0_dir = (setup->bRequestType & USB_DIR_IN)
-					?  USB_DIR_IN : USB_DIR_OUT;
-			dev_vdbg(&dev->pdev->dev,
-					"dev->ep0_dir = 0x%x, wLength = %d\n",
-					dev->ep0_dir, wLength);
-			spin_unlock(&dev->lock);
-			if (dev->driver->setup(&dev->gadget,
-					&dev->local_setup_buff) < 0)
-				ep0_stall(dev);
-			spin_lock(&dev->lock);
-			dev->ep0_state = (setup->bRequestType & USB_DIR_IN)
-					?  DATA_STATE_XMIT : DATA_STATE_RECV;
-		} else {
-			/* no DATA phase, IN STATUS phase from gadget */
-			dev->ep0_dir = USB_DIR_IN;
-			dev_vdbg(&dev->pdev->dev,
-					"dev->ep0_dir = 0x%x, wLength = %d\n",
-					dev->ep0_dir, wLength);
-			spin_unlock(&dev->lock);
-			if (dev->driver->setup(&dev->gadget,
-					&dev->local_setup_buff) < 0)
-				ep0_stall(dev);
-			spin_lock(&dev->lock);
-			dev->ep0_state = WAIT_FOR_OUT_STATUS;
-		}
-		break;
-	}
-end:
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* transfer completion, process endpoint request and free the completed dTDs
- * for this request
- */
-static int process_ep_req(struct langwell_udc *dev, int index,
-		struct langwell_request *curr_req)
-{
-	struct langwell_dtd	*curr_dtd;
-	struct langwell_dqh	*curr_dqh;
-	int			td_complete, actual, remaining_length;
-	int			i, dir;
-	u8			dtd_status = 0;
-	int			retval = 0;
-
-	curr_dqh = &dev->ep_dqh[index];
-	dir = index % 2;
-
-	curr_dtd = curr_req->head;
-	td_complete = 0;
-	actual = curr_req->req.length;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	for (i = 0; i < curr_req->dtd_count; i++) {
-
-		/* command execution states by dTD */
-		dtd_status = curr_dtd->dtd_status;
-
-		barrier();
-		remaining_length = le16_to_cpu(curr_dtd->dtd_total);
-		actual -= remaining_length;
-
-		if (!dtd_status) {
-			/* transfers completed successfully */
-			if (!remaining_length) {
-				td_complete++;
-				dev_vdbg(&dev->pdev->dev,
-					"dTD transmitted successfully\n");
-			} else {
-				if (dir) {
-					dev_vdbg(&dev->pdev->dev,
-						"TX dTD remains data\n");
-					retval = -EPROTO;
-					break;
-
-				} else {
-					td_complete++;
-					break;
-				}
-			}
-		} else {
-			/* transfers completed with errors */
-			if (dtd_status & DTD_STS_ACTIVE) {
-				dev_dbg(&dev->pdev->dev,
-					"dTD status ACTIVE dQH[%d]\n", index);
-				retval = 1;
-				return retval;
-			} else if (dtd_status & DTD_STS_HALTED) {
-				dev_err(&dev->pdev->dev,
-					"dTD error %08x dQH[%d]\n",
-					dtd_status, index);
-				/* clear the errors and halt condition */
-				curr_dqh->dtd_status = 0;
-				retval = -EPIPE;
-				break;
-			} else if (dtd_status & DTD_STS_DBE) {
-				dev_dbg(&dev->pdev->dev,
-					"data buffer (overflow) error\n");
-				retval = -EPROTO;
-				break;
-			} else if (dtd_status & DTD_STS_TRE) {
-				dev_dbg(&dev->pdev->dev,
-					"transaction(ISO) error\n");
-				retval = -EILSEQ;
-				break;
-			} else
-				dev_err(&dev->pdev->dev,
-					"unknown error (0x%x)!\n",
-					dtd_status);
-		}
-
-		if (i != curr_req->dtd_count - 1)
-			curr_dtd = (struct langwell_dtd *)
-				curr_dtd->next_dtd_virt;
-	}
-
-	if (retval)
-		return retval;
-
-	curr_req->req.actual = actual;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* complete DATA or STATUS phase of ep0 prime status phase if needed */
-static void ep0_req_complete(struct langwell_udc *dev,
-		struct langwell_ep *ep0, struct langwell_request *req)
-{
-	u32	new_addr;
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (dev->usb_state == USB_STATE_ADDRESS) {
-		/* set the new address */
-		new_addr = (u32)dev->dev_addr;
-		writel(new_addr << USBADR_SHIFT, &dev->op_regs->deviceaddr);
-
-		new_addr = USBADR(readl(&dev->op_regs->deviceaddr));
-		dev_vdbg(&dev->pdev->dev, "new_addr = %d\n", new_addr);
-	}
-
-	done(ep0, req, 0);
-
-	switch (dev->ep0_state) {
-	case DATA_STATE_XMIT:
-		/* receive status phase */
-		if (prime_status_phase(dev, EP_DIR_OUT))
-			ep0_stall(dev);
-		break;
-	case DATA_STATE_RECV:
-		/* send status phase */
-		if (prime_status_phase(dev, EP_DIR_IN))
-			ep0_stall(dev);
-		break;
-	case WAIT_FOR_OUT_STATUS:
-		dev->ep0_state = WAIT_FOR_SETUP;
-		break;
-	case WAIT_FOR_SETUP:
-		dev_err(&dev->pdev->dev, "unexpect ep0 packets\n");
-		break;
-	default:
-		ep0_stall(dev);
-		break;
-	}
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* USB transfer completion interrupt */
-static void handle_trans_complete(struct langwell_udc *dev)
-{
-	u32			complete_bits;
-	int			i, ep_num, dir, bit_mask, status;
-	struct langwell_ep	*epn;
-	struct langwell_request	*curr_req, *temp_req;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	complete_bits = readl(&dev->op_regs->endptcomplete);
-	dev_vdbg(&dev->pdev->dev, "endptcomplete register: 0x%08x\n",
-			complete_bits);
-
-	/* Write-Clear the bits in endptcomplete register */
-	writel(complete_bits, &dev->op_regs->endptcomplete);
-
-	if (!complete_bits) {
-		dev_dbg(&dev->pdev->dev, "complete_bits = 0\n");
-		goto done;
-	}
-
-	for (i = 0; i < dev->ep_max; i++) {
-		ep_num = i / 2;
-		dir = i % 2;
-
-		bit_mask = 1 << (ep_num + 16 * dir);
-
-		if (!(complete_bits & bit_mask))
-			continue;
-
-		/* ep0 */
-		if (i == 1)
-			epn = &dev->ep[0];
-		else
-			epn = &dev->ep[i];
-
-		if (epn->name == NULL) {
-			dev_warn(&dev->pdev->dev, "invalid endpoint\n");
-			continue;
-		}
-
-		if (i < 2)
-			/* ep0 in and out */
-			dev_dbg(&dev->pdev->dev, "%s-%s transfer completed\n",
-					epn->name,
-					is_in(epn) ? "in" : "out");
-		else
-			dev_dbg(&dev->pdev->dev, "%s transfer completed\n",
-					epn->name);
-
-		/* process the req queue until an uncomplete request */
-		list_for_each_entry_safe(curr_req, temp_req,
-				&epn->queue, queue) {
-			status = process_ep_req(dev, i, curr_req);
-			dev_vdbg(&dev->pdev->dev, "%s req status: %d\n",
-					epn->name, status);
-
-			if (status)
-				break;
-
-			/* write back status to req */
-			curr_req->req.status = status;
-
-			/* ep0 request completion */
-			if (ep_num == 0) {
-				ep0_req_complete(dev, epn, curr_req);
-				break;
-			} else {
-				done(epn, curr_req, status);
-			}
-		}
-	}
-done:
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-/* port change detect interrupt handler */
-static void handle_port_change(struct langwell_udc *dev)
-{
-	u32	portsc1, devlc;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (dev->bus_reset)
-		dev->bus_reset = 0;
-
-	portsc1 = readl(&dev->op_regs->portsc1);
-	devlc = readl(&dev->op_regs->devlc);
-	dev_vdbg(&dev->pdev->dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
-			portsc1, devlc);
-
-	/* bus reset is finished */
-	if (!(portsc1 & PORTS_PR)) {
-		/* get the speed */
-		dev->gadget.speed = lpm_device_speed(devlc);
-		dev_vdbg(&dev->pdev->dev, "dev->gadget.speed = %d\n",
-			dev->gadget.speed);
-	}
-
-	/* LPM L0 to L1 */
-	if (dev->lpm && dev->lpm_state == LPM_L0)
-		if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) {
-			dev_info(&dev->pdev->dev, "LPM L0 to L1\n");
-			dev->lpm_state = LPM_L1;
-		}
-
-	/* LPM L1 to L0, force resume or remote wakeup finished */
-	if (dev->lpm && dev->lpm_state == LPM_L1)
-		if (!(portsc1 & PORTS_SUSP)) {
-			dev_info(&dev->pdev->dev, "LPM L1 to L0\n");
-			dev->lpm_state = LPM_L0;
-		}
-
-	/* update USB state */
-	if (!dev->resume_state)
-		dev->usb_state = USB_STATE_DEFAULT;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* USB reset interrupt handler */
-static void handle_usb_reset(struct langwell_udc *dev)
-{
-	u32		deviceaddr,
-			endptsetupstat,
-			endptcomplete;
-	unsigned long	timeout;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* Write-Clear the device address */
-	deviceaddr = readl(&dev->op_regs->deviceaddr);
-	writel(deviceaddr & ~USBADR_MASK, &dev->op_regs->deviceaddr);
-
-	dev->dev_addr = 0;
-
-	/* clear usb state */
-	dev->resume_state = 0;
-
-	/* LPM L1 to L0, reset */
-	if (dev->lpm)
-		dev->lpm_state = LPM_L0;
-
-	dev->ep0_dir = USB_DIR_OUT;
-	dev->ep0_state = WAIT_FOR_SETUP;
-
-	/* remote wakeup reset to 0 when the device is reset */
-	dev->remote_wakeup = 0;
-	dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
-	dev->gadget.b_hnp_enable = 0;
-	dev->gadget.a_hnp_support = 0;
-	dev->gadget.a_alt_hnp_support = 0;
-
-	/* Write-Clear all the setup token semaphores */
-	endptsetupstat = readl(&dev->op_regs->endptsetupstat);
-	writel(endptsetupstat, &dev->op_regs->endptsetupstat);
-
-	/* Write-Clear all the endpoint complete status bits */
-	endptcomplete = readl(&dev->op_regs->endptcomplete);
-	writel(endptcomplete, &dev->op_regs->endptcomplete);
-
-	/* wait until all endptprime bits cleared */
-	timeout = jiffies + PRIME_TIMEOUT;
-	while (readl(&dev->op_regs->endptprime)) {
-		if (time_after(jiffies, timeout)) {
-			dev_err(&dev->pdev->dev, "USB reset timeout\n");
-			break;
-		}
-		cpu_relax();
-	}
-
-	/* write 1s to endptflush register to clear any primed buffers */
-	writel((u32) ~0, &dev->op_regs->endptflush);
-
-	if (readl(&dev->op_regs->portsc1) & PORTS_PR) {
-		dev_vdbg(&dev->pdev->dev, "USB bus reset\n");
-		/* bus is reseting */
-		dev->bus_reset = 1;
-
-		/* reset all the queues, stop all USB activities */
-		stop_activity(dev);
-		dev->usb_state = USB_STATE_DEFAULT;
-	} else {
-		dev_vdbg(&dev->pdev->dev, "device controller reset\n");
-		/* controller reset */
-		langwell_udc_reset(dev);
-
-		/* reset all the queues, stop all USB activities */
-		stop_activity(dev);
-
-		/* reset ep0 dQH and endptctrl */
-		ep0_reset(dev);
-
-		/* enable interrupt and set controller to run state */
-		langwell_udc_start(dev);
-
-		dev->usb_state = USB_STATE_ATTACHED;
-	}
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* USB bus suspend/resume interrupt */
-static void handle_bus_suspend(struct langwell_udc *dev)
-{
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	dev->resume_state = dev->usb_state;
-	dev->usb_state = USB_STATE_SUSPENDED;
-
-	/* report suspend to the driver */
-	if (dev->driver) {
-		if (dev->driver->suspend) {
-			spin_unlock(&dev->lock);
-			dev->driver->suspend(&dev->gadget);
-			spin_lock(&dev->lock);
-			dev_dbg(&dev->pdev->dev, "suspend %s\n",
-					dev->driver->driver.name);
-		}
-	}
-
-	/* enter PHY low power suspend */
-	if (dev->pdev->device != 0x0829)
-		langwell_phy_low_power(dev, 0);
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-static void handle_bus_resume(struct langwell_udc *dev)
-{
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	dev->usb_state = dev->resume_state;
-	dev->resume_state = 0;
-
-	/* exit PHY low power suspend */
-	if (dev->pdev->device != 0x0829)
-		langwell_phy_low_power(dev, 0);
-
-	/* report resume to the driver */
-	if (dev->driver) {
-		if (dev->driver->resume) {
-			spin_unlock(&dev->lock);
-			dev->driver->resume(&dev->gadget);
-			spin_lock(&dev->lock);
-			dev_dbg(&dev->pdev->dev, "resume %s\n",
-					dev->driver->driver.name);
-		}
-	}
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* USB device controller interrupt handler */
-static irqreturn_t langwell_irq(int irq, void *_dev)
-{
-	struct langwell_udc	*dev = _dev;
-	u32			usbsts,
-				usbintr,
-				irq_sts,
-				portsc1;
-
-	dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	if (dev->stopped) {
-		dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n");
-		dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-		return IRQ_NONE;
-	}
-
-	spin_lock(&dev->lock);
-
-	/* USB status */
-	usbsts = readl(&dev->op_regs->usbsts);
-
-	/* USB interrupt enable */
-	usbintr = readl(&dev->op_regs->usbintr);
-
-	irq_sts = usbsts & usbintr;
-	dev_vdbg(&dev->pdev->dev,
-			"usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n",
-			usbsts, usbintr, irq_sts);
-
-	if (!irq_sts) {
-		dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n");
-		dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-		spin_unlock(&dev->lock);
-		return IRQ_NONE;
-	}
-
-	/* Write-Clear interrupt status bits */
-	writel(irq_sts, &dev->op_regs->usbsts);
-
-	/* resume from suspend */
-	portsc1 = readl(&dev->op_regs->portsc1);
-	if (dev->usb_state == USB_STATE_SUSPENDED)
-		if (!(portsc1 & PORTS_SUSP))
-			handle_bus_resume(dev);
-
-	/* USB interrupt */
-	if (irq_sts & STS_UI) {
-		dev_vdbg(&dev->pdev->dev, "USB interrupt\n");
-
-		/* setup packet received from ep0 */
-		if (readl(&dev->op_regs->endptsetupstat)
-				& EP0SETUPSTAT_MASK) {
-			dev_vdbg(&dev->pdev->dev,
-				"USB SETUP packet received interrupt\n");
-			/* setup tripwire semaphone */
-			setup_tripwire(dev);
-			handle_setup_packet(dev, &dev->local_setup_buff);
-		}
-
-		/* USB transfer completion */
-		if (readl(&dev->op_regs->endptcomplete)) {
-			dev_vdbg(&dev->pdev->dev,
-				"USB transfer completion interrupt\n");
-			handle_trans_complete(dev);
-		}
-	}
-
-	/* SOF received interrupt (for ISO transfer) */
-	if (irq_sts & STS_SRI) {
-		/* FIXME */
-		/* dev_vdbg(&dev->pdev->dev, "SOF received interrupt\n"); */
-	}
-
-	/* port change detect interrupt */
-	if (irq_sts & STS_PCI) {
-		dev_vdbg(&dev->pdev->dev, "port change detect interrupt\n");
-		handle_port_change(dev);
-	}
-
-	/* suspend interrupt */
-	if (irq_sts & STS_SLI) {
-		dev_vdbg(&dev->pdev->dev, "suspend interrupt\n");
-		handle_bus_suspend(dev);
-	}
-
-	/* USB reset interrupt */
-	if (irq_sts & STS_URI) {
-		dev_vdbg(&dev->pdev->dev, "USB reset interrupt\n");
-		handle_usb_reset(dev);
-	}
-
-	/* USB error or system error interrupt */
-	if (irq_sts & (STS_UEI | STS_SEI)) {
-		/* FIXME */
-		dev_warn(&dev->pdev->dev, "error IRQ, irq_sts: %x\n", irq_sts);
-	}
-
-	spin_unlock(&dev->lock);
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return IRQ_HANDLED;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* release device structure */
-static void gadget_release(struct device *_dev)
-{
-	struct langwell_udc	*dev = dev_get_drvdata(_dev);
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	complete(dev->done);
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	kfree(dev);
-}
-
-
-/* enable SRAM caching if SRAM detected */
-static void sram_init(struct langwell_udc *dev)
-{
-	struct pci_dev		*pdev = dev->pdev;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	dev->sram_addr = pci_resource_start(pdev, 1);
-	dev->sram_size = pci_resource_len(pdev, 1);
-	dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n",
-			dev->sram_addr, dev->sram_size);
-	dev->got_sram = 1;
-
-	if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) {
-		dev_warn(&dev->pdev->dev, "SRAM request failed\n");
-		dev->got_sram = 0;
-	} else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr,
-			dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) {
-		dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n");
-		pci_release_region(pdev, 1);
-		dev->got_sram = 0;
-	}
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* release SRAM caching */
-static void sram_deinit(struct langwell_udc *dev)
-{
-	struct pci_dev *pdev = dev->pdev;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	dma_release_declared_memory(&pdev->dev);
-	pci_release_region(pdev, 1);
-
-	dev->got_sram = 0;
-
-	dev_info(&dev->pdev->dev, "release SRAM caching\n");
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-
-/* tear down the binding between this driver and the pci device */
-static void langwell_udc_remove(struct pci_dev *pdev)
-{
-	struct langwell_udc	*dev = pci_get_drvdata(pdev);
-
-	DECLARE_COMPLETION(done);
-
-	BUG_ON(dev->driver);
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	dev->done = &done;
-
-	/* free dTD dma_pool and dQH */
-	if (dev->dtd_pool)
-		dma_pool_destroy(dev->dtd_pool);
-
-	if (dev->ep_dqh)
-		dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
-			dev->ep_dqh, dev->ep_dqh_dma);
-
-	/* release SRAM caching */
-	if (dev->has_sram && dev->got_sram)
-		sram_deinit(dev);
-
-	if (dev->status_req) {
-		kfree(dev->status_req->req.buf);
-		kfree(dev->status_req);
-	}
-
-	kfree(dev->ep);
-
-	/* disable IRQ handler */
-	if (dev->got_irq)
-		free_irq(pdev->irq, dev);
-
-	if (dev->cap_regs)
-		iounmap(dev->cap_regs);
-
-	if (dev->region)
-		release_mem_region(pci_resource_start(pdev, 0),
-				pci_resource_len(pdev, 0));
-
-	if (dev->enabled)
-		pci_disable_device(pdev);
-
-	dev->cap_regs = NULL;
-
-	dev_info(&dev->pdev->dev, "unbind\n");
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-
-	device_unregister(&dev->gadget.dev);
-	device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
-	device_remove_file(&pdev->dev, &dev_attr_remote_wakeup);
-
-	pci_set_drvdata(pdev, NULL);
-
-	/* free dev, wait for the release() finished */
-	wait_for_completion(&done);
-}
-
-
-/*
- * wrap this driver around the specified device, but
- * don't respond over USB until a gadget driver binds to us.
- */
-static int langwell_udc_probe(struct pci_dev *pdev,
-		const struct pci_device_id *id)
-{
-	struct langwell_udc	*dev;
-	unsigned long		resource, len;
-	void			__iomem *base = NULL;
-	size_t			size;
-	int			retval;
-
-	/* alloc, and start init */
-	dev = kzalloc(sizeof *dev, GFP_KERNEL);
-	if (dev == NULL) {
-		retval = -ENOMEM;
-		goto error;
-	}
-
-	/* initialize device spinlock */
-	spin_lock_init(&dev->lock);
-
-	dev->pdev = pdev;
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	pci_set_drvdata(pdev, dev);
-
-	/* now all the pci goodies ... */
-	if (pci_enable_device(pdev) < 0) {
-		retval = -ENODEV;
-		goto error;
-	}
-	dev->enabled = 1;
-
-	/* control register: BAR 0 */
-	resource = pci_resource_start(pdev, 0);
-	len = pci_resource_len(pdev, 0);
-	if (!request_mem_region(resource, len, driver_name)) {
-		dev_err(&dev->pdev->dev, "controller already in use\n");
-		retval = -EBUSY;
-		goto error;
-	}
-	dev->region = 1;
-
-	base = ioremap_nocache(resource, len);
-	if (base == NULL) {
-		dev_err(&dev->pdev->dev, "can't map memory\n");
-		retval = -EFAULT;
-		goto error;
-	}
-
-	dev->cap_regs = (struct langwell_cap_regs __iomem *) base;
-	dev_vdbg(&dev->pdev->dev, "dev->cap_regs: %p\n", dev->cap_regs);
-	dev->op_regs = (struct langwell_op_regs __iomem *)
-		(base + OP_REG_OFFSET);
-	dev_vdbg(&dev->pdev->dev, "dev->op_regs: %p\n", dev->op_regs);
-
-	/* irq setup after old hardware is cleaned up */
-	if (!pdev->irq) {
-		dev_err(&dev->pdev->dev, "No IRQ. Check PCI setup!\n");
-		retval = -ENODEV;
-		goto error;
-	}
-
-	dev->has_sram = 1;
-	dev->got_sram = 0;
-	dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram);
-
-	/* enable SRAM caching if detected */
-	if (dev->has_sram && !dev->got_sram)
-		sram_init(dev);
-
-	dev_info(&dev->pdev->dev,
-			"irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
-			pdev->irq, resource, len, base);
-	/* enables bus-mastering for device dev */
-	pci_set_master(pdev);
-
-	if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
-				driver_name, dev) != 0) {
-		dev_err(&dev->pdev->dev,
-				"request interrupt %d failed\n", pdev->irq);
-		retval = -EBUSY;
-		goto error;
-	}
-	dev->got_irq = 1;
-
-	/* set stopped bit */
-	dev->stopped = 1;
-
-	/* capabilities and endpoint number */
-	dev->lpm = (readl(&dev->cap_regs->hccparams) & HCC_LEN) ? 1 : 0;
-	dev->dciversion = readw(&dev->cap_regs->dciversion);
-	dev->devcap = (readl(&dev->cap_regs->dccparams) & DEVCAP) ? 1 : 0;
-	dev_vdbg(&dev->pdev->dev, "dev->lpm: %d\n", dev->lpm);
-	dev_vdbg(&dev->pdev->dev, "dev->dciversion: 0x%04x\n",
-			dev->dciversion);
-	dev_vdbg(&dev->pdev->dev, "dccparams: 0x%08x\n",
-			readl(&dev->cap_regs->dccparams));
-	dev_vdbg(&dev->pdev->dev, "dev->devcap: %d\n", dev->devcap);
-	if (!dev->devcap) {
-		dev_err(&dev->pdev->dev, "can't support device mode\n");
-		retval = -ENODEV;
-		goto error;
-	}
-
-	/* a pair of endpoints (out/in) for each address */
-	dev->ep_max = DEN(readl(&dev->cap_regs->dccparams)) * 2;
-	dev_vdbg(&dev->pdev->dev, "dev->ep_max: %d\n", dev->ep_max);
-
-	/* allocate endpoints memory */
-	dev->ep = kzalloc(sizeof(struct langwell_ep) * dev->ep_max,
-			GFP_KERNEL);
-	if (!dev->ep) {
-		dev_err(&dev->pdev->dev, "allocate endpoints memory failed\n");
-		retval = -ENOMEM;
-		goto error;
-	}
-
-	/* allocate device dQH memory */
-	size = dev->ep_max * sizeof(struct langwell_dqh);
-	dev_vdbg(&dev->pdev->dev, "orig size = %zd\n", size);
-	if (size < DQH_ALIGNMENT)
-		size = DQH_ALIGNMENT;
-	else if ((size % DQH_ALIGNMENT) != 0) {
-		size += DQH_ALIGNMENT + 1;
-		size &= ~(DQH_ALIGNMENT - 1);
-	}
-	dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
-					&dev->ep_dqh_dma, GFP_KERNEL);
-	if (!dev->ep_dqh) {
-		dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
-		retval = -ENOMEM;
-		goto error;
-	}
-	dev->ep_dqh_size = size;
-	dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %zd\n", dev->ep_dqh_size);
-
-	/* initialize ep0 status request structure */
-	dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL);
-	if (!dev->status_req) {
-		dev_err(&dev->pdev->dev,
-				"allocate status_req memory failed\n");
-		retval = -ENOMEM;
-		goto error;
-	}
-	INIT_LIST_HEAD(&dev->status_req->queue);
-
-	/* allocate a small amount of memory to get valid address */
-	dev->status_req->req.buf = kmalloc(8, GFP_KERNEL);
-	dev->status_req->req.dma = virt_to_phys(dev->status_req->req.buf);
-
-	dev->resume_state = USB_STATE_NOTATTACHED;
-	dev->usb_state = USB_STATE_POWERED;
-	dev->ep0_dir = USB_DIR_OUT;
-
-	/* remote wakeup reset to 0 when the device is reset */
-	dev->remote_wakeup = 0;
-	dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
-
-	/* reset device controller */
-	langwell_udc_reset(dev);
-
-	/* initialize gadget structure */
-	dev->gadget.ops = &langwell_ops;	/* usb_gadget_ops */
-	dev->gadget.ep0 = &dev->ep[0].ep;	/* gadget ep0 */
-	INIT_LIST_HEAD(&dev->gadget.ep_list);	/* ep_list */
-	dev->gadget.speed = USB_SPEED_UNKNOWN;	/* speed */
-	dev->gadget.max_speed = USB_SPEED_HIGH;	/* support dual speed */
-
-	/* the "gadget" abstracts/virtualizes the controller */
-	dev_set_name(&dev->gadget.dev, "gadget");
-	dev->gadget.dev.parent = &pdev->dev;
-	dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
-	dev->gadget.dev.release = gadget_release;
-	dev->gadget.name = driver_name;		/* gadget name */
-
-	/* controller endpoints reinit */
-	eps_reinit(dev);
-
-	/* reset ep0 dQH and endptctrl */
-	ep0_reset(dev);
-
-	/* create dTD dma_pool resource */
-	dev->dtd_pool = dma_pool_create("langwell_dtd",
-			&dev->pdev->dev,
-			sizeof(struct langwell_dtd),
-			DTD_ALIGNMENT,
-			DMA_BOUNDARY);
-
-	if (!dev->dtd_pool) {
-		retval = -ENOMEM;
-		goto error;
-	}
-
-	/* done */
-	dev_info(&dev->pdev->dev, "%s\n", driver_desc);
-	dev_info(&dev->pdev->dev, "irq %d, pci mem %p\n", pdev->irq, base);
-	dev_info(&dev->pdev->dev, "Driver version: " DRIVER_VERSION "\n");
-	dev_info(&dev->pdev->dev, "Support (max) %d endpoints\n", dev->ep_max);
-	dev_info(&dev->pdev->dev, "Device interface version: 0x%04x\n",
-			dev->dciversion);
-	dev_info(&dev->pdev->dev, "Controller mode: %s\n",
-			dev->devcap ? "Device" : "Host");
-	dev_info(&dev->pdev->dev, "Support USB LPM: %s\n",
-			dev->lpm ? "Yes" : "No");
-
-	dev_vdbg(&dev->pdev->dev,
-			"After langwell_udc_probe(), print all registers:\n");
-	print_all_registers(dev);
-
-	retval = device_register(&dev->gadget.dev);
-	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;
-
-	retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup);
-	if (retval)
-		goto error_attr1;
-
-	dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-
-error_attr1:
-	device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
-error:
-	if (dev) {
-		dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-		langwell_udc_remove(pdev);
-	}
-
-	return retval;
-}
-
-
-/* device controller suspend */
-static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-	struct langwell_udc	*dev = pci_get_drvdata(pdev);
-
-	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);
-
-	/* disable IRQ handler */
-	if (dev->got_irq)
-		free_irq(pdev->irq, dev);
-	dev->got_irq = 0;
-
-	/* save PCI state */
-	pci_save_state(pdev);
-
-	spin_lock_irq(&dev->lock);
-	/* stop all usb activities */
-	stop_activity(dev);
-	spin_unlock_irq(&dev->lock);
-
-	/* free dTD dma_pool and dQH */
-	if (dev->dtd_pool)
-		dma_pool_destroy(dev->dtd_pool);
-
-	if (dev->ep_dqh)
-		dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
-			dev->ep_dqh, dev->ep_dqh_dma);
-
-	/* release SRAM caching */
-	if (dev->has_sram && dev->got_sram)
-		sram_deinit(dev);
-
-	/* set device power state */
-	pci_set_power_state(pdev, PCI_D3hot);
-
-	/* enter PHY low power suspend */
-	if (dev->pdev->device != 0x0829)
-		langwell_phy_low_power(dev, 1);
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* device controller resume */
-static int langwell_udc_resume(struct pci_dev *pdev)
-{
-	struct langwell_udc	*dev = pci_get_drvdata(pdev);
-	size_t			size;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* exit PHY low power suspend */
-	if (dev->pdev->device != 0x0829)
-		langwell_phy_low_power(dev, 0);
-
-	/* set device D0 power state */
-	pci_set_power_state(pdev, PCI_D0);
-
-	/* enable SRAM caching if detected */
-	if (dev->has_sram && !dev->got_sram)
-		sram_init(dev);
-
-	/* allocate device dQH memory */
-	size = dev->ep_max * sizeof(struct langwell_dqh);
-	dev_vdbg(&dev->pdev->dev, "orig size = %zd\n", size);
-	if (size < DQH_ALIGNMENT)
-		size = DQH_ALIGNMENT;
-	else if ((size % DQH_ALIGNMENT) != 0) {
-		size += DQH_ALIGNMENT + 1;
-		size &= ~(DQH_ALIGNMENT - 1);
-	}
-	dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
-					&dev->ep_dqh_dma, GFP_KERNEL);
-	if (!dev->ep_dqh) {
-		dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
-		return -ENOMEM;
-	}
-	dev->ep_dqh_size = size;
-	dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %zd\n", dev->ep_dqh_size);
-
-	/* create dTD dma_pool resource */
-	dev->dtd_pool = dma_pool_create("langwell_dtd",
-			&dev->pdev->dev,
-			sizeof(struct langwell_dtd),
-			DTD_ALIGNMENT,
-			DMA_BOUNDARY);
-
-	if (!dev->dtd_pool)
-		return -ENOMEM;
-
-	/* restore PCI state */
-	pci_restore_state(pdev);
-
-	/* enable IRQ handler */
-	if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
-				driver_name, dev) != 0) {
-		dev_err(&dev->pdev->dev, "request interrupt %d failed\n",
-				pdev->irq);
-		return -EBUSY;
-	}
-	dev->got_irq = 1;
-
-	/* reset and start controller to run state */
-	if (dev->stopped) {
-		/* reset device controller */
-		langwell_udc_reset(dev);
-
-		/* reset ep0 dQH and endptctrl */
-		ep0_reset(dev);
-
-		/* start device if gadget is loaded */
-		if (dev->driver)
-			langwell_udc_start(dev);
-	}
-
-	/* reset USB status */
-	dev->usb_state = USB_STATE_ATTACHED;
-	dev->ep0_state = WAIT_FOR_SETUP;
-	dev->ep0_dir = USB_DIR_OUT;
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-	return 0;
-}
-
-
-/* pci driver shutdown */
-static void langwell_udc_shutdown(struct pci_dev *pdev)
-{
-	struct langwell_udc	*dev = pci_get_drvdata(pdev);
-	u32			usbmode;
-
-	dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
-
-	/* reset controller mode to IDLE */
-	usbmode = readl(&dev->op_regs->usbmode);
-	dev_dbg(&dev->pdev->dev, "usbmode = 0x%08x\n", usbmode);
-	usbmode &= (~3 | MODE_IDLE);
-	writel(usbmode, &dev->op_regs->usbmode);
-
-	dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static const struct pci_device_id pci_ids[] = { {
-	.class =	((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-	.class_mask =	~0,
-	.vendor =	0x8086,
-	.device =	0x0811,
-	.subvendor =	PCI_ANY_ID,
-	.subdevice =	PCI_ANY_ID,
-}, { /* end: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE(pci, pci_ids);
-
-
-static struct pci_driver langwell_pci_driver = {
-	.name =		(char *) driver_name,
-	.id_table =	pci_ids,
-
-	.probe =	langwell_udc_probe,
-	.remove =	langwell_udc_remove,
-
-	/* device controller suspend/resume */
-	.suspend =	langwell_udc_suspend,
-	.resume =	langwell_udc_resume,
-
-	.shutdown =	langwell_udc_shutdown,
-};
-
-
-static int __init init(void)
-{
-	return pci_register_driver(&langwell_pci_driver);
-}
-module_init(init);
-
-
-static void __exit cleanup(void)
-{
-	pci_unregister_driver(&langwell_pci_driver);
-}
-module_exit(cleanup);
-
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h
deleted file mode 100644
index 8c8087a..0000000
--- a/drivers/usb/gadget/langwell_udc.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Intel Langwell USB Device Controller driver
- * Copyright (C) 2008-2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- */
-
-#include <linux/usb/langwell_udc.h>
-
-/*-------------------------------------------------------------------------*/
-
-/* driver data structures and utilities */
-
-/*
- * dTD: Device Endpoint Transfer Descriptor
- * describe to the device controller the location and quantity of
- * data to be send/received for given transfer
- */
-struct langwell_dtd {
-	u32	dtd_next;
-/* bits 31:5, next transfer element pointer */
-#define	DTD_NEXT(d)	(((d)>>5)&0x7ffffff)
-#define	DTD_NEXT_MASK	(0x7ffffff << 5)
-/* terminate */
-#define	DTD_TERM	BIT(0)
-	/* bits 7:0, execution back states */
-	u32	dtd_status:8;
-#define	DTD_STATUS(d)	(((d)>>0)&0xff)
-#define	DTD_STS_ACTIVE	BIT(7)	/* active */
-#define	DTD_STS_HALTED	BIT(6)	/* halted */
-#define	DTD_STS_DBE	BIT(5)	/* data buffer error */
-#define	DTD_STS_TRE	BIT(3)	/* transaction error  */
-	/* bits 9:8 */
-	u32	dtd_res0:2;
-	/* bits 11:10, multipier override */
-	u32	dtd_multo:2;
-#define	DTD_MULTO	(BIT(11) | BIT(10))
-	/* bits 14:12 */
-	u32	dtd_res1:3;
-	/* bit 15, interrupt on complete */
-	u32	dtd_ioc:1;
-#define	DTD_IOC		BIT(15)
-	/* bits 30:16, total bytes */
-	u32	dtd_total:15;
-#define	DTD_TOTAL(d)	(((d)>>16)&0x7fff)
-#define	DTD_MAX_TRANSFER_LENGTH	0x4000
-	/* bit 31 */
-	u32	dtd_res2:1;
-	/* dTD buffer pointer page 0 to 4 */
-	u32	dtd_buf[5];
-#define	DTD_OFFSET_MASK	0xfff
-/* bits 31:12, buffer pointer */
-#define	DTD_BUFFER(d)	(((d)>>12)&0x3ff)
-/* bits 11:0, current offset */
-#define	DTD_C_OFFSET(d)	(((d)>>0)&0xfff)
-/* bits 10:0, frame number */
-#define	DTD_FRAME(d)	(((d)>>0)&0x7ff)
-
-	/* driver-private parts */
-
-	/* dtd dma address */
-	dma_addr_t		dtd_dma;
-	/* next dtd virtual address */
-	struct langwell_dtd	*next_dtd_virt;
-};
-
-
-/*
- * dQH: Device Endpoint Queue Head
- * describe where all transfers are managed
- * 48-byte data structure, aligned on 64-byte boundary
- *
- * These are associated with dTD structure
- */
-struct langwell_dqh {
-	/* endpoint capabilities and characteristics */
-	u32	dqh_res0:15;	/* bits 14:0 */
-	u32	dqh_ios:1;	/* bit 15, interrupt on setup */
-#define	DQH_IOS		BIT(15)
-	u32	dqh_mpl:11;	/* bits 26:16, maximum packet length */
-#define	DQH_MPL		(0x7ff << 16)
-	u32	dqh_res1:2;	/* bits 28:27 */
-	u32	dqh_zlt:1;	/* bit 29, zero length termination */
-#define	DQH_ZLT		BIT(29)
-	u32	dqh_mult:2;	/* bits 31:30 */
-#define	DQH_MULT	(BIT(30) | BIT(31))
-
-	/* current dTD pointer */
-	u32	dqh_current;	/* locate the transfer in progress */
-#define DQH_C_DTD(e)	\
-	(((e)>>5)&0x7ffffff)	/* bits 31:5, current dTD pointer */
-
-	/* transfer overlay, hardware parts of a struct langwell_dtd */
-	u32	dtd_next;
-	u32	dtd_status:8;	/* bits 7:0, execution back states */
-	u32	dtd_res0:2;	/* bits 9:8 */
-	u32	dtd_multo:2;	/* bits 11:10, multipier override */
-	u32	dtd_res1:3;	/* bits 14:12 */
-	u32	dtd_ioc:1;	/* bit 15, interrupt on complete */
-	u32	dtd_total:15;	/* bits 30:16, total bytes */
-	u32	dtd_res2:1;	/* bit 31 */
-	u32	dtd_buf[5];	/* dTD buffer pointer page 0 to 4 */
-
-	u32	dqh_res2;
-	struct usb_ctrlrequest	dqh_setup;	/* setup packet buffer */
-} __attribute__ ((aligned(64)));
-
-
-/* endpoint data structure */
-struct langwell_ep {
-	struct usb_ep		ep;
-	dma_addr_t		dma;
-	struct langwell_udc	*dev;
-	unsigned long		irqs;
-	struct list_head	queue;
-	struct langwell_dqh	*dqh;
-	const struct usb_endpoint_descriptor	*desc;
-	char			name[14];
-	unsigned		stopped:1,
-				ep_type:2,
-				ep_num:8;
-};
-
-
-/* request data structure */
-struct langwell_request {
-	struct usb_request	req;
-	struct langwell_dtd	*dtd, *head, *tail;
-	struct langwell_ep	*ep;
-	dma_addr_t		dtd_dma;
-	struct list_head	queue;
-	unsigned		dtd_count;
-	unsigned		mapped:1;
-};
-
-
-/* ep0 transfer state */
-enum ep0_state {
-	WAIT_FOR_SETUP,
-	DATA_STATE_XMIT,
-	DATA_STATE_NEED_ZLP,
-	WAIT_FOR_OUT_STATUS,
-	DATA_STATE_RECV,
-};
-
-
-/* device suspend state */
-enum lpm_state {
-	LPM_L0,	/* on */
-	LPM_L1,	/* LPM L1 sleep */
-	LPM_L2,	/* suspend */
-	LPM_L3,	/* off */
-};
-
-
-/* device data structure */
-struct langwell_udc {
-	/* each pci device provides one gadget, several endpoints */
-	struct usb_gadget	gadget;
-	spinlock_t		lock;	/* device lock */
-	struct langwell_ep	*ep;
-	struct usb_gadget_driver	*driver;
-	struct usb_phy		*transceiver;
-	u8			dev_addr;
-	u32			usb_state;
-	u32			resume_state;
-	u32			bus_reset;
-	enum lpm_state		lpm_state;
-	enum ep0_state		ep0_state;
-	u32			ep0_dir;
-	u16			dciversion;
-	unsigned		ep_max;
-	unsigned		devcap:1,
-				enabled:1,
-				region:1,
-				got_irq:1,
-				powered:1,
-				remote_wakeup:1,
-				rate:1,
-				is_reset:1,
-				softconnected:1,
-				vbus_active:1,
-				suspended:1,
-				stopped:1,
-				lpm:1,		/* LPM capability */
-				has_sram:1,	/* SRAM caching */
-				got_sram:1;
-
-	/* pci state used to access those endpoints */
-	struct pci_dev		*pdev;
-
-	/* Langwell otg transceiver */
-	struct langwell_otg	*lotg;
-
-	/* control registers */
-	struct langwell_cap_regs	__iomem	*cap_regs;
-	struct langwell_op_regs		__iomem	*op_regs;
-
-	struct usb_ctrlrequest	local_setup_buff;
-	struct langwell_dqh	*ep_dqh;
-	size_t			ep_dqh_size;
-	dma_addr_t		ep_dqh_dma;
-
-	/* ep0 status request */
-	struct langwell_request	*status_req;
-
-	/* dma pool */
-	struct dma_pool		*dtd_pool;
-
-	/* make sure release() is done */
-	struct completion	*done;
-
-	/* for private SRAM caching */
-	unsigned int		sram_addr;
-	unsigned int		sram_size;
-
-	/* device status data for get_status request */
-	u16			dev_status;
-};
-
-#define gadget_to_langwell(g)	container_of((g), struct langwell_udc, gadget)
-
diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c
new file mode 100644
index 0000000..262acfd
--- /dev/null
+++ b/drivers/usb/gadget/lpc32xx_udc.c
@@ -0,0 +1,3538 @@
+/*
+ * USB Gadget driver for LPC32xx
+ *
+ * Authors:
+ *    Kevin Wells <kevin.wells@nxp.com>
+ *    Mike James
+ *    Roland Stigge <stigge@antcom.de>
+ *
+ * Copyright (C) 2006 Philips Semiconductors
+ * Copyright (C) 2009 NXP Semiconductors
+ * Copyright (C) 2012 Roland Stigge
+ *
+ * Note: This driver is based on original work done by Mike James for
+ *       the LPC3180.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/i2c.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/workqueue.h>
+#include <linux/of.h>
+#include <linux/usb/isp1301.h>
+
+#include <asm/byteorder.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <mach/platform.h>
+#include <mach/irqs.h>
+#include <mach/board.h>
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+#include <linux/seq_file.h>
+#endif
+
+/*
+ * USB device configuration structure
+ */
+typedef void (*usc_chg_event)(int);
+struct lpc32xx_usbd_cfg {
+	int vbus_drv_pol;   /* 0=active low drive for VBUS via ISP1301 */
+	usc_chg_event conn_chgb; /* Connection change event (optional) */
+	usc_chg_event susp_chgb; /* Suspend/resume event (optional) */
+	usc_chg_event rmwk_chgb; /* Enable/disable remote wakeup */
+};
+
+/*
+ * controller driver data structures
+ */
+
+/* 16 endpoints (not to be confused with 32 hardware endpoints) */
+#define	NUM_ENDPOINTS	16
+
+/*
+ * IRQ indices make reading the code a little easier
+ */
+#define IRQ_USB_LP	0
+#define IRQ_USB_HP	1
+#define IRQ_USB_DEVDMA	2
+#define IRQ_USB_ATX	3
+
+#define EP_OUT 0 /* RX (from host) */
+#define EP_IN 1 /* TX (to host) */
+
+/* Returns the interrupt mask for the selected hardware endpoint */
+#define EP_MASK_SEL(ep, dir) (1 << (((ep) * 2) + dir))
+
+#define EP_INT_TYPE 0
+#define EP_ISO_TYPE 1
+#define EP_BLK_TYPE 2
+#define EP_CTL_TYPE 3
+
+/* EP0 states */
+#define WAIT_FOR_SETUP 0 /* Wait for setup packet */
+#define DATA_IN        1 /* Expect dev->host transfer */
+#define DATA_OUT       2 /* Expect host->dev transfer */
+
+/* DD (DMA Descriptor) structure, requires word alignment, this is already
+ * defined in the LPC32XX USB device header file, but this version is slightly
+ * modified to tag some work data with each DMA descriptor. */
+struct lpc32xx_usbd_dd_gad {
+	u32 dd_next_phy;
+	u32 dd_setup;
+	u32 dd_buffer_addr;
+	u32 dd_status;
+	u32 dd_iso_ps_mem_addr;
+	u32 this_dma;
+	u32 iso_status[6]; /* 5 spare */
+	u32 dd_next_v;
+};
+
+/*
+ * Logical endpoint structure
+ */
+struct lpc32xx_ep {
+	struct usb_ep		ep;
+	struct list_head	queue;
+	struct lpc32xx_udc	*udc;
+
+	u32			hwep_num_base; /* Physical hardware EP */
+	u32			hwep_num; /* Maps to hardware endpoint */
+	u32			maxpacket;
+	u32			lep;
+
+	bool			is_in;
+	bool			req_pending;
+	u32			eptype;
+
+	u32                     totalints;
+
+	bool			wedge;
+
+	const struct usb_endpoint_descriptor *desc;
+};
+
+/*
+ * Common UDC structure
+ */
+struct lpc32xx_udc {
+	struct usb_gadget	gadget;
+	struct usb_gadget_driver *driver;
+	struct platform_device	*pdev;
+	struct device		*dev;
+	struct dentry		*pde;
+	spinlock_t		lock;
+	struct i2c_client	*isp1301_i2c_client;
+
+	/* Board and device specific */
+	struct lpc32xx_usbd_cfg	*board;
+	u32			io_p_start;
+	u32			io_p_size;
+	void __iomem		*udp_baseaddr;
+	int			udp_irq[4];
+	struct clk		*usb_pll_clk;
+	struct clk		*usb_slv_clk;
+
+	/* DMA support */
+	u32			*udca_v_base;
+	u32			udca_p_base;
+	struct dma_pool		*dd_cache;
+
+	/* Common EP and control data */
+	u32			enabled_devints;
+	u32			enabled_hwepints;
+	u32			dev_status;
+	u32			realized_eps;
+
+	/* VBUS detection, pullup, and power flags */
+	u8			vbus;
+	u8			last_vbus;
+	int			pullup;
+	int			poweron;
+
+	/* Work queues related to I2C support */
+	struct work_struct	pullup_job;
+	struct work_struct	vbus_job;
+	struct work_struct	power_job;
+
+	/* USB device peripheral - various */
+	struct lpc32xx_ep	ep[NUM_ENDPOINTS];
+	bool			enabled;
+	bool			clocked;
+	bool			suspended;
+	bool			selfpowered;
+	int                     ep0state;
+	atomic_t                enabled_ep_cnt;
+	wait_queue_head_t       ep_disable_wait_queue;
+};
+
+/*
+ * Endpoint request
+ */
+struct lpc32xx_request {
+	struct usb_request	req;
+	struct list_head	queue;
+	struct lpc32xx_usbd_dd_gad *dd_desc_ptr;
+	bool			mapped;
+	bool			send_zlp;
+};
+
+static inline struct lpc32xx_udc *to_udc(struct usb_gadget *g)
+{
+	return container_of(g, struct lpc32xx_udc, gadget);
+}
+
+#define ep_dbg(epp, fmt, arg...) \
+	dev_dbg(epp->udc->dev, "%s: " fmt, __func__, ## arg)
+#define ep_err(epp, fmt, arg...) \
+	dev_err(epp->udc->dev, "%s: " fmt, __func__, ## arg)
+#define ep_info(epp, fmt, arg...) \
+	dev_info(epp->udc->dev, "%s: " fmt, __func__, ## arg)
+#define ep_warn(epp, fmt, arg...) \
+	dev_warn(epp->udc->dev, "%s:" fmt, __func__, ## arg)
+
+#define UDCA_BUFF_SIZE (128)
+
+/* TODO: When the clock framework is introduced in LPC32xx, IO_ADDRESS will
+ * be replaced with an inremap()ed pointer, see USB_OTG_CLK_CTRL()
+ * */
+#define USB_CTRL		IO_ADDRESS(LPC32XX_CLK_PM_BASE + 0x64)
+#define USB_CLOCK_MASK		(AHB_M_CLOCK_ON | OTG_CLOCK_ON | \
+				 DEV_CLOCK_ON | I2C_CLOCK_ON)
+
+/* USB_CTRL bit defines */
+#define USB_SLAVE_HCLK_EN	(1 << 24)
+#define USB_HOST_NEED_CLK_EN	(1 << 21)
+#define USB_DEV_NEED_CLK_EN	(1 << 22)
+
+#define USB_OTG_CLK_CTRL(udc)	((udc)->udp_baseaddr + 0xFF4)
+#define USB_OTG_CLK_STAT(udc)	((udc)->udp_baseaddr + 0xFF8)
+
+/* USB_OTG_CLK_CTRL bit defines */
+#define AHB_M_CLOCK_ON		(1 << 4)
+#define OTG_CLOCK_ON		(1 << 3)
+#define I2C_CLOCK_ON		(1 << 2)
+#define DEV_CLOCK_ON		(1 << 1)
+#define HOST_CLOCK_ON		(1 << 0)
+
+#define USB_OTG_STAT_CONTROL(udc) (udc->udp_baseaddr + 0x110)
+
+/* USB_OTG_STAT_CONTROL bit defines */
+#define TRANSPARENT_I2C_EN	(1 << 7)
+#define HOST_EN			(1 << 0)
+
+/**********************************************************************
+ * USB device controller register offsets
+ **********************************************************************/
+
+#define USBD_DEVINTST(x)	((x) + 0x200)
+#define USBD_DEVINTEN(x)	((x) + 0x204)
+#define USBD_DEVINTCLR(x)	((x) + 0x208)
+#define USBD_DEVINTSET(x)	((x) + 0x20C)
+#define USBD_CMDCODE(x)		((x) + 0x210)
+#define USBD_CMDDATA(x)		((x) + 0x214)
+#define USBD_RXDATA(x)		((x) + 0x218)
+#define USBD_TXDATA(x)		((x) + 0x21C)
+#define USBD_RXPLEN(x)		((x) + 0x220)
+#define USBD_TXPLEN(x)		((x) + 0x224)
+#define USBD_CTRL(x)		((x) + 0x228)
+#define USBD_DEVINTPRI(x)	((x) + 0x22C)
+#define USBD_EPINTST(x)		((x) + 0x230)
+#define USBD_EPINTEN(x)		((x) + 0x234)
+#define USBD_EPINTCLR(x)	((x) + 0x238)
+#define USBD_EPINTSET(x)	((x) + 0x23C)
+#define USBD_EPINTPRI(x)	((x) + 0x240)
+#define USBD_REEP(x)		((x) + 0x244)
+#define USBD_EPIND(x)		((x) + 0x248)
+#define USBD_EPMAXPSIZE(x)	((x) + 0x24C)
+/* DMA support registers only below */
+/* Set, clear, or get enabled state of the DMA request status. If
+ * enabled, an IN or OUT token will start a DMA transfer for the EP */
+#define USBD_DMARST(x)		((x) + 0x250)
+#define USBD_DMARCLR(x)		((x) + 0x254)
+#define USBD_DMARSET(x)		((x) + 0x258)
+/* DMA UDCA head pointer */
+#define USBD_UDCAH(x)		((x) + 0x280)
+/* EP DMA status, enable, and disable. This is used to specifically
+ * enabled or disable DMA for a specific EP */
+#define USBD_EPDMAST(x)		((x) + 0x284)
+#define USBD_EPDMAEN(x)		((x) + 0x288)
+#define USBD_EPDMADIS(x)	((x) + 0x28C)
+/* DMA master interrupts enable and pending interrupts */
+#define USBD_DMAINTST(x)	((x) + 0x290)
+#define USBD_DMAINTEN(x)	((x) + 0x294)
+/* DMA end of transfer interrupt enable, disable, status */
+#define USBD_EOTINTST(x)	((x) + 0x2A0)
+#define USBD_EOTINTCLR(x)	((x) + 0x2A4)
+#define USBD_EOTINTSET(x)	((x) + 0x2A8)
+/* New DD request interrupt enable, disable, status */
+#define USBD_NDDRTINTST(x)	((x) + 0x2AC)
+#define USBD_NDDRTINTCLR(x)	((x) + 0x2B0)
+#define USBD_NDDRTINTSET(x)	((x) + 0x2B4)
+/* DMA error interrupt enable, disable, status */
+#define USBD_SYSERRTINTST(x)	((x) + 0x2B8)
+#define USBD_SYSERRTINTCLR(x)	((x) + 0x2BC)
+#define USBD_SYSERRTINTSET(x)	((x) + 0x2C0)
+
+/**********************************************************************
+ * USBD_DEVINTST/USBD_DEVINTEN/USBD_DEVINTCLR/USBD_DEVINTSET/
+ * USBD_DEVINTPRI register definitions
+ **********************************************************************/
+#define USBD_ERR_INT		(1 << 9)
+#define USBD_EP_RLZED		(1 << 8)
+#define USBD_TXENDPKT		(1 << 7)
+#define USBD_RXENDPKT		(1 << 6)
+#define USBD_CDFULL		(1 << 5)
+#define USBD_CCEMPTY		(1 << 4)
+#define USBD_DEV_STAT		(1 << 3)
+#define USBD_EP_SLOW		(1 << 2)
+#define USBD_EP_FAST		(1 << 1)
+#define USBD_FRAME		(1 << 0)
+
+/**********************************************************************
+ * USBD_EPINTST/USBD_EPINTEN/USBD_EPINTCLR/USBD_EPINTSET/
+ * USBD_EPINTPRI register definitions
+ **********************************************************************/
+/* End point selection macro (RX) */
+#define USBD_RX_EP_SEL(e)	(1 << ((e) << 1))
+
+/* End point selection macro (TX) */
+#define USBD_TX_EP_SEL(e)	(1 << (((e) << 1) + 1))
+
+/**********************************************************************
+ * USBD_REEP/USBD_DMARST/USBD_DMARCLR/USBD_DMARSET/USBD_EPDMAST/
+ * USBD_EPDMAEN/USBD_EPDMADIS/
+ * USBD_NDDRTINTST/USBD_NDDRTINTCLR/USBD_NDDRTINTSET/
+ * USBD_EOTINTST/USBD_EOTINTCLR/USBD_EOTINTSET/
+ * USBD_SYSERRTINTST/USBD_SYSERRTINTCLR/USBD_SYSERRTINTSET
+ * register definitions
+ **********************************************************************/
+/* Endpoint selection macro */
+#define USBD_EP_SEL(e)		(1 << (e))
+
+/**********************************************************************
+ * SBD_DMAINTST/USBD_DMAINTEN
+ **********************************************************************/
+#define USBD_SYS_ERR_INT	(1 << 2)
+#define USBD_NEW_DD_INT		(1 << 1)
+#define USBD_EOT_INT		(1 << 0)
+
+/**********************************************************************
+ * USBD_RXPLEN register definitions
+ **********************************************************************/
+#define USBD_PKT_RDY		(1 << 11)
+#define USBD_DV			(1 << 10)
+#define USBD_PK_LEN_MASK	0x3FF
+
+/**********************************************************************
+ * USBD_CTRL register definitions
+ **********************************************************************/
+#define USBD_LOG_ENDPOINT(e)	((e) << 2)
+#define USBD_WR_EN		(1 << 1)
+#define USBD_RD_EN		(1 << 0)
+
+/**********************************************************************
+ * USBD_CMDCODE register definitions
+ **********************************************************************/
+#define USBD_CMD_CODE(c)	((c) << 16)
+#define USBD_CMD_PHASE(p)	((p) << 8)
+
+/**********************************************************************
+ * USBD_DMARST/USBD_DMARCLR/USBD_DMARSET register definitions
+ **********************************************************************/
+#define USBD_DMAEP(e)		(1 << (e))
+
+/* DD (DMA Descriptor) structure, requires word alignment */
+struct lpc32xx_usbd_dd {
+	u32 *dd_next;
+	u32 dd_setup;
+	u32 dd_buffer_addr;
+	u32 dd_status;
+	u32 dd_iso_ps_mem_addr;
+};
+
+/* dd_setup bit defines */
+#define DD_SETUP_ATLE_DMA_MODE	0x01
+#define DD_SETUP_NEXT_DD_VALID	0x04
+#define DD_SETUP_ISO_EP		0x10
+#define DD_SETUP_PACKETLEN(n)	(((n) & 0x7FF) << 5)
+#define DD_SETUP_DMALENBYTES(n)	(((n) & 0xFFFF) << 16)
+
+/* dd_status bit defines */
+#define DD_STATUS_DD_RETIRED	0x01
+#define DD_STATUS_STS_MASK	0x1E
+#define DD_STATUS_STS_NS	0x00 /* Not serviced */
+#define DD_STATUS_STS_BS	0x02 /* Being serviced */
+#define DD_STATUS_STS_NC	0x04 /* Normal completion */
+#define DD_STATUS_STS_DUR	0x06 /* Data underrun (short packet) */
+#define DD_STATUS_STS_DOR	0x08 /* Data overrun */
+#define DD_STATUS_STS_SE	0x12 /* System error */
+#define DD_STATUS_PKT_VAL	0x20 /* Packet valid */
+#define DD_STATUS_LSB_EX	0x40 /* LS byte extracted (ATLE) */
+#define DD_STATUS_MSB_EX	0x80 /* MS byte extracted (ATLE) */
+#define DD_STATUS_MLEN(n)	(((n) >> 8) & 0x3F)
+#define DD_STATUS_CURDMACNT(n)	(((n) >> 16) & 0xFFFF)
+
+/*
+ *
+ * Protocol engine bits below
+ *
+ */
+/* Device Interrupt Bit Definitions */
+#define FRAME_INT		0x00000001
+#define EP_FAST_INT		0x00000002
+#define EP_SLOW_INT		0x00000004
+#define DEV_STAT_INT		0x00000008
+#define CCEMTY_INT		0x00000010
+#define CDFULL_INT		0x00000020
+#define RxENDPKT_INT		0x00000040
+#define TxENDPKT_INT		0x00000080
+#define EP_RLZED_INT		0x00000100
+#define ERR_INT			0x00000200
+
+/* Rx & Tx Packet Length Definitions */
+#define PKT_LNGTH_MASK		0x000003FF
+#define PKT_DV			0x00000400
+#define PKT_RDY			0x00000800
+
+/* USB Control Definitions */
+#define CTRL_RD_EN		0x00000001
+#define CTRL_WR_EN		0x00000002
+
+/* Command Codes */
+#define CMD_SET_ADDR		0x00D00500
+#define CMD_CFG_DEV		0x00D80500
+#define CMD_SET_MODE		0x00F30500
+#define CMD_RD_FRAME		0x00F50500
+#define DAT_RD_FRAME		0x00F50200
+#define CMD_RD_TEST		0x00FD0500
+#define DAT_RD_TEST		0x00FD0200
+#define CMD_SET_DEV_STAT	0x00FE0500
+#define CMD_GET_DEV_STAT	0x00FE0500
+#define DAT_GET_DEV_STAT	0x00FE0200
+#define CMD_GET_ERR_CODE	0x00FF0500
+#define DAT_GET_ERR_CODE	0x00FF0200
+#define CMD_RD_ERR_STAT		0x00FB0500
+#define DAT_RD_ERR_STAT		0x00FB0200
+#define DAT_WR_BYTE(x)		(0x00000100 | ((x) << 16))
+#define CMD_SEL_EP(x)		(0x00000500 | ((x) << 16))
+#define DAT_SEL_EP(x)		(0x00000200 | ((x) << 16))
+#define CMD_SEL_EP_CLRI(x)	(0x00400500 | ((x) << 16))
+#define DAT_SEL_EP_CLRI(x)	(0x00400200 | ((x) << 16))
+#define CMD_SET_EP_STAT(x)	(0x00400500 | ((x) << 16))
+#define CMD_CLR_BUF		0x00F20500
+#define DAT_CLR_BUF		0x00F20200
+#define CMD_VALID_BUF		0x00FA0500
+
+/* Device Address Register Definitions */
+#define DEV_ADDR_MASK		0x7F
+#define DEV_EN			0x80
+
+/* Device Configure Register Definitions */
+#define CONF_DVICE		0x01
+
+/* Device Mode Register Definitions */
+#define AP_CLK			0x01
+#define INAK_CI			0x02
+#define INAK_CO			0x04
+#define INAK_II			0x08
+#define INAK_IO			0x10
+#define INAK_BI			0x20
+#define INAK_BO			0x40
+
+/* Device Status Register Definitions */
+#define DEV_CON			0x01
+#define DEV_CON_CH		0x02
+#define DEV_SUS			0x04
+#define DEV_SUS_CH		0x08
+#define DEV_RST			0x10
+
+/* Error Code Register Definitions */
+#define ERR_EC_MASK		0x0F
+#define ERR_EA			0x10
+
+/* Error Status Register Definitions */
+#define ERR_PID			0x01
+#define ERR_UEPKT		0x02
+#define ERR_DCRC		0x04
+#define ERR_TIMOUT		0x08
+#define ERR_EOP			0x10
+#define ERR_B_OVRN		0x20
+#define ERR_BTSTF		0x40
+#define ERR_TGL			0x80
+
+/* Endpoint Select Register Definitions */
+#define EP_SEL_F		0x01
+#define EP_SEL_ST		0x02
+#define EP_SEL_STP		0x04
+#define EP_SEL_PO		0x08
+#define EP_SEL_EPN		0x10
+#define EP_SEL_B_1_FULL		0x20
+#define EP_SEL_B_2_FULL		0x40
+
+/* Endpoint Status Register Definitions */
+#define EP_STAT_ST		0x01
+#define EP_STAT_DA		0x20
+#define EP_STAT_RF_MO		0x40
+#define EP_STAT_CND_ST		0x80
+
+/* Clear Buffer Register Definitions */
+#define CLR_BUF_PO		0x01
+
+/* DMA Interrupt Bit Definitions */
+#define EOT_INT			0x01
+#define NDD_REQ_INT		0x02
+#define SYS_ERR_INT		0x04
+
+#define	DRIVER_VERSION	"1.03"
+static const char driver_name[] = "lpc32xx_udc";
+
+/*
+ *
+ * proc interface support
+ *
+ */
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+static char *epnames[] = {"INT", "ISO", "BULK", "CTRL"};
+static const char debug_filename[] = "driver/udc";
+
+static void proc_ep_show(struct seq_file *s, struct lpc32xx_ep *ep)
+{
+	struct lpc32xx_request *req;
+
+	seq_printf(s, "\n");
+	seq_printf(s, "%12s, maxpacket %4d %3s",
+			ep->ep.name, ep->ep.maxpacket,
+			ep->is_in ? "in" : "out");
+	seq_printf(s, " type %4s", epnames[ep->eptype]);
+	seq_printf(s, " ints: %12d", ep->totalints);
+
+	if (list_empty(&ep->queue))
+		seq_printf(s, "\t(queue empty)\n");
+	else {
+		list_for_each_entry(req, &ep->queue, queue) {
+			u32 length = req->req.actual;
+
+			seq_printf(s, "\treq %p len %d/%d buf %p\n",
+				   &req->req, length,
+				   req->req.length, req->req.buf);
+		}
+	}
+}
+
+static int proc_udc_show(struct seq_file *s, void *unused)
+{
+	struct lpc32xx_udc *udc = s->private;
+	struct lpc32xx_ep *ep;
+	unsigned long flags;
+
+	seq_printf(s, "%s: version %s\n", driver_name, DRIVER_VERSION);
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	seq_printf(s, "vbus %s, pullup %s, %s powered%s, gadget %s\n\n",
+		   udc->vbus ? "present" : "off",
+		   udc->enabled ? (udc->vbus ? "active" : "enabled") :
+		   "disabled",
+		   udc->selfpowered ? "self" : "VBUS",
+		   udc->suspended ? ", suspended" : "",
+		   udc->driver ? udc->driver->driver.name : "(none)");
+
+	if (udc->enabled && udc->vbus) {
+		proc_ep_show(s, &udc->ep[0]);
+		list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
+			if (ep->desc)
+				proc_ep_show(s, ep);
+		}
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int proc_udc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_udc_show, PDE(inode)->data);
+}
+
+static const struct file_operations proc_ops = {
+	.owner		= THIS_MODULE,
+	.open		= proc_udc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static void create_debug_file(struct lpc32xx_udc *udc)
+{
+	udc->pde = debugfs_create_file(debug_filename, 0, NULL, udc, &proc_ops);
+}
+
+static void remove_debug_file(struct lpc32xx_udc *udc)
+{
+	if (udc->pde)
+		debugfs_remove(udc->pde);
+}
+
+#else
+static inline void create_debug_file(struct lpc32xx_udc *udc) {}
+static inline void remove_debug_file(struct lpc32xx_udc *udc) {}
+#endif
+
+/* Primary initialization sequence for the ISP1301 transceiver */
+static void isp1301_udc_configure(struct lpc32xx_udc *udc)
+{
+	/* LPC32XX only supports DAT_SE0 USB mode */
+	/* This sequence is important */
+
+	/* Disable transparent UART mode first */
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		(ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR),
+		MC1_UART_EN);
+
+	/* Set full speed and SE0 mode */
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		(ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), ~0);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_MODE_CONTROL_1, (MC1_SPEED_REG | MC1_DAT_SE0));
+
+	/*
+	 * The PSW_OE enable bit state is reversed in the ISP1301 User's Guide
+	 */
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		(ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR), ~0);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_SPD_SUSP_CTRL));
+
+	/* Driver VBUS_DRV high or low depending on board setup */
+	if (udc->board->vbus_drv_pol != 0)
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
+	else
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR,
+			OTG1_VBUS_DRV);
+
+	/* Bi-directional mode with suspend control
+	 * Enable both pulldowns for now - the pullup will be enable when VBUS
+	 * is detected */
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		(ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR), ~0);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_OTG_CONTROL_1,
+		(0 | OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN));
+
+	/* Discharge VBUS (just in case) */
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DISCHRG);
+	msleep(1);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		(ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR),
+		OTG1_VBUS_DISCHRG);
+
+	/* Clear and enable VBUS high edge interrupt */
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_INTERRUPT_FALLING, INT_VBUS_VLD);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
+	i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+		ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD);
+
+	/* Enable usb_need_clk clock after transceiver is initialized */
+	writel((readl(USB_CTRL) | (1 << 22)), USB_CTRL);
+
+	dev_info(udc->dev, "ISP1301 Vendor ID  : 0x%04x\n",
+		 i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00));
+	dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n",
+		 i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02));
+	dev_info(udc->dev, "ISP1301 Version ID : 0x%04x\n",
+		 i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x14));
+}
+
+/* Enables or disables the USB device pullup via the ISP1301 transceiver */
+static void isp1301_pullup_set(struct lpc32xx_udc *udc)
+{
+	if (udc->pullup)
+		/* Enable pullup for bus signalling */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_OTG_CONTROL_1, OTG1_DP_PULLUP);
+	else
+		/* Enable pullup for bus signalling */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR,
+			OTG1_DP_PULLUP);
+}
+
+static void pullup_work(struct work_struct *work)
+{
+	struct lpc32xx_udc *udc =
+		container_of(work, struct lpc32xx_udc, pullup_job);
+
+	isp1301_pullup_set(udc);
+}
+
+static void isp1301_pullup_enable(struct lpc32xx_udc *udc, int en_pullup,
+				  int block)
+{
+	if (en_pullup == udc->pullup)
+		return;
+
+	udc->pullup = en_pullup;
+	if (block)
+		isp1301_pullup_set(udc);
+	else
+		/* defer slow i2c pull up setting */
+		schedule_work(&udc->pullup_job);
+}
+
+#ifdef CONFIG_PM
+/* Powers up or down the ISP1301 transceiver */
+static void isp1301_set_powerstate(struct lpc32xx_udc *udc, int enable)
+{
+	if (enable != 0)
+		/* Power up ISP1301 - this ISP1301 will automatically wakeup
+		   when VBUS is detected */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR,
+			MC2_GLOBAL_PWR_DN);
+	else
+		/* Power down ISP1301 */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
+}
+
+static void power_work(struct work_struct *work)
+{
+	struct lpc32xx_udc *udc =
+		container_of(work, struct lpc32xx_udc, power_job);
+
+	isp1301_set_powerstate(udc, udc->poweron);
+}
+#endif
+
+/*
+ *
+ * USB protocol engine command/data read/write helper functions
+ *
+ */
+/* Issues a single command to the USB device state machine */
+static void udc_protocol_cmd_w(struct lpc32xx_udc *udc, u32 cmd)
+{
+	u32 pass = 0;
+	int to;
+
+	/* EP may lock on CLRI if this read isn't done */
+	u32 tmp = readl(USBD_DEVINTST(udc->udp_baseaddr));
+	(void) tmp;
+
+	while (pass == 0) {
+		writel(USBD_CCEMPTY, USBD_DEVINTCLR(udc->udp_baseaddr));
+
+		/* Write command code */
+		writel(cmd, USBD_CMDCODE(udc->udp_baseaddr));
+		to = 10000;
+		while (((readl(USBD_DEVINTST(udc->udp_baseaddr)) &
+			 USBD_CCEMPTY) == 0) && (to > 0)) {
+			to--;
+		}
+
+		if (to > 0)
+			pass = 1;
+
+		cpu_relax();
+	}
+}
+
+/* Issues 2 commands (or command and data) to the USB device state machine */
+static inline void udc_protocol_cmd_data_w(struct lpc32xx_udc *udc, u32 cmd,
+					   u32 data)
+{
+	udc_protocol_cmd_w(udc, cmd);
+	udc_protocol_cmd_w(udc, data);
+}
+
+/* Issues a single command to the USB device state machine and reads
+ * response data */
+static u32 udc_protocol_cmd_r(struct lpc32xx_udc *udc, u32 cmd)
+{
+	u32 tmp;
+	int to = 1000;
+
+	/* Write a command and read data from the protocol engine */
+	writel((USBD_CDFULL | USBD_CCEMPTY),
+		     USBD_DEVINTCLR(udc->udp_baseaddr));
+
+	/* Write command code */
+	udc_protocol_cmd_w(udc, cmd);
+
+	tmp = readl(USBD_DEVINTST(udc->udp_baseaddr));
+	while ((!(readl(USBD_DEVINTST(udc->udp_baseaddr)) & USBD_CDFULL))
+	       && (to > 0))
+		to--;
+	if (!to)
+		dev_dbg(udc->dev,
+			"Protocol engine didn't receive response (CDFULL)\n");
+
+	return readl(USBD_CMDDATA(udc->udp_baseaddr));
+}
+
+/*
+ *
+ * USB device interrupt mask support functions
+ *
+ */
+/* Enable one or more USB device interrupts */
+static inline void uda_enable_devint(struct lpc32xx_udc *udc, u32 devmask)
+{
+	udc->enabled_devints |= devmask;
+	writel(udc->enabled_devints, USBD_DEVINTEN(udc->udp_baseaddr));
+}
+
+/* Disable one or more USB device interrupts */
+static inline void uda_disable_devint(struct lpc32xx_udc *udc, u32 mask)
+{
+	udc->enabled_devints &= ~mask;
+	writel(udc->enabled_devints, USBD_DEVINTEN(udc->udp_baseaddr));
+}
+
+/* Clear one or more USB device interrupts */
+static inline void uda_clear_devint(struct lpc32xx_udc *udc, u32 mask)
+{
+	writel(mask, USBD_DEVINTCLR(udc->udp_baseaddr));
+}
+
+/*
+ *
+ * Endpoint interrupt disable/enable functions
+ *
+ */
+/* Enable one or more USB endpoint interrupts */
+static void uda_enable_hwepint(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc->enabled_hwepints |= (1 << hwep);
+	writel(udc->enabled_hwepints, USBD_EPINTEN(udc->udp_baseaddr));
+}
+
+/* Disable one or more USB endpoint interrupts */
+static void uda_disable_hwepint(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc->enabled_hwepints &= ~(1 << hwep);
+	writel(udc->enabled_hwepints, USBD_EPINTEN(udc->udp_baseaddr));
+}
+
+/* Clear one or more USB endpoint interrupts */
+static inline void uda_clear_hwepint(struct lpc32xx_udc *udc, u32 hwep)
+{
+	writel((1 << hwep), USBD_EPINTCLR(udc->udp_baseaddr));
+}
+
+/* Enable DMA for the HW channel */
+static inline void udc_ep_dma_enable(struct lpc32xx_udc *udc, u32 hwep)
+{
+	writel((1 << hwep), USBD_EPDMAEN(udc->udp_baseaddr));
+}
+
+/* Disable DMA for the HW channel */
+static inline void udc_ep_dma_disable(struct lpc32xx_udc *udc, u32 hwep)
+{
+	writel((1 << hwep), USBD_EPDMADIS(udc->udp_baseaddr));
+}
+
+/*
+ *
+ * Endpoint realize/unrealize functions
+ *
+ */
+/* Before an endpoint can be used, it needs to be realized
+ * in the USB protocol engine - this realizes the endpoint.
+ * The interrupt (FIFO or DMA) is not enabled with this function */
+static void udc_realize_hwep(struct lpc32xx_udc *udc, u32 hwep,
+			     u32 maxpacket)
+{
+	int to = 1000;
+
+	writel(USBD_EP_RLZED, USBD_DEVINTCLR(udc->udp_baseaddr));
+	writel(hwep, USBD_EPIND(udc->udp_baseaddr));
+	udc->realized_eps |= (1 << hwep);
+	writel(udc->realized_eps, USBD_REEP(udc->udp_baseaddr));
+	writel(maxpacket, USBD_EPMAXPSIZE(udc->udp_baseaddr));
+
+	/* Wait until endpoint is realized in hardware */
+	while ((!(readl(USBD_DEVINTST(udc->udp_baseaddr)) &
+		  USBD_EP_RLZED)) && (to > 0))
+		to--;
+	if (!to)
+		dev_dbg(udc->dev, "EP not correctly realized in hardware\n");
+
+	writel(USBD_EP_RLZED, USBD_DEVINTCLR(udc->udp_baseaddr));
+}
+
+/* Unrealize an EP */
+static void udc_unrealize_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc->realized_eps &= ~(1 << hwep);
+	writel(udc->realized_eps, USBD_REEP(udc->udp_baseaddr));
+}
+
+/*
+ *
+ * Endpoint support functions
+ *
+ */
+/* Select and clear endpoint interrupt */
+static u32 udc_selep_clrint(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_protocol_cmd_w(udc, CMD_SEL_EP_CLRI(hwep));
+	return udc_protocol_cmd_r(udc, DAT_SEL_EP_CLRI(hwep));
+}
+
+/* Disables the endpoint in the USB protocol engine */
+static void udc_disable_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(hwep),
+				DAT_WR_BYTE(EP_STAT_DA));
+}
+
+/* Stalls the endpoint - endpoint will return STALL */
+static void udc_stall_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(hwep),
+				DAT_WR_BYTE(EP_STAT_ST));
+}
+
+/* Clear stall or reset endpoint */
+static void udc_clrstall_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(hwep),
+				DAT_WR_BYTE(0));
+}
+
+/* Select an endpoint for endpoint status, clear, validate */
+static void udc_select_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_protocol_cmd_w(udc, CMD_SEL_EP(hwep));
+}
+
+/*
+ *
+ * Endpoint buffer management functions
+ *
+ */
+/* Clear the current endpoint's buffer */
+static void udc_clr_buffer_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_select_hwep(udc, hwep);
+	udc_protocol_cmd_w(udc, CMD_CLR_BUF);
+}
+
+/* Validate the current endpoint's buffer */
+static void udc_val_buffer_hwep(struct lpc32xx_udc *udc, u32 hwep)
+{
+	udc_select_hwep(udc, hwep);
+	udc_protocol_cmd_w(udc, CMD_VALID_BUF);
+}
+
+static inline u32 udc_clearep_getsts(struct lpc32xx_udc *udc, u32 hwep)
+{
+	/* Clear EP interrupt */
+	uda_clear_hwepint(udc, hwep);
+	return udc_selep_clrint(udc, hwep);
+}
+
+/*
+ *
+ * USB EP DMA support
+ *
+ */
+/* Allocate a DMA Descriptor */
+static struct lpc32xx_usbd_dd_gad *udc_dd_alloc(struct lpc32xx_udc *udc)
+{
+	dma_addr_t			dma;
+	struct lpc32xx_usbd_dd_gad	*dd;
+
+	dd = (struct lpc32xx_usbd_dd_gad *) dma_pool_alloc(
+			udc->dd_cache, (GFP_KERNEL | GFP_DMA), &dma);
+	if (dd)
+		dd->this_dma = dma;
+
+	return dd;
+}
+
+/* Free a DMA Descriptor */
+static void udc_dd_free(struct lpc32xx_udc *udc, struct lpc32xx_usbd_dd_gad *dd)
+{
+	dma_pool_free(udc->dd_cache, dd, dd->this_dma);
+}
+
+/*
+ *
+ * USB setup and shutdown functions
+ *
+ */
+/* Enables or disables most of the USB system clocks when low power mode is
+ * needed. Clocks are typically started on a connection event, and disabled
+ * when a cable is disconnected */
+#define OTGOFF_CLK_MASK (AHB_M_CLOCK_ON | I2C_CLOCK_ON)
+static void udc_clk_set(struct lpc32xx_udc *udc, int enable)
+{
+	int to = 1000;
+
+	if (enable != 0) {
+		if (udc->clocked)
+			return;
+
+		udc->clocked = 1;
+
+		/* 48MHz PLL up */
+		clk_enable(udc->usb_pll_clk);
+
+		/* Enable the USB device clock */
+		writel(readl(USB_CTRL) | USB_DEV_NEED_CLK_EN,
+			     USB_CTRL);
+
+		/* Set to enable all needed USB OTG clocks */
+		writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc));
+
+		while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) !=
+			USB_CLOCK_MASK) && (to > 0))
+			to--;
+		if (!to)
+			dev_dbg(udc->dev, "Cannot enable USB OTG clocking\n");
+	} else {
+		if (!udc->clocked)
+			return;
+
+		udc->clocked = 0;
+
+		/* Never disable the USB_HCLK during normal operation */
+
+		/* 48MHz PLL dpwn */
+		clk_disable(udc->usb_pll_clk);
+
+		/* Enable the USB device clock */
+		writel(readl(USB_CTRL) & ~USB_DEV_NEED_CLK_EN,
+			     USB_CTRL);
+
+		/* Set to enable all needed USB OTG clocks */
+		writel(OTGOFF_CLK_MASK, USB_OTG_CLK_CTRL(udc));
+
+		while (((readl(USB_OTG_CLK_STAT(udc)) &
+			 OTGOFF_CLK_MASK) !=
+			OTGOFF_CLK_MASK) && (to > 0))
+			to--;
+		if (!to)
+			dev_dbg(udc->dev, "Cannot disable USB OTG clocking\n");
+	}
+}
+
+/* Set/reset USB device address */
+static void udc_set_address(struct lpc32xx_udc *udc, u32 addr)
+{
+	/* Address will be latched at the end of the status phase, or
+	   latched immediately if function is called twice */
+	udc_protocol_cmd_data_w(udc, CMD_SET_ADDR,
+				DAT_WR_BYTE(DEV_EN | addr));
+}
+
+/* Setup up a IN request for DMA transfer - this consists of determining the
+ * list of DMA addresses for the transfer, allocating DMA Descriptors,
+ * installing the DD into the UDCA, and then enabling the DMA for that EP */
+static int udc_ep_in_req_dma(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
+{
+	struct lpc32xx_request *req;
+	u32 hwep = ep->hwep_num;
+
+	ep->req_pending = 1;
+
+	/* There will always be a request waiting here */
+	req = list_entry(ep->queue.next, struct lpc32xx_request, queue);
+
+	/* Place the DD Descriptor into the UDCA */
+	udc->udca_v_base[hwep] = req->dd_desc_ptr->this_dma;
+
+	/* Enable DMA and interrupt for the HW EP */
+	udc_ep_dma_enable(udc, hwep);
+
+	/* Clear ZLP if last packet is not of MAXP size */
+	if (req->req.length % ep->ep.maxpacket)
+		req->send_zlp = 0;
+
+	return 0;
+}
+
+/* Setup up a OUT request for DMA transfer - this consists of determining the
+ * list of DMA addresses for the transfer, allocating DMA Descriptors,
+ * installing the DD into the UDCA, and then enabling the DMA for that EP */
+static int udc_ep_out_req_dma(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
+{
+	struct lpc32xx_request *req;
+	u32 hwep = ep->hwep_num;
+
+	ep->req_pending = 1;
+
+	/* There will always be a request waiting here */
+	req = list_entry(ep->queue.next, struct lpc32xx_request, queue);
+
+	/* Place the DD Descriptor into the UDCA */
+	udc->udca_v_base[hwep] = req->dd_desc_ptr->this_dma;
+
+	/* Enable DMA and interrupt for the HW EP */
+	udc_ep_dma_enable(udc, hwep);
+	return 0;
+}
+
+static void udc_disable(struct lpc32xx_udc *udc)
+{
+	u32 i;
+
+	/* Disable device */
+	udc_protocol_cmd_data_w(udc, CMD_CFG_DEV, DAT_WR_BYTE(0));
+	udc_protocol_cmd_data_w(udc, CMD_SET_DEV_STAT, DAT_WR_BYTE(0));
+
+	/* Disable all device interrupts (including EP0) */
+	uda_disable_devint(udc, 0x3FF);
+
+	/* Disable and reset all endpoint interrupts */
+	for (i = 0; i < 32; i++) {
+		uda_disable_hwepint(udc, i);
+		uda_clear_hwepint(udc, i);
+		udc_disable_hwep(udc, i);
+		udc_unrealize_hwep(udc, i);
+		udc->udca_v_base[i] = 0;
+
+		/* Disable and clear all interrupts and DMA */
+		udc_ep_dma_disable(udc, i);
+		writel((1 << i), USBD_EOTINTCLR(udc->udp_baseaddr));
+		writel((1 << i), USBD_NDDRTINTCLR(udc->udp_baseaddr));
+		writel((1 << i), USBD_SYSERRTINTCLR(udc->udp_baseaddr));
+		writel((1 << i), USBD_DMARCLR(udc->udp_baseaddr));
+	}
+
+	/* Disable DMA interrupts */
+	writel(0, USBD_DMAINTEN(udc->udp_baseaddr));
+
+	writel(0, USBD_UDCAH(udc->udp_baseaddr));
+}
+
+static void udc_enable(struct lpc32xx_udc *udc)
+{
+	u32 i;
+	struct lpc32xx_ep *ep = &udc->ep[0];
+
+	/* Start with known state */
+	udc_disable(udc);
+
+	/* Enable device */
+	udc_protocol_cmd_data_w(udc, CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON));
+
+	/* EP interrupts on high priority, FRAME interrupt on low priority */
+	writel(USBD_EP_FAST, USBD_DEVINTPRI(udc->udp_baseaddr));
+	writel(0xFFFF, USBD_EPINTPRI(udc->udp_baseaddr));
+
+	/* Clear any pending device interrupts */
+	writel(0x3FF, USBD_DEVINTCLR(udc->udp_baseaddr));
+
+	/* Setup UDCA - not yet used (DMA) */
+	writel(udc->udca_p_base, USBD_UDCAH(udc->udp_baseaddr));
+
+	/* Only enable EP0 in and out for now, EP0 only works in FIFO mode */
+	for (i = 0; i <= 1; i++) {
+		udc_realize_hwep(udc, i, ep->ep.maxpacket);
+		uda_enable_hwepint(udc, i);
+		udc_select_hwep(udc, i);
+		udc_clrstall_hwep(udc, i);
+		udc_clr_buffer_hwep(udc, i);
+	}
+
+	/* Device interrupt setup */
+	uda_clear_devint(udc, (USBD_ERR_INT | USBD_DEV_STAT | USBD_EP_SLOW |
+			       USBD_EP_FAST));
+	uda_enable_devint(udc, (USBD_ERR_INT | USBD_DEV_STAT | USBD_EP_SLOW |
+				USBD_EP_FAST));
+
+	/* Set device address to 0 - called twice to force a latch in the USB
+	   engine without the need of a setup packet status closure */
+	udc_set_address(udc, 0);
+	udc_set_address(udc, 0);
+
+	/* Enable master DMA interrupts */
+	writel((USBD_SYS_ERR_INT | USBD_EOT_INT),
+		     USBD_DMAINTEN(udc->udp_baseaddr));
+
+	udc->dev_status = 0;
+}
+
+/*
+ *
+ * USB device board specific events handled via callbacks
+ *
+ */
+/* Connection change event - notify board function of change */
+static void uda_power_event(struct lpc32xx_udc *udc, u32 conn)
+{
+	/* Just notify of a connection change event (optional) */
+	if (udc->board->conn_chgb != NULL)
+		udc->board->conn_chgb(conn);
+}
+
+/* Suspend/resume event - notify board function of change */
+static void uda_resm_susp_event(struct lpc32xx_udc *udc, u32 conn)
+{
+	/* Just notify of a Suspend/resume change event (optional) */
+	if (udc->board->susp_chgb != NULL)
+		udc->board->susp_chgb(conn);
+
+	if (conn)
+		udc->suspended = 0;
+	else
+		udc->suspended = 1;
+}
+
+/* Remote wakeup enable/disable - notify board function of change */
+static void uda_remwkp_cgh(struct lpc32xx_udc *udc)
+{
+	if (udc->board->rmwk_chgb != NULL)
+		udc->board->rmwk_chgb(udc->dev_status &
+				      (1 << USB_DEVICE_REMOTE_WAKEUP));
+}
+
+/* Reads data from FIFO, adjusts for alignment and data size */
+static void udc_pop_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes)
+{
+	int n, i, bl;
+	u16 *p16;
+	u32 *p32, tmp, cbytes;
+
+	/* Use optimal data transfer method based on source address and size */
+	switch (((u32) data) & 0x3) {
+	case 0: /* 32-bit aligned */
+		p32 = (u32 *) data;
+		cbytes = (bytes & ~0x3);
+
+		/* Copy 32-bit aligned data first */
+		for (n = 0; n < cbytes; n += 4)
+			*p32++ = readl(USBD_RXDATA(udc->udp_baseaddr));
+
+		/* Handle any remaining bytes */
+		bl = bytes - cbytes;
+		if (bl) {
+			tmp = readl(USBD_RXDATA(udc->udp_baseaddr));
+			for (n = 0; n < bl; n++)
+				data[cbytes + n] = ((tmp >> (n * 8)) & 0xFF);
+
+		}
+		break;
+
+	case 1: /* 8-bit aligned */
+	case 3:
+		/* Each byte has to be handled independently */
+		for (n = 0; n < bytes; n += 4) {
+			tmp = readl(USBD_RXDATA(udc->udp_baseaddr));
+
+			bl = bytes - n;
+			if (bl > 3)
+				bl = 3;
+
+			for (i = 0; i < bl; i++)
+				data[n + i] = (u8) ((tmp >> (n * 8)) & 0xFF);
+		}
+		break;
+
+	case 2: /* 16-bit aligned */
+		p16 = (u16 *) data;
+		cbytes = (bytes & ~0x3);
+
+		/* Copy 32-bit sized objects first with 16-bit alignment */
+		for (n = 0; n < cbytes; n += 4) {
+			tmp = readl(USBD_RXDATA(udc->udp_baseaddr));
+			*p16++ = (u16)(tmp & 0xFFFF);
+			*p16++ = (u16)((tmp >> 16) & 0xFFFF);
+		}
+
+		/* Handle any remaining bytes */
+		bl = bytes - cbytes;
+		if (bl) {
+			tmp = readl(USBD_RXDATA(udc->udp_baseaddr));
+			for (n = 0; n < bl; n++)
+				data[cbytes + n] = ((tmp >> (n * 8)) & 0xFF);
+		}
+		break;
+	}
+}
+
+/* Read data from the FIFO for an endpoint. This function is for endpoints (such
+ * as EP0) that don't use DMA. This function should only be called if a packet
+ * is known to be ready to read for the endpoint. Note that the endpoint must
+ * be selected in the protocol engine prior to this call. */
+static u32 udc_read_hwep(struct lpc32xx_udc *udc, u32 hwep, u32 *data,
+			 u32 bytes)
+{
+	u32 tmpv;
+	int to = 1000;
+	u32 tmp, hwrep = ((hwep & 0x1E) << 1) | CTRL_RD_EN;
+
+	/* Setup read of endpoint */
+	writel(hwrep, USBD_CTRL(udc->udp_baseaddr));
+
+	/* Wait until packet is ready */
+	while ((((tmpv = readl(USBD_RXPLEN(udc->udp_baseaddr))) &
+		 PKT_RDY) == 0)	&& (to > 0))
+		to--;
+	if (!to)
+		dev_dbg(udc->dev, "No packet ready on FIFO EP read\n");
+
+	/* Mask out count */
+	tmp = tmpv & PKT_LNGTH_MASK;
+	if (bytes < tmp)
+		tmp = bytes;
+
+	if ((tmp > 0) && (data != NULL))
+		udc_pop_fifo(udc, (u8 *) data, tmp);
+
+	writel(((hwep & 0x1E) << 1), USBD_CTRL(udc->udp_baseaddr));
+
+	/* Clear the buffer */
+	udc_clr_buffer_hwep(udc, hwep);
+
+	return tmp;
+}
+
+/* Stuffs data into the FIFO, adjusts for alignment and data size */
+static void udc_stuff_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes)
+{
+	int n, i, bl;
+	u16 *p16;
+	u32 *p32, tmp, cbytes;
+
+	/* Use optimal data transfer method based on source address and size */
+	switch (((u32) data) & 0x3) {
+	case 0: /* 32-bit aligned */
+		p32 = (u32 *) data;
+		cbytes = (bytes & ~0x3);
+
+		/* Copy 32-bit aligned data first */
+		for (n = 0; n < cbytes; n += 4)
+			writel(*p32++, USBD_TXDATA(udc->udp_baseaddr));
+
+		/* Handle any remaining bytes */
+		bl = bytes - cbytes;
+		if (bl) {
+			tmp = 0;
+			for (n = 0; n < bl; n++)
+				tmp |= data[cbytes + n] << (n * 8);
+
+			writel(tmp, USBD_TXDATA(udc->udp_baseaddr));
+		}
+		break;
+
+	case 1: /* 8-bit aligned */
+	case 3:
+		/* Each byte has to be handled independently */
+		for (n = 0; n < bytes; n += 4) {
+			bl = bytes - n;
+			if (bl > 4)
+				bl = 4;
+
+			tmp = 0;
+			for (i = 0; i < bl; i++)
+				tmp |= data[n + i] << (i * 8);
+
+			writel(tmp, USBD_TXDATA(udc->udp_baseaddr));
+		}
+		break;
+
+	case 2: /* 16-bit aligned */
+		p16 = (u16 *) data;
+		cbytes = (bytes & ~0x3);
+
+		/* Copy 32-bit aligned data first */
+		for (n = 0; n < cbytes; n += 4) {
+			tmp = *p16++ & 0xFFFF;
+			tmp |= (*p16++ & 0xFFFF) << 16;
+			writel(tmp, USBD_TXDATA(udc->udp_baseaddr));
+		}
+
+		/* Handle any remaining bytes */
+		bl = bytes - cbytes;
+		if (bl) {
+			tmp = 0;
+			for (n = 0; n < bl; n++)
+				tmp |= data[cbytes + n] << (n * 8);
+
+			writel(tmp, USBD_TXDATA(udc->udp_baseaddr));
+		}
+		break;
+	}
+}
+
+/* Write data to the FIFO for an endpoint. This function is for endpoints (such
+ * as EP0) that don't use DMA. Note that the endpoint must be selected in the
+ * protocol engine prior to this call. */
+static void udc_write_hwep(struct lpc32xx_udc *udc, u32 hwep, u32 *data,
+			   u32 bytes)
+{
+	u32 hwwep = ((hwep & 0x1E) << 1) | CTRL_WR_EN;
+
+	if ((bytes > 0) && (data == NULL))
+		return;
+
+	/* Setup write of endpoint */
+	writel(hwwep, USBD_CTRL(udc->udp_baseaddr));
+
+	writel(bytes, USBD_TXPLEN(udc->udp_baseaddr));
+
+	/* Need at least 1 byte to trigger TX */
+	if (bytes == 0)
+		writel(0, USBD_TXDATA(udc->udp_baseaddr));
+	else
+		udc_stuff_fifo(udc, (u8 *) data, bytes);
+
+	writel(((hwep & 0x1E) << 1), USBD_CTRL(udc->udp_baseaddr));
+
+	udc_val_buffer_hwep(udc, hwep);
+}
+
+/* USB device reset - resets USB to a default state with just EP0
+   enabled */
+static void uda_usb_reset(struct lpc32xx_udc *udc)
+{
+	u32 i = 0;
+	/* Re-init device controller and EP0 */
+	udc_enable(udc);
+	udc->gadget.speed = USB_SPEED_FULL;
+
+	for (i = 1; i < NUM_ENDPOINTS; i++) {
+		struct lpc32xx_ep *ep = &udc->ep[i];
+		ep->req_pending = 0;
+	}
+}
+
+/* Send a ZLP on EP0 */
+static void udc_ep0_send_zlp(struct lpc32xx_udc *udc)
+{
+	udc_write_hwep(udc, EP_IN, NULL, 0);
+}
+
+/* Get current frame number */
+static u16 udc_get_current_frame(struct lpc32xx_udc *udc)
+{
+	u16 flo, fhi;
+
+	udc_protocol_cmd_w(udc, CMD_RD_FRAME);
+	flo = (u16) udc_protocol_cmd_r(udc, DAT_RD_FRAME);
+	fhi = (u16) udc_protocol_cmd_r(udc, DAT_RD_FRAME);
+
+	return (fhi << 8) | flo;
+}
+
+/* Set the device as configured - enables all endpoints */
+static inline void udc_set_device_configured(struct lpc32xx_udc *udc)
+{
+	udc_protocol_cmd_data_w(udc, CMD_CFG_DEV, DAT_WR_BYTE(CONF_DVICE));
+}
+
+/* Set the device as unconfigured - disables all endpoints */
+static inline void udc_set_device_unconfigured(struct lpc32xx_udc *udc)
+{
+	udc_protocol_cmd_data_w(udc, CMD_CFG_DEV, DAT_WR_BYTE(0));
+}
+
+/* reinit == restore initial software state */
+static void udc_reinit(struct lpc32xx_udc *udc)
+{
+	u32 i;
+
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+	INIT_LIST_HEAD(&udc->gadget.ep0->ep_list);
+
+	for (i = 0; i < NUM_ENDPOINTS; i++) {
+		struct lpc32xx_ep *ep = &udc->ep[i];
+
+		if (i != 0)
+			list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+		ep->desc = NULL;
+		ep->ep.maxpacket = ep->maxpacket;
+		INIT_LIST_HEAD(&ep->queue);
+		ep->req_pending = 0;
+	}
+
+	udc->ep0state = WAIT_FOR_SETUP;
+}
+
+/* Must be called with lock */
+static void done(struct lpc32xx_ep *ep, struct lpc32xx_request *req, int status)
+{
+	struct lpc32xx_udc *udc = ep->udc;
+
+	list_del_init(&req->queue);
+	if (req->req.status == -EINPROGRESS)
+		req->req.status = status;
+	else
+		status = req->req.status;
+
+	if (ep->lep) {
+		enum dma_data_direction direction;
+
+		if (ep->is_in)
+			direction = DMA_TO_DEVICE;
+		else
+			direction = DMA_FROM_DEVICE;
+
+		if (req->mapped) {
+			dma_unmap_single(ep->udc->gadget.dev.parent,
+					req->req.dma, req->req.length,
+					direction);
+			req->req.dma = 0;
+			req->mapped = 0;
+		} else
+			dma_sync_single_for_cpu(ep->udc->gadget.dev.parent,
+						req->req.dma, req->req.length,
+						direction);
+
+		/* Free DDs */
+		udc_dd_free(udc, req->dd_desc_ptr);
+	}
+
+	if (status && status != -ESHUTDOWN)
+		ep_dbg(ep, "%s done %p, status %d\n", ep->ep.name, req, status);
+
+	ep->req_pending = 0;
+	spin_unlock(&udc->lock);
+	req->req.complete(&ep->ep, &req->req);
+	spin_lock(&udc->lock);
+}
+
+/* Must be called with lock */
+static void nuke(struct lpc32xx_ep *ep, int status)
+{
+	struct lpc32xx_request *req;
+
+	while (!list_empty(&ep->queue)) {
+		req = list_entry(ep->queue.next, struct lpc32xx_request, queue);
+		done(ep, req, status);
+	}
+
+	if (ep->desc && status == -ESHUTDOWN) {
+		uda_disable_hwepint(ep->udc, ep->hwep_num);
+		udc_disable_hwep(ep->udc, ep->hwep_num);
+	}
+}
+
+/* IN endpoint 0 transfer */
+static int udc_ep0_in_req(struct lpc32xx_udc *udc)
+{
+	struct lpc32xx_request *req;
+	struct lpc32xx_ep *ep0 = &udc->ep[0];
+	u32 tsend, ts = 0;
+
+	if (list_empty(&ep0->queue))
+		/* Nothing to send */
+		return 0;
+	else
+		req = list_entry(ep0->queue.next, struct lpc32xx_request,
+				 queue);
+
+	tsend = ts = req->req.length - req->req.actual;
+	if (ts == 0) {
+		/* Send a ZLP */
+		udc_ep0_send_zlp(udc);
+		done(ep0, req, 0);
+		return 1;
+	} else if (ts > ep0->ep.maxpacket)
+		ts = ep0->ep.maxpacket; /* Just send what we can */
+
+	/* Write data to the EP0 FIFO and start transfer */
+	udc_write_hwep(udc, EP_IN, (req->req.buf + req->req.actual), ts);
+
+	/* Increment data pointer */
+	req->req.actual += ts;
+
+	if (tsend >= ep0->ep.maxpacket)
+		return 0; /* Stay in data transfer state */
+
+	/* Transfer request is complete */
+	udc->ep0state = WAIT_FOR_SETUP;
+	done(ep0, req, 0);
+	return 1;
+}
+
+/* OUT endpoint 0 transfer */
+static int udc_ep0_out_req(struct lpc32xx_udc *udc)
+{
+	struct lpc32xx_request *req;
+	struct lpc32xx_ep *ep0 = &udc->ep[0];
+	u32 tr, bufferspace;
+
+	if (list_empty(&ep0->queue))
+		return 0;
+	else
+		req = list_entry(ep0->queue.next, struct lpc32xx_request,
+				 queue);
+
+	if (req) {
+		if (req->req.length == 0) {
+			/* Just dequeue request */
+			done(ep0, req, 0);
+			udc->ep0state = WAIT_FOR_SETUP;
+			return 1;
+		}
+
+		/* Get data from FIFO */
+		bufferspace = req->req.length - req->req.actual;
+		if (bufferspace > ep0->ep.maxpacket)
+			bufferspace = ep0->ep.maxpacket;
+
+		/* Copy data to buffer */
+		prefetchw(req->req.buf + req->req.actual);
+		tr = udc_read_hwep(udc, EP_OUT, req->req.buf + req->req.actual,
+				   bufferspace);
+		req->req.actual += bufferspace;
+
+		if (tr < ep0->ep.maxpacket) {
+			/* This is the last packet */
+			done(ep0, req, 0);
+			udc->ep0state = WAIT_FOR_SETUP;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/* Must be called with lock */
+static void stop_activity(struct lpc32xx_udc *udc)
+{
+	struct usb_gadget_driver *driver = udc->driver;
+	int i;
+
+	if (udc->gadget.speed == USB_SPEED_UNKNOWN)
+		driver = NULL;
+
+	udc->gadget.speed = USB_SPEED_UNKNOWN;
+	udc->suspended = 0;
+
+	for (i = 0; i < NUM_ENDPOINTS; i++) {
+		struct lpc32xx_ep *ep = &udc->ep[i];
+		nuke(ep, -ESHUTDOWN);
+	}
+	if (driver) {
+		spin_unlock(&udc->lock);
+		driver->disconnect(&udc->gadget);
+		spin_lock(&udc->lock);
+	}
+
+	isp1301_pullup_enable(udc, 0, 0);
+	udc_disable(udc);
+	udc_reinit(udc);
+}
+
+/*
+ * Activate or kill host pullup
+ * Can be called with or without lock
+ */
+static void pullup(struct lpc32xx_udc *udc, int is_on)
+{
+	if (!udc->clocked)
+		return;
+
+	if (!udc->enabled || !udc->vbus)
+		is_on = 0;
+
+	if (is_on != udc->pullup)
+		isp1301_pullup_enable(udc, is_on, 0);
+}
+
+/* Must be called without lock */
+static int lpc32xx_ep_disable(struct usb_ep *_ep)
+{
+	struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep);
+	struct lpc32xx_udc *udc = ep->udc;
+	unsigned long	flags;
+
+	if ((ep->hwep_num_base == 0) || (ep->hwep_num == 0))
+		return -EINVAL;
+	spin_lock_irqsave(&udc->lock, flags);
+
+	nuke(ep, -ESHUTDOWN);
+
+	/* restore the endpoint's pristine config */
+	ep->desc = NULL;
+
+	/* Clear all DMA statuses for this EP */
+	udc_ep_dma_disable(udc, ep->hwep_num);
+	writel(1 << ep->hwep_num, USBD_EOTINTCLR(udc->udp_baseaddr));
+	writel(1 << ep->hwep_num, USBD_NDDRTINTCLR(udc->udp_baseaddr));
+	writel(1 << ep->hwep_num, USBD_SYSERRTINTCLR(udc->udp_baseaddr));
+	writel(1 << ep->hwep_num, USBD_DMARCLR(udc->udp_baseaddr));
+
+	/* Remove the DD pointer in the UDCA */
+	udc->udca_v_base[ep->hwep_num] = 0;
+
+	/* Disable and reset endpoint and interrupt */
+	uda_clear_hwepint(udc, ep->hwep_num);
+	udc_unrealize_hwep(udc, ep->hwep_num);
+
+	ep->hwep_num = 0;
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	atomic_dec(&udc->enabled_ep_cnt);
+	wake_up(&udc->ep_disable_wait_queue);
+
+	return 0;
+}
+
+/* Must be called without lock */
+static int lpc32xx_ep_enable(struct usb_ep *_ep,
+			     const struct usb_endpoint_descriptor *desc)
+{
+	struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep);
+	struct lpc32xx_udc *udc = ep->udc;
+	u16 maxpacket;
+	u32 tmp;
+	unsigned long flags;
+
+	/* Verify EP data */
+	if ((!_ep) || (!ep) || (!desc) || (ep->desc) ||
+	    (desc->bDescriptorType != USB_DT_ENDPOINT)) {
+		dev_dbg(udc->dev, "bad ep or descriptor\n");
+		return -EINVAL;
+	}
+	maxpacket = usb_endpoint_maxp(desc);
+	if ((maxpacket == 0) || (maxpacket > ep->maxpacket)) {
+		dev_dbg(udc->dev, "bad ep descriptor's packet size\n");
+		return -EINVAL;
+	}
+
+	/* Don't touch EP0 */
+	if (ep->hwep_num_base == 0) {
+		dev_dbg(udc->dev, "Can't re-enable EP0!!!\n");
+		return -EINVAL;
+	}
+
+	/* Is driver ready? */
+	if ((!udc->driver) || (udc->gadget.speed == USB_SPEED_UNKNOWN)) {
+		dev_dbg(udc->dev, "bogus device state\n");
+		return -ESHUTDOWN;
+	}
+
+	tmp = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+	switch (tmp) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		return -EINVAL;
+
+	case USB_ENDPOINT_XFER_INT:
+		if (maxpacket > ep->maxpacket) {
+			dev_dbg(udc->dev,
+				"Bad INT endpoint maxpacket %d\n", maxpacket);
+			return -EINVAL;
+		}
+		break;
+
+	case USB_ENDPOINT_XFER_BULK:
+		switch (maxpacket) {
+		case 8:
+		case 16:
+		case 32:
+		case 64:
+			break;
+
+		default:
+			dev_dbg(udc->dev,
+				"Bad BULK endpoint maxpacket %d\n", maxpacket);
+			return -EINVAL;
+		}
+		break;
+
+	case USB_ENDPOINT_XFER_ISOC:
+		break;
+	}
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* Initialize endpoint to match the selected descriptor */
+	ep->is_in = (desc->bEndpointAddress & USB_DIR_IN) != 0;
+	ep->desc = desc;
+	ep->ep.maxpacket = maxpacket;
+
+	/* Map hardware endpoint from base and direction */
+	if (ep->is_in)
+		/* IN endpoints are offset 1 from the OUT endpoint */
+		ep->hwep_num = ep->hwep_num_base + EP_IN;
+	else
+		ep->hwep_num = ep->hwep_num_base;
+
+	ep_dbg(ep, "EP enabled: %s, HW:%d, MP:%d IN:%d\n", ep->ep.name,
+	       ep->hwep_num, maxpacket, (ep->is_in == 1));
+
+	/* Realize the endpoint, interrupt is enabled later when
+	 * buffers are queued, IN EPs will NAK until buffers are ready */
+	udc_realize_hwep(udc, ep->hwep_num, ep->ep.maxpacket);
+	udc_clr_buffer_hwep(udc, ep->hwep_num);
+	uda_disable_hwepint(udc, ep->hwep_num);
+	udc_clrstall_hwep(udc, ep->hwep_num);
+
+	/* Clear all DMA statuses for this EP */
+	udc_ep_dma_disable(udc, ep->hwep_num);
+	writel(1 << ep->hwep_num, USBD_EOTINTCLR(udc->udp_baseaddr));
+	writel(1 << ep->hwep_num, USBD_NDDRTINTCLR(udc->udp_baseaddr));
+	writel(1 << ep->hwep_num, USBD_SYSERRTINTCLR(udc->udp_baseaddr));
+	writel(1 << ep->hwep_num, USBD_DMARCLR(udc->udp_baseaddr));
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	atomic_inc(&udc->enabled_ep_cnt);
+	return 0;
+}
+
+/*
+ * Allocate a USB request list
+ * Can be called with or without lock
+ */
+static struct usb_request *lpc32xx_ep_alloc_request(struct usb_ep *_ep,
+						    gfp_t gfp_flags)
+{
+	struct lpc32xx_request *req;
+
+	req = kzalloc(sizeof(struct lpc32xx_request), gfp_flags);
+	if (!req)
+		return NULL;
+
+	INIT_LIST_HEAD(&req->queue);
+	return &req->req;
+}
+
+/*
+ * De-allocate a USB request list
+ * Can be called with or without lock
+ */
+static void lpc32xx_ep_free_request(struct usb_ep *_ep,
+				    struct usb_request *_req)
+{
+	struct lpc32xx_request *req;
+
+	req = container_of(_req, struct lpc32xx_request, req);
+	BUG_ON(!list_empty(&req->queue));
+	kfree(req);
+}
+
+/* Must be called without lock */
+static int lpc32xx_ep_queue(struct usb_ep *_ep,
+			    struct usb_request *_req, gfp_t gfp_flags)
+{
+	struct lpc32xx_request *req;
+	struct lpc32xx_ep *ep;
+	struct lpc32xx_udc *udc;
+	unsigned long flags;
+	int status = 0;
+
+	req = container_of(_req, struct lpc32xx_request, req);
+	ep = container_of(_ep, struct lpc32xx_ep, ep);
+
+	if (!_req || !_req->complete || !_req->buf ||
+	    !list_empty(&req->queue))
+		return -EINVAL;
+
+	udc = ep->udc;
+
+	if (!_ep || (!ep->desc && ep->hwep_num_base != 0)) {
+		dev_dbg(udc->dev, "invalid ep\n");
+		return -EINVAL;
+	}
+
+
+	if ((!udc) || (!udc->driver) ||
+	    (udc->gadget.speed == USB_SPEED_UNKNOWN)) {
+		dev_dbg(udc->dev, "invalid device\n");
+		return -EINVAL;
+	}
+
+	if (ep->lep) {
+		enum dma_data_direction direction;
+		struct lpc32xx_usbd_dd_gad *dd;
+
+		/* Map DMA pointer */
+		if (ep->is_in)
+			direction = DMA_TO_DEVICE;
+		else
+			direction = DMA_FROM_DEVICE;
+
+		if (req->req.dma == 0) {
+			req->req.dma = dma_map_single(
+				ep->udc->gadget.dev.parent,
+				req->req.buf, req->req.length, direction);
+			req->mapped = 1;
+		} else {
+			dma_sync_single_for_device(
+				ep->udc->gadget.dev.parent, req->req.dma,
+				req->req.length, direction);
+			req->mapped = 0;
+		}
+
+		/* For the request, build a list of DDs */
+		dd = udc_dd_alloc(udc);
+		if (!dd) {
+			/* Error allocating DD */
+			return -ENOMEM;
+		}
+		req->dd_desc_ptr = dd;
+
+		/* Setup the DMA descriptor */
+		dd->dd_next_phy = dd->dd_next_v = 0;
+		dd->dd_buffer_addr = req->req.dma;
+		dd->dd_status = 0;
+
+		/* Special handling for ISO EPs */
+		if (ep->eptype == EP_ISO_TYPE) {
+			dd->dd_setup = DD_SETUP_ISO_EP |
+				DD_SETUP_PACKETLEN(0) |
+				DD_SETUP_DMALENBYTES(1);
+			dd->dd_iso_ps_mem_addr = dd->this_dma + 24;
+			if (ep->is_in)
+				dd->iso_status[0] = req->req.length;
+			else
+				dd->iso_status[0] = 0;
+		} else
+			dd->dd_setup = DD_SETUP_PACKETLEN(ep->ep.maxpacket) |
+				DD_SETUP_DMALENBYTES(req->req.length);
+	}
+
+	ep_dbg(ep, "%s queue req %p len %d buf %p (in=%d) z=%d\n", _ep->name,
+	       _req, _req->length, _req->buf, ep->is_in, _req->zero);
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	_req->status = -EINPROGRESS;
+	_req->actual = 0;
+	req->send_zlp = _req->zero;
+
+	/* Kickstart empty queues */
+	if (list_empty(&ep->queue)) {
+		list_add_tail(&req->queue, &ep->queue);
+
+		if (ep->hwep_num_base == 0) {
+			/* Handle expected data direction */
+			if (ep->is_in) {
+				/* IN packet to host */
+				udc->ep0state = DATA_IN;
+				status = udc_ep0_in_req(udc);
+			} else {
+				/* OUT packet from host */
+				udc->ep0state = DATA_OUT;
+				status = udc_ep0_out_req(udc);
+			}
+		} else if (ep->is_in) {
+			/* IN packet to host and kick off transfer */
+			if (!ep->req_pending)
+				udc_ep_in_req_dma(udc, ep);
+		} else
+			/* OUT packet from host and kick off list */
+			if (!ep->req_pending)
+				udc_ep_out_req_dma(udc, ep);
+	} else
+		list_add_tail(&req->queue, &ep->queue);
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return (status < 0) ? status : 0;
+}
+
+/* Must be called without lock */
+static int lpc32xx_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct lpc32xx_ep *ep;
+	struct lpc32xx_request *req;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct lpc32xx_ep, ep);
+	if (!_ep || ep->hwep_num_base == 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	/* make sure it's actually queued on this endpoint */
+	list_for_each_entry(req, &ep->queue, queue) {
+		if (&req->req == _req)
+			break;
+	}
+	if (&req->req != _req) {
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EINVAL;
+	}
+
+	done(ep, req, -ECONNRESET);
+
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	return 0;
+}
+
+/* Must be called without lock */
+static int lpc32xx_ep_set_halt(struct usb_ep *_ep, int value)
+{
+	struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep);
+	struct lpc32xx_udc *udc = ep->udc;
+	unsigned long flags;
+
+	if ((!ep) || (ep->desc == NULL) || (ep->hwep_num <= 1))
+		return -EINVAL;
+
+	/* Don't halt an IN EP */
+	if (ep->is_in)
+		return -EAGAIN;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	if (value == 1) {
+		/* stall */
+		udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(ep->hwep_num),
+					DAT_WR_BYTE(EP_STAT_ST));
+	} else {
+		/* End stall */
+		ep->wedge = 0;
+		udc_protocol_cmd_data_w(udc, CMD_SET_EP_STAT(ep->hwep_num),
+					DAT_WR_BYTE(0));
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+/* set the halt feature and ignores clear requests */
+static int lpc32xx_ep_set_wedge(struct usb_ep *_ep)
+{
+	struct lpc32xx_ep *ep = container_of(_ep, struct lpc32xx_ep, ep);
+
+	if (!_ep || !ep->udc)
+		return -EINVAL;
+
+	ep->wedge = 1;
+
+	return usb_ep_set_halt(_ep);
+}
+
+static const struct usb_ep_ops lpc32xx_ep_ops = {
+	.enable		= lpc32xx_ep_enable,
+	.disable	= lpc32xx_ep_disable,
+	.alloc_request	= lpc32xx_ep_alloc_request,
+	.free_request	= lpc32xx_ep_free_request,
+	.queue		= lpc32xx_ep_queue,
+	.dequeue	= lpc32xx_ep_dequeue,
+	.set_halt	= lpc32xx_ep_set_halt,
+	.set_wedge	= lpc32xx_ep_set_wedge,
+};
+
+/* Send a ZLP on a non-0 IN EP */
+void udc_send_in_zlp(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
+{
+	/* Clear EP status */
+	udc_clearep_getsts(udc, ep->hwep_num);
+
+	/* Send ZLP via FIFO mechanism */
+	udc_write_hwep(udc, ep->hwep_num, NULL, 0);
+}
+
+/*
+ * Handle EP completion for ZLP
+ * This function will only be called when a delayed ZLP needs to be sent out
+ * after a DMA transfer has filled both buffers.
+ */
+void udc_handle_eps(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
+{
+	u32 epstatus;
+	struct lpc32xx_request *req;
+
+	if (ep->hwep_num <= 0)
+		return;
+
+	uda_clear_hwepint(udc, ep->hwep_num);
+
+	/* If this interrupt isn't enabled, return now */
+	if (!(udc->enabled_hwepints & (1 << ep->hwep_num)))
+		return;
+
+	/* Get endpoint status */
+	epstatus = udc_clearep_getsts(udc, ep->hwep_num);
+
+	/*
+	 * This should never happen, but protect against writing to the
+	 * buffer when full.
+	 */
+	if (epstatus & EP_SEL_F)
+		return;
+
+	if (ep->is_in) {
+		udc_send_in_zlp(udc, ep);
+		uda_disable_hwepint(udc, ep->hwep_num);
+	} else
+		return;
+
+	/* If there isn't a request waiting, something went wrong */
+	req = list_entry(ep->queue.next, struct lpc32xx_request, queue);
+	if (req) {
+		done(ep, req, 0);
+
+		/* Start another request if ready */
+		if (!list_empty(&ep->queue)) {
+			if (ep->is_in)
+				udc_ep_in_req_dma(udc, ep);
+			else
+				udc_ep_out_req_dma(udc, ep);
+		} else
+			ep->req_pending = 0;
+	}
+}
+
+
+/* DMA end of transfer completion */
+static void udc_handle_dma_ep(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
+{
+	u32 status, epstatus;
+	struct lpc32xx_request *req;
+	struct lpc32xx_usbd_dd_gad *dd;
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+	ep->totalints++;
+#endif
+
+	req = list_entry(ep->queue.next, struct lpc32xx_request, queue);
+	if (!req) {
+		ep_err(ep, "DMA interrupt on no req!\n");
+		return;
+	}
+	dd = req->dd_desc_ptr;
+
+	/* DMA descriptor should always be retired for this call */
+	if (!(dd->dd_status & DD_STATUS_DD_RETIRED))
+		ep_warn(ep, "DMA descriptor did not retire\n");
+
+	/* Disable DMA */
+	udc_ep_dma_disable(udc, ep->hwep_num);
+	writel((1 << ep->hwep_num), USBD_EOTINTCLR(udc->udp_baseaddr));
+	writel((1 << ep->hwep_num), USBD_NDDRTINTCLR(udc->udp_baseaddr));
+
+	/* System error? */
+	if (readl(USBD_SYSERRTINTST(udc->udp_baseaddr)) &
+	    (1 << ep->hwep_num)) {
+		writel((1 << ep->hwep_num),
+			     USBD_SYSERRTINTCLR(udc->udp_baseaddr));
+		ep_err(ep, "AHB critical error!\n");
+		ep->req_pending = 0;
+
+		/* The error could have occurred on a packet of a multipacket
+		 * transfer, so recovering the transfer is not possible. Close
+		 * the request with an error */
+		done(ep, req, -ECONNABORTED);
+		return;
+	}
+
+	/* Handle the current DD's status */
+	status = dd->dd_status;
+	switch (status & DD_STATUS_STS_MASK) {
+	case DD_STATUS_STS_NS:
+		/* DD not serviced? This shouldn't happen! */
+		ep->req_pending = 0;
+		ep_err(ep, "DMA critical EP error: DD not serviced (0x%x)!\n",
+		       status);
+
+		done(ep, req, -ECONNABORTED);
+		return;
+
+	case DD_STATUS_STS_BS:
+		/* Interrupt only fires on EOT - This shouldn't happen! */
+		ep->req_pending = 0;
+		ep_err(ep, "DMA critical EP error: EOT prior to service completion (0x%x)!\n",
+		       status);
+		done(ep, req, -ECONNABORTED);
+		return;
+
+	case DD_STATUS_STS_NC:
+	case DD_STATUS_STS_DUR:
+		/* Really just a short packet, not an underrun */
+		/* This is a good status and what we expect */
+		break;
+
+	default:
+		/* Data overrun, system error, or unknown */
+		ep->req_pending = 0;
+		ep_err(ep, "DMA critical EP error: System error (0x%x)!\n",
+		       status);
+		done(ep, req, -ECONNABORTED);
+		return;
+	}
+
+	/* ISO endpoints are handled differently */
+	if (ep->eptype == EP_ISO_TYPE) {
+		if (ep->is_in)
+			req->req.actual = req->req.length;
+		else
+			req->req.actual = dd->iso_status[0] & 0xFFFF;
+	} else
+		req->req.actual += DD_STATUS_CURDMACNT(status);
+
+	/* Send a ZLP if necessary. This will be done for non-int
+	 * packets which have a size that is a divisor of MAXP */
+	if (req->send_zlp) {
+		/*
+		 * If at least 1 buffer is available, send the ZLP now.
+		 * Otherwise, the ZLP send needs to be deferred until a
+		 * buffer is available.
+		 */
+		if (udc_clearep_getsts(udc, ep->hwep_num) & EP_SEL_F) {
+			udc_clearep_getsts(udc, ep->hwep_num);
+			uda_enable_hwepint(udc, ep->hwep_num);
+			epstatus = udc_clearep_getsts(udc, ep->hwep_num);
+
+			/* Let the EP interrupt handle the ZLP */
+			return;
+		} else
+			udc_send_in_zlp(udc, ep);
+	}
+
+	/* Transfer request is complete */
+	done(ep, req, 0);
+
+	/* Start another request if ready */
+	udc_clearep_getsts(udc, ep->hwep_num);
+	if (!list_empty((&ep->queue))) {
+		if (ep->is_in)
+			udc_ep_in_req_dma(udc, ep);
+		else
+			udc_ep_out_req_dma(udc, ep);
+	} else
+		ep->req_pending = 0;
+
+}
+
+/*
+ *
+ * Endpoint 0 functions
+ *
+ */
+static void udc_handle_dev(struct lpc32xx_udc *udc)
+{
+	u32 tmp;
+
+	udc_protocol_cmd_w(udc, CMD_GET_DEV_STAT);
+	tmp = udc_protocol_cmd_r(udc, DAT_GET_DEV_STAT);
+
+	if (tmp & DEV_RST)
+		uda_usb_reset(udc);
+	else if (tmp & DEV_CON_CH)
+		uda_power_event(udc, (tmp & DEV_CON));
+	else if (tmp & DEV_SUS_CH) {
+		if (tmp & DEV_SUS) {
+			if (udc->vbus == 0)
+				stop_activity(udc);
+			else if ((udc->gadget.speed != USB_SPEED_UNKNOWN) &&
+				 udc->driver) {
+				/* Power down transceiver */
+				udc->poweron = 0;
+				schedule_work(&udc->pullup_job);
+				uda_resm_susp_event(udc, 1);
+			}
+		} else if ((udc->gadget.speed != USB_SPEED_UNKNOWN) &&
+			   udc->driver && udc->vbus) {
+			uda_resm_susp_event(udc, 0);
+			/* Power up transceiver */
+			udc->poweron = 1;
+			schedule_work(&udc->pullup_job);
+		}
+	}
+}
+
+static int udc_get_status(struct lpc32xx_udc *udc, u16 reqtype, u16 wIndex)
+{
+	struct lpc32xx_ep *ep;
+	u32 ep0buff = 0, tmp;
+
+	switch (reqtype & USB_RECIP_MASK) {
+	case USB_RECIP_INTERFACE:
+		break; /* Not supported */
+
+	case USB_RECIP_DEVICE:
+		ep0buff = (udc->selfpowered << USB_DEVICE_SELF_POWERED);
+		if (udc->dev_status & (1 << USB_DEVICE_REMOTE_WAKEUP))
+			ep0buff |= (1 << USB_DEVICE_REMOTE_WAKEUP);
+		break;
+
+	case USB_RECIP_ENDPOINT:
+		tmp = wIndex & USB_ENDPOINT_NUMBER_MASK;
+		ep = &udc->ep[tmp];
+		if ((tmp == 0) || (tmp >= NUM_ENDPOINTS) || (tmp && !ep->desc))
+			return -EOPNOTSUPP;
+
+		if (wIndex & USB_DIR_IN) {
+			if (!ep->is_in)
+				return -EOPNOTSUPP; /* Something's wrong */
+		} else if (ep->is_in)
+			return -EOPNOTSUPP; /* Not an IN endpoint */
+
+		/* Get status of the endpoint */
+		udc_protocol_cmd_w(udc, CMD_SEL_EP(ep->hwep_num));
+		tmp = udc_protocol_cmd_r(udc, DAT_SEL_EP(ep->hwep_num));
+
+		if (tmp & EP_SEL_ST)
+			ep0buff = (1 << USB_ENDPOINT_HALT);
+		else
+			ep0buff = 0;
+		break;
+
+	default:
+		break;
+	}
+
+	/* Return data */
+	udc_write_hwep(udc, EP_IN, &ep0buff, 2);
+
+	return 0;
+}
+
+static void udc_handle_ep0_setup(struct lpc32xx_udc *udc)
+{
+	struct lpc32xx_ep *ep, *ep0 = &udc->ep[0];
+	struct usb_ctrlrequest ctrlpkt;
+	int i, bytes;
+	u16 wIndex, wValue, wLength, reqtype, req, tmp;
+
+	/* Nuke previous transfers */
+	nuke(ep0, -EPROTO);
+
+	/* Get setup packet */
+	bytes = udc_read_hwep(udc, EP_OUT, (u32 *) &ctrlpkt, 8);
+	if (bytes != 8) {
+		ep_warn(ep0, "Incorrectly sized setup packet (s/b 8, is %d)!\n",
+			bytes);
+		return;
+	}
+
+	/* Native endianness */
+	wIndex = le16_to_cpu(ctrlpkt.wIndex);
+	wValue = le16_to_cpu(ctrlpkt.wValue);
+	wLength = le16_to_cpu(ctrlpkt.wLength);
+	reqtype = le16_to_cpu(ctrlpkt.bRequestType);
+
+	/* Set direction of EP0 */
+	if (likely(reqtype & USB_DIR_IN))
+		ep0->is_in = 1;
+	else
+		ep0->is_in = 0;
+
+	/* Handle SETUP packet */
+	req = le16_to_cpu(ctrlpkt.bRequest);
+	switch (req) {
+	case USB_REQ_CLEAR_FEATURE:
+	case USB_REQ_SET_FEATURE:
+		switch (reqtype) {
+		case (USB_TYPE_STANDARD | USB_RECIP_DEVICE):
+			if (wValue != USB_DEVICE_REMOTE_WAKEUP)
+				goto stall; /* Nothing else handled */
+
+			/* Tell board about event */
+			if (req == USB_REQ_CLEAR_FEATURE)
+				udc->dev_status &=
+					~(1 << USB_DEVICE_REMOTE_WAKEUP);
+			else
+				udc->dev_status |=
+					(1 << USB_DEVICE_REMOTE_WAKEUP);
+			uda_remwkp_cgh(udc);
+			goto zlp_send;
+
+		case (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
+			tmp = wIndex & USB_ENDPOINT_NUMBER_MASK;
+			if ((wValue != USB_ENDPOINT_HALT) ||
+			    (tmp >= NUM_ENDPOINTS))
+				break;
+
+			/* Find hardware endpoint from logical endpoint */
+			ep = &udc->ep[tmp];
+			tmp = ep->hwep_num;
+			if (tmp == 0)
+				break;
+
+			if (req == USB_REQ_SET_FEATURE)
+				udc_stall_hwep(udc, tmp);
+			else if (!ep->wedge)
+				udc_clrstall_hwep(udc, tmp);
+
+			goto zlp_send;
+
+		default:
+			break;
+		}
+
+
+	case USB_REQ_SET_ADDRESS:
+		if (reqtype == (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) {
+			udc_set_address(udc, wValue);
+			goto zlp_send;
+		}
+		break;
+
+	case USB_REQ_GET_STATUS:
+		udc_get_status(udc, reqtype, wIndex);
+		return;
+
+	default:
+		break; /* Let GadgetFS handle the descriptor instead */
+	}
+
+	if (likely(udc->driver)) {
+		/* device-2-host (IN) or no data setup command, process
+		 * immediately */
+		spin_unlock(&udc->lock);
+		i = udc->driver->setup(&udc->gadget, &ctrlpkt);
+
+		spin_lock(&udc->lock);
+		if (req == USB_REQ_SET_CONFIGURATION) {
+			/* Configuration is set after endpoints are realized */
+			if (wValue) {
+				/* Set configuration */
+				udc_set_device_configured(udc);
+
+				udc_protocol_cmd_data_w(udc, CMD_SET_MODE,
+							DAT_WR_BYTE(AP_CLK |
+							INAK_BI | INAK_II));
+			} else {
+				/* Clear configuration */
+				udc_set_device_unconfigured(udc);
+
+				/* Disable NAK interrupts */
+				udc_protocol_cmd_data_w(udc, CMD_SET_MODE,
+							DAT_WR_BYTE(AP_CLK));
+			}
+		}
+
+		if (i < 0) {
+			/* setup processing failed, force stall */
+			dev_err(udc->dev,
+				"req %02x.%02x protocol STALL; stat %d\n",
+				reqtype, req, i);
+			udc->ep0state = WAIT_FOR_SETUP;
+			goto stall;
+		}
+	}
+
+	if (!ep0->is_in)
+		udc_ep0_send_zlp(udc); /* ZLP IN packet on data phase */
+
+	return;
+
+stall:
+	udc_stall_hwep(udc, EP_IN);
+	return;
+
+zlp_send:
+	udc_ep0_send_zlp(udc);
+	return;
+}
+
+/* IN endpoint 0 transfer */
+static void udc_handle_ep0_in(struct lpc32xx_udc *udc)
+{
+	struct lpc32xx_ep *ep0 = &udc->ep[0];
+	u32 epstatus;
+
+	/* Clear EP interrupt */
+	epstatus = udc_clearep_getsts(udc, EP_IN);
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+	ep0->totalints++;
+#endif
+
+	/* Stalled? Clear stall and reset buffers */
+	if (epstatus & EP_SEL_ST) {
+		udc_clrstall_hwep(udc, EP_IN);
+		nuke(ep0, -ECONNABORTED);
+		udc->ep0state = WAIT_FOR_SETUP;
+		return;
+	}
+
+	/* Is a buffer available? */
+	if (!(epstatus & EP_SEL_F)) {
+		/* Handle based on current state */
+		if (udc->ep0state == DATA_IN)
+			udc_ep0_in_req(udc);
+		else {
+			/* Unknown state for EP0 oe end of DATA IN phase */
+			nuke(ep0, -ECONNABORTED);
+			udc->ep0state = WAIT_FOR_SETUP;
+		}
+	}
+}
+
+/* OUT endpoint 0 transfer */
+static void udc_handle_ep0_out(struct lpc32xx_udc *udc)
+{
+	struct lpc32xx_ep *ep0 = &udc->ep[0];
+	u32 epstatus;
+
+	/* Clear EP interrupt */
+	epstatus = udc_clearep_getsts(udc, EP_OUT);
+
+
+#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+	ep0->totalints++;
+#endif
+
+	/* Stalled? */
+	if (epstatus & EP_SEL_ST) {
+		udc_clrstall_hwep(udc, EP_OUT);
+		nuke(ep0, -ECONNABORTED);
+		udc->ep0state = WAIT_FOR_SETUP;
+		return;
+	}
+
+	/* A NAK may occur if a packet couldn't be received yet */
+	if (epstatus & EP_SEL_EPN)
+		return;
+	/* Setup packet incoming? */
+	if (epstatus & EP_SEL_STP) {
+		nuke(ep0, 0);
+		udc->ep0state = WAIT_FOR_SETUP;
+	}
+
+	/* Data available? */
+	if (epstatus & EP_SEL_F)
+		/* Handle based on current state */
+		switch (udc->ep0state) {
+		case WAIT_FOR_SETUP:
+			udc_handle_ep0_setup(udc);
+			break;
+
+		case DATA_OUT:
+			udc_ep0_out_req(udc);
+			break;
+
+		default:
+			/* Unknown state for EP0 */
+			nuke(ep0, -ECONNABORTED);
+			udc->ep0state = WAIT_FOR_SETUP;
+		}
+}
+
+/* Must be called without lock */
+static int lpc32xx_get_frame(struct usb_gadget *gadget)
+{
+	int frame;
+	unsigned long flags;
+	struct lpc32xx_udc *udc = to_udc(gadget);
+
+	if (!udc->clocked)
+		return -EINVAL;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	frame = (int) udc_get_current_frame(udc);
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return frame;
+}
+
+static int lpc32xx_wakeup(struct usb_gadget *gadget)
+{
+	return -ENOTSUPP;
+}
+
+static int lpc32xx_set_selfpowered(struct usb_gadget *gadget, int is_on)
+{
+	struct lpc32xx_udc *udc = to_udc(gadget);
+
+	/* Always self-powered */
+	udc->selfpowered = (is_on != 0);
+
+	return 0;
+}
+
+/*
+ * vbus is here!  turn everything on that's ready
+ * Must be called without lock
+ */
+static int lpc32xx_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+	unsigned long flags;
+	struct lpc32xx_udc *udc = to_udc(gadget);
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* Doesn't need lock */
+	if (udc->driver) {
+		udc_clk_set(udc, 1);
+		udc_enable(udc);
+		pullup(udc, is_active);
+	} else {
+		stop_activity(udc);
+		pullup(udc, 0);
+
+		spin_unlock_irqrestore(&udc->lock, flags);
+		/*
+		 *  Wait for all the endpoints to disable,
+		 *  before disabling clocks. Don't wait if
+		 *  endpoints are not enabled.
+		 */
+		if (atomic_read(&udc->enabled_ep_cnt))
+			wait_event_interruptible(udc->ep_disable_wait_queue,
+				 (atomic_read(&udc->enabled_ep_cnt) == 0));
+
+		spin_lock_irqsave(&udc->lock, flags);
+
+		udc_clk_set(udc, 0);
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+/* Can be called with or without lock */
+static int lpc32xx_pullup(struct usb_gadget *gadget, int is_on)
+{
+	struct lpc32xx_udc *udc = to_udc(gadget);
+
+	/* Doesn't need lock */
+	pullup(udc, is_on);
+
+	return 0;
+}
+
+static int lpc32xx_start(struct usb_gadget_driver *driver,
+			 int (*bind)(struct usb_gadget *));
+static int lpc32xx_stop(struct usb_gadget_driver *driver);
+
+static const struct usb_gadget_ops lpc32xx_udc_ops = {
+	.get_frame		= lpc32xx_get_frame,
+	.wakeup			= lpc32xx_wakeup,
+	.set_selfpowered	= lpc32xx_set_selfpowered,
+	.vbus_session		= lpc32xx_vbus_session,
+	.pullup			= lpc32xx_pullup,
+	.start			= lpc32xx_start,
+	.stop			= lpc32xx_stop,
+};
+
+static void nop_release(struct device *dev)
+{
+	/* nothing to free */
+}
+
+static struct lpc32xx_udc controller = {
+	.gadget = {
+		.ops	= &lpc32xx_udc_ops,
+		.ep0	= &controller.ep[0].ep,
+		.name	= driver_name,
+		.dev	= {
+			.init_name = "gadget",
+			.release = nop_release,
+		}
+	},
+	.ep[0] = {
+		.ep = {
+			.name	= "ep0",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 0,
+		.hwep_num	= 0, /* Can be 0 or 1, has special handling */
+		.lep		= 0,
+		.eptype		= EP_CTL_TYPE,
+	},
+	.ep[1] = {
+		.ep = {
+			.name	= "ep1-int",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 2,
+		.hwep_num	= 0, /* 2 or 3, will be set later */
+		.lep		= 1,
+		.eptype		= EP_INT_TYPE,
+	},
+	.ep[2] = {
+		.ep = {
+			.name	= "ep2-bulk",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 4,
+		.hwep_num	= 0, /* 4 or 5, will be set later */
+		.lep		= 2,
+		.eptype		= EP_BLK_TYPE,
+	},
+	.ep[3] = {
+		.ep = {
+			.name	= "ep3-iso",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 1023,
+		.hwep_num_base	= 6,
+		.hwep_num	= 0, /* 6 or 7, will be set later */
+		.lep		= 3,
+		.eptype		= EP_ISO_TYPE,
+	},
+	.ep[4] = {
+		.ep = {
+			.name	= "ep4-int",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 8,
+		.hwep_num	= 0, /* 8 or 9, will be set later */
+		.lep		= 4,
+		.eptype		= EP_INT_TYPE,
+	},
+	.ep[5] = {
+		.ep = {
+			.name	= "ep5-bulk",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 10,
+		.hwep_num	= 0, /* 10 or 11, will be set later */
+		.lep		= 5,
+		.eptype		= EP_BLK_TYPE,
+	},
+	.ep[6] = {
+		.ep = {
+			.name	= "ep6-iso",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 1023,
+		.hwep_num_base	= 12,
+		.hwep_num	= 0, /* 12 or 13, will be set later */
+		.lep		= 6,
+		.eptype		= EP_ISO_TYPE,
+	},
+	.ep[7] = {
+		.ep = {
+			.name	= "ep7-int",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 14,
+		.hwep_num	= 0,
+		.lep		= 7,
+		.eptype		= EP_INT_TYPE,
+	},
+	.ep[8] = {
+		.ep = {
+			.name	= "ep8-bulk",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 16,
+		.hwep_num	= 0,
+		.lep		= 8,
+		.eptype		= EP_BLK_TYPE,
+	},
+	.ep[9] = {
+		.ep = {
+			.name	= "ep9-iso",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 1023,
+		.hwep_num_base	= 18,
+		.hwep_num	= 0,
+		.lep		= 9,
+		.eptype		= EP_ISO_TYPE,
+	},
+	.ep[10] = {
+		.ep = {
+			.name	= "ep10-int",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 20,
+		.hwep_num	= 0,
+		.lep		= 10,
+		.eptype		= EP_INT_TYPE,
+	},
+	.ep[11] = {
+		.ep = {
+			.name	= "ep11-bulk",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 22,
+		.hwep_num	= 0,
+		.lep		= 11,
+		.eptype		= EP_BLK_TYPE,
+	},
+	.ep[12] = {
+		.ep = {
+			.name	= "ep12-iso",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 1023,
+		.hwep_num_base	= 24,
+		.hwep_num	= 0,
+		.lep		= 12,
+		.eptype		= EP_ISO_TYPE,
+	},
+	.ep[13] = {
+		.ep = {
+			.name	= "ep13-int",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 26,
+		.hwep_num	= 0,
+		.lep		= 13,
+		.eptype		= EP_INT_TYPE,
+	},
+	.ep[14] = {
+		.ep = {
+			.name	= "ep14-bulk",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 64,
+		.hwep_num_base	= 28,
+		.hwep_num	= 0,
+		.lep		= 14,
+		.eptype		= EP_BLK_TYPE,
+	},
+	.ep[15] = {
+		.ep = {
+			.name	= "ep15-bulk",
+			.ops	= &lpc32xx_ep_ops,
+		},
+		.udc		= &controller,
+		.maxpacket	= 1023,
+		.hwep_num_base	= 30,
+		.hwep_num	= 0,
+		.lep		= 15,
+		.eptype		= EP_BLK_TYPE,
+	},
+};
+
+/* ISO and status interrupts */
+static irqreturn_t lpc32xx_usb_lp_irq(int irq, void *_udc)
+{
+	u32 tmp, devstat;
+	struct lpc32xx_udc *udc = _udc;
+
+	spin_lock(&udc->lock);
+
+	/* Read the device status register */
+	devstat = readl(USBD_DEVINTST(udc->udp_baseaddr));
+
+	devstat &= ~USBD_EP_FAST;
+	writel(devstat, USBD_DEVINTCLR(udc->udp_baseaddr));
+	devstat = devstat & udc->enabled_devints;
+
+	/* Device specific handling needed? */
+	if (devstat & USBD_DEV_STAT)
+		udc_handle_dev(udc);
+
+	/* Start of frame? (devstat & FRAME_INT):
+	 * The frame interrupt isn't really needed for ISO support,
+	 * as the driver will queue the necessary packets */
+
+	/* Error? */
+	if (devstat & ERR_INT) {
+		/* All types of errors, from cable removal during transfer to
+		 * misc protocol and bit errors. These are mostly for just info,
+		 * as the USB hardware will work around these. If these errors
+		 * happen alot, something is wrong. */
+		udc_protocol_cmd_w(udc, CMD_RD_ERR_STAT);
+		tmp = udc_protocol_cmd_r(udc, DAT_RD_ERR_STAT);
+		dev_dbg(udc->dev, "Device error (0x%x)!\n", tmp);
+	}
+
+	spin_unlock(&udc->lock);
+
+	return IRQ_HANDLED;
+}
+
+/* EP interrupts */
+static irqreturn_t lpc32xx_usb_hp_irq(int irq, void *_udc)
+{
+	u32 tmp;
+	struct lpc32xx_udc *udc = _udc;
+
+	spin_lock(&udc->lock);
+
+	/* Read the device status register */
+	writel(USBD_EP_FAST, USBD_DEVINTCLR(udc->udp_baseaddr));
+
+	/* Endpoints */
+	tmp = readl(USBD_EPINTST(udc->udp_baseaddr));
+
+	/* Special handling for EP0 */
+	if (tmp & (EP_MASK_SEL(0, EP_OUT) | EP_MASK_SEL(0, EP_IN))) {
+		/* Handle EP0 IN */
+		if (tmp & (EP_MASK_SEL(0, EP_IN)))
+			udc_handle_ep0_in(udc);
+
+		/* Handle EP0 OUT */
+		if (tmp & (EP_MASK_SEL(0, EP_OUT)))
+			udc_handle_ep0_out(udc);
+	}
+
+	/* All other EPs */
+	if (tmp & ~(EP_MASK_SEL(0, EP_OUT) | EP_MASK_SEL(0, EP_IN))) {
+		int i;
+
+		/* Handle other EP interrupts */
+		for (i = 1; i < NUM_ENDPOINTS; i++) {
+			if (tmp & (1 << udc->ep[i].hwep_num))
+				udc_handle_eps(udc, &udc->ep[i]);
+		}
+	}
+
+	spin_unlock(&udc->lock);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t lpc32xx_usb_devdma_irq(int irq, void *_udc)
+{
+	struct lpc32xx_udc *udc = _udc;
+
+	int i;
+	u32 tmp;
+
+	spin_lock(&udc->lock);
+
+	/* Handle EP DMA EOT interrupts */
+	tmp = readl(USBD_EOTINTST(udc->udp_baseaddr)) |
+		(readl(USBD_EPDMAST(udc->udp_baseaddr)) &
+		 readl(USBD_NDDRTINTST(udc->udp_baseaddr))) |
+		readl(USBD_SYSERRTINTST(udc->udp_baseaddr));
+	for (i = 1; i < NUM_ENDPOINTS; i++) {
+		if (tmp & (1 << udc->ep[i].hwep_num))
+			udc_handle_dma_ep(udc, &udc->ep[i]);
+	}
+
+	spin_unlock(&udc->lock);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ *
+ * VBUS detection, pullup handler, and Gadget cable state notification
+ *
+ */
+static void vbus_work(struct work_struct *work)
+{
+	u8 value;
+	struct lpc32xx_udc *udc = container_of(work, struct lpc32xx_udc,
+					       vbus_job);
+
+	if (udc->enabled != 0) {
+		/* Discharge VBUS real quick */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DISCHRG);
+
+		/* Give VBUS some time (100mS) to discharge */
+		msleep(100);
+
+		/* Disable VBUS discharge resistor */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR,
+			OTG1_VBUS_DISCHRG);
+
+		/* Clear interrupt */
+		i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
+			ISP1301_I2C_INTERRUPT_LATCH |
+			ISP1301_I2C_REG_CLEAR_ADDR, ~0);
+
+		/* Get the VBUS status from the transceiver */
+		value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client,
+						 ISP1301_I2C_OTG_CONTROL_2);
+
+		/* VBUS on or off? */
+		if (value & OTG_B_SESS_VLD)
+			udc->vbus = 1;
+		else
+			udc->vbus = 0;
+
+		/* VBUS changed? */
+		if (udc->last_vbus != udc->vbus) {
+			udc->last_vbus = udc->vbus;
+			lpc32xx_vbus_session(&udc->gadget, udc->vbus);
+		}
+	}
+
+	/* Re-enable after completion */
+	enable_irq(udc->udp_irq[IRQ_USB_ATX]);
+}
+
+static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc)
+{
+	struct lpc32xx_udc *udc = _udc;
+
+	/* Defer handling of VBUS IRQ to work queue */
+	disable_irq_nosync(udc->udp_irq[IRQ_USB_ATX]);
+	schedule_work(&udc->vbus_job);
+
+	return IRQ_HANDLED;
+}
+
+static int lpc32xx_start(struct usb_gadget_driver *driver,
+			 int (*bind)(struct usb_gadget *))
+{
+	struct lpc32xx_udc *udc = &controller;
+	int retval, i;
+
+	if (!driver || driver->max_speed < USB_SPEED_FULL ||
+	    !bind || !driver->setup) {
+		dev_err(udc->dev, "bad parameter.\n");
+		return -EINVAL;
+	}
+
+	if (udc->driver) {
+		dev_err(udc->dev, "UDC already has a gadget driver\n");
+		return -EBUSY;
+	}
+
+	udc->driver = driver;
+	udc->gadget.dev.driver = &driver->driver;
+	udc->enabled = 1;
+	udc->selfpowered = 1;
+	udc->vbus = 0;
+
+	retval = bind(&udc->gadget);
+	if (retval) {
+		dev_err(udc->dev, "bind() returned %d\n", retval);
+		udc->enabled = 0;
+		udc->selfpowered = 0;
+		udc->driver = NULL;
+		udc->gadget.dev.driver = NULL;
+		return retval;
+	}
+
+	dev_dbg(udc->dev, "bound to %s\n", driver->driver.name);
+
+	/* Force VBUS process once to check for cable insertion */
+	udc->last_vbus = udc->vbus = 0;
+	schedule_work(&udc->vbus_job);
+
+	/* Do not re-enable ATX IRQ (3) */
+	for (i = IRQ_USB_LP; i < IRQ_USB_ATX; i++)
+		enable_irq(udc->udp_irq[i]);
+
+	return 0;
+}
+
+static int lpc32xx_stop(struct usb_gadget_driver *driver)
+{
+	int i;
+	struct lpc32xx_udc *udc = &controller;
+
+	if (!driver || driver != udc->driver || !driver->unbind)
+		return -EINVAL;
+
+	/* Disable USB pullup */
+	isp1301_pullup_enable(udc, 0, 1);
+
+	for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++)
+		disable_irq(udc->udp_irq[i]);
+
+	if (udc->clocked) {
+
+		spin_lock(&udc->lock);
+		stop_activity(udc);
+		spin_unlock(&udc->lock);
+
+		/*
+		 *  Wait for all the endpoints to disable,
+		 *  before disabling clocks. Don't wait if
+		 *  endpoints are not enabled.
+		 */
+		if (atomic_read(&udc->enabled_ep_cnt))
+			wait_event_interruptible(udc->ep_disable_wait_queue,
+				(atomic_read(&udc->enabled_ep_cnt) == 0));
+
+		spin_lock(&udc->lock);
+		udc_clk_set(udc, 0);
+		spin_unlock(&udc->lock);
+	}
+
+	udc->enabled = 0;
+	pullup(udc, 0);
+
+	driver->unbind(&udc->gadget);
+	udc->gadget.dev.driver = NULL;
+	udc->driver = NULL;
+
+	dev_dbg(udc->dev, "unbound from %s\n", driver->driver.name);
+	return 0;
+}
+
+static void lpc32xx_udc_shutdown(struct platform_device *dev)
+{
+	/* Force disconnect on reboot */
+	struct lpc32xx_udc *udc = &controller;
+
+	pullup(udc, 0);
+}
+
+/*
+ * Callbacks to be overridden by options passed via OF (TODO)
+ */
+
+static void lpc32xx_usbd_conn_chg(int conn)
+{
+	/* Do nothing, it might be nice to enable an LED
+	 * based on conn state being !0 */
+}
+
+static void lpc32xx_usbd_susp_chg(int susp)
+{
+	/* Device suspend if susp != 0 */
+}
+
+static void lpc32xx_rmwkup_chg(int remote_wakup_enable)
+{
+	/* Enable or disable USB remote wakeup */
+}
+
+struct lpc32xx_usbd_cfg lpc32xx_usbddata = {
+	.vbus_drv_pol = 0,
+	.conn_chgb = &lpc32xx_usbd_conn_chg,
+	.susp_chgb = &lpc32xx_usbd_susp_chg,
+	.rmwk_chgb = &lpc32xx_rmwkup_chg,
+};
+
+
+static u64 lpc32xx_usbd_dmamask = ~(u32) 0x7F;
+
+static int __init lpc32xx_udc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct lpc32xx_udc *udc = &controller;
+	int retval, i;
+	struct resource *res;
+	dma_addr_t dma_handle;
+	struct device_node *isp1301_node;
+
+	/* init software state */
+	udc->gadget.dev.parent = dev;
+	udc->pdev = pdev;
+	udc->dev = &pdev->dev;
+	udc->enabled = 0;
+
+	if (pdev->dev.of_node) {
+		isp1301_node = of_parse_phandle(pdev->dev.of_node,
+						"transceiver", 0);
+	} else {
+		isp1301_node = NULL;
+	}
+
+	udc->isp1301_i2c_client = isp1301_get_client(isp1301_node);
+	if (!udc->isp1301_i2c_client)
+		return -EPROBE_DEFER;
+
+	dev_info(udc->dev, "ISP1301 I2C device at address 0x%x\n",
+		 udc->isp1301_i2c_client->addr);
+
+	pdev->dev.dma_mask = &lpc32xx_usbd_dmamask;
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+	udc->board = &lpc32xx_usbddata;
+
+	/*
+	 * Resources are mapped as follows:
+	 *  IORESOURCE_MEM, base address and size of USB space
+	 *  IORESOURCE_IRQ, USB device low priority interrupt number
+	 *  IORESOURCE_IRQ, USB device high priority interrupt number
+	 *  IORESOURCE_IRQ, USB device interrupt number
+	 *  IORESOURCE_IRQ, USB transceiver interrupt number
+	 */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	spin_lock_init(&udc->lock);
+
+	/* Get IRQs */
+	for (i = 0; i < 4; i++) {
+		udc->udp_irq[i] = platform_get_irq(pdev, i);
+		if (udc->udp_irq[i] < 0) {
+			dev_err(udc->dev,
+				"irq resource %d not available!\n", i);
+			return udc->udp_irq[i];
+		}
+	}
+
+	udc->io_p_start = res->start;
+	udc->io_p_size = resource_size(res);
+	if (!request_mem_region(udc->io_p_start, udc->io_p_size, driver_name)) {
+		dev_err(udc->dev, "someone's using UDC memory\n");
+		return -EBUSY;
+	}
+
+	udc->udp_baseaddr = ioremap(udc->io_p_start, udc->io_p_size);
+	if (!udc->udp_baseaddr) {
+		retval = -ENOMEM;
+		dev_err(udc->dev, "IO map failure\n");
+		goto io_map_fail;
+	}
+
+	/* Enable AHB slave USB clock, needed for further USB clock control */
+	writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL);
+
+	/* Get required clocks */
+	udc->usb_pll_clk = clk_get(&pdev->dev, "ck_pll5");
+	if (IS_ERR(udc->usb_pll_clk)) {
+		dev_err(udc->dev, "failed to acquire USB PLL\n");
+		retval = PTR_ERR(udc->usb_pll_clk);
+		goto pll_get_fail;
+	}
+	udc->usb_slv_clk = clk_get(&pdev->dev, "ck_usbd");
+	if (IS_ERR(udc->usb_slv_clk)) {
+		dev_err(udc->dev, "failed to acquire USB device clock\n");
+		retval = PTR_ERR(udc->usb_slv_clk);
+		goto usb_clk_get_fail;
+	}
+
+	/* Setup PLL clock to 48MHz */
+	retval = clk_enable(udc->usb_pll_clk);
+	if (retval < 0) {
+		dev_err(udc->dev, "failed to start USB PLL\n");
+		goto pll_enable_fail;
+	}
+
+	retval = clk_set_rate(udc->usb_pll_clk, 48000);
+	if (retval < 0) {
+		dev_err(udc->dev, "failed to set USB clock rate\n");
+		goto pll_set_fail;
+	}
+
+	writel(readl(USB_CTRL) | USB_DEV_NEED_CLK_EN, USB_CTRL);
+
+	/* Enable USB device clock */
+	retval = clk_enable(udc->usb_slv_clk);
+	if (retval < 0) {
+		dev_err(udc->dev, "failed to start USB device clock\n");
+		goto usb_clk_enable_fail;
+	}
+
+	/* Set to enable all needed USB OTG clocks */
+	writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc));
+
+	i = 1000;
+	while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) !=
+		USB_CLOCK_MASK) && (i > 0))
+		i--;
+	if (!i)
+		dev_dbg(udc->dev, "USB OTG clocks not correctly enabled\n");
+
+	/* Setup deferred workqueue data */
+	udc->poweron = udc->pullup = 0;
+	INIT_WORK(&udc->pullup_job, pullup_work);
+	INIT_WORK(&udc->vbus_job, vbus_work);
+#ifdef CONFIG_PM
+	INIT_WORK(&udc->power_job, power_work);
+#endif
+
+	/* All clocks are now on */
+	udc->clocked = 1;
+
+	isp1301_udc_configure(udc);
+	/* Allocate memory for the UDCA */
+	udc->udca_v_base = dma_alloc_coherent(&pdev->dev, UDCA_BUFF_SIZE,
+					      &dma_handle,
+					      (GFP_KERNEL | GFP_DMA));
+	if (!udc->udca_v_base) {
+		dev_err(udc->dev, "error getting UDCA region\n");
+		retval = -ENOMEM;
+		goto i2c_fail;
+	}
+	udc->udca_p_base = dma_handle;
+	dev_dbg(udc->dev, "DMA buffer(0x%x bytes), P:0x%08x, V:0x%p\n",
+		UDCA_BUFF_SIZE, udc->udca_p_base, udc->udca_v_base);
+
+	/* Setup the DD DMA memory pool */
+	udc->dd_cache = dma_pool_create("udc_dd", udc->dev,
+					sizeof(struct lpc32xx_usbd_dd_gad),
+					sizeof(u32), 0);
+	if (!udc->dd_cache) {
+		dev_err(udc->dev, "error getting DD DMA region\n");
+		retval = -ENOMEM;
+		goto dma_alloc_fail;
+	}
+
+	/* Clear USB peripheral and initialize gadget endpoints */
+	udc_disable(udc);
+	udc_reinit(udc);
+
+	retval = device_register(&udc->gadget.dev);
+	if (retval < 0) {
+		dev_err(udc->dev, "Device registration failure\n");
+		goto dev_register_fail;
+	}
+
+	/* Request IRQs - low and high priority USB device IRQs are routed to
+	 * the same handler, while the DMA interrupt is routed elsewhere */
+	retval = request_irq(udc->udp_irq[IRQ_USB_LP], lpc32xx_usb_lp_irq,
+			     0, "udc_lp", udc);
+	if (retval < 0) {
+		dev_err(udc->dev, "LP request irq %d failed\n",
+			udc->udp_irq[IRQ_USB_LP]);
+		goto irq_lp_fail;
+	}
+	retval = request_irq(udc->udp_irq[IRQ_USB_HP], lpc32xx_usb_hp_irq,
+			     0, "udc_hp", udc);
+	if (retval < 0) {
+		dev_err(udc->dev, "HP request irq %d failed\n",
+			udc->udp_irq[IRQ_USB_HP]);
+		goto irq_hp_fail;
+	}
+
+	retval = request_irq(udc->udp_irq[IRQ_USB_DEVDMA],
+			     lpc32xx_usb_devdma_irq, 0, "udc_dma", udc);
+	if (retval < 0) {
+		dev_err(udc->dev, "DEV request irq %d failed\n",
+			udc->udp_irq[IRQ_USB_DEVDMA]);
+		goto irq_dev_fail;
+	}
+
+	/* The transceiver interrupt is used for VBUS detection and will
+	   kick off the VBUS handler function */
+	retval = request_irq(udc->udp_irq[IRQ_USB_ATX], lpc32xx_usb_vbus_irq,
+			     0, "udc_otg", udc);
+	if (retval < 0) {
+		dev_err(udc->dev, "VBUS request irq %d failed\n",
+			udc->udp_irq[IRQ_USB_ATX]);
+		goto irq_xcvr_fail;
+	}
+
+	/* Initialize wait queue */
+	init_waitqueue_head(&udc->ep_disable_wait_queue);
+	atomic_set(&udc->enabled_ep_cnt, 0);
+
+	/* Keep all IRQs disabled until GadgetFS starts up */
+	for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++)
+		disable_irq(udc->udp_irq[i]);
+
+	retval = usb_add_gadget_udc(dev, &udc->gadget);
+	if (retval < 0)
+		goto add_gadget_fail;
+
+	dev_set_drvdata(dev, udc);
+	device_init_wakeup(dev, 1);
+	create_debug_file(udc);
+
+	/* Disable clocks for now */
+	udc_clk_set(udc, 0);
+
+	dev_info(udc->dev, "%s version %s\n", driver_name, DRIVER_VERSION);
+	return 0;
+
+add_gadget_fail:
+	free_irq(udc->udp_irq[IRQ_USB_ATX], udc);
+irq_xcvr_fail:
+	free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc);
+irq_dev_fail:
+	free_irq(udc->udp_irq[IRQ_USB_HP], udc);
+irq_hp_fail:
+	free_irq(udc->udp_irq[IRQ_USB_LP], udc);
+irq_lp_fail:
+	device_unregister(&udc->gadget.dev);
+dev_register_fail:
+	dma_pool_destroy(udc->dd_cache);
+dma_alloc_fail:
+	dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
+			  udc->udca_v_base, udc->udca_p_base);
+i2c_fail:
+	clk_disable(udc->usb_slv_clk);
+usb_clk_enable_fail:
+pll_set_fail:
+	clk_disable(udc->usb_pll_clk);
+pll_enable_fail:
+	clk_put(udc->usb_slv_clk);
+usb_clk_get_fail:
+	clk_put(udc->usb_pll_clk);
+pll_get_fail:
+	iounmap(udc->udp_baseaddr);
+io_map_fail:
+	release_mem_region(udc->io_p_start, udc->io_p_size);
+	dev_err(udc->dev, "%s probe failed, %d\n", driver_name, retval);
+
+	return retval;
+}
+
+static int __devexit lpc32xx_udc_remove(struct platform_device *pdev)
+{
+	struct lpc32xx_udc *udc = platform_get_drvdata(pdev);
+
+	usb_del_gadget_udc(&udc->gadget);
+	if (udc->driver)
+		return -EBUSY;
+
+	udc_clk_set(udc, 1);
+	udc_disable(udc);
+	pullup(udc, 0);
+
+	free_irq(udc->udp_irq[IRQ_USB_ATX], udc);
+
+	device_init_wakeup(&pdev->dev, 0);
+	remove_debug_file(udc);
+
+	dma_pool_destroy(udc->dd_cache);
+	dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE,
+			  udc->udca_v_base, udc->udca_p_base);
+	free_irq(udc->udp_irq[IRQ_USB_DEVDMA], udc);
+	free_irq(udc->udp_irq[IRQ_USB_HP], udc);
+	free_irq(udc->udp_irq[IRQ_USB_LP], udc);
+
+	device_unregister(&udc->gadget.dev);
+
+	clk_disable(udc->usb_slv_clk);
+	clk_put(udc->usb_slv_clk);
+	clk_disable(udc->usb_pll_clk);
+	clk_put(udc->usb_pll_clk);
+	iounmap(udc->udp_baseaddr);
+	release_mem_region(udc->io_p_start, udc->io_p_size);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+	int to = 1000;
+	struct lpc32xx_udc *udc = platform_get_drvdata(pdev);
+
+	if (udc->clocked) {
+		/* Power down ISP */
+		udc->poweron = 0;
+		isp1301_set_powerstate(udc, 0);
+
+		/* Disable clocking */
+		udc_clk_set(udc, 0);
+
+		/* Keep clock flag on, so we know to re-enable clocks
+		   on resume */
+		udc->clocked = 1;
+
+		/* Kill OTG and I2C clocks */
+		writel(0, USB_OTG_CLK_CTRL(udc));
+		while (((readl(USB_OTG_CLK_STAT(udc)) & OTGOFF_CLK_MASK) !=
+			OTGOFF_CLK_MASK) && (to > 0))
+			to--;
+		if (!to)
+			dev_dbg(udc->dev,
+				"USB OTG clocks not correctly enabled\n");
+
+		/* Kill global USB clock */
+		clk_disable(udc->usb_slv_clk);
+	}
+
+	return 0;
+}
+
+static int lpc32xx_udc_resume(struct platform_device *pdev)
+{
+	struct lpc32xx_udc *udc = platform_get_drvdata(pdev);
+
+	if (udc->clocked) {
+		/* Enable global USB clock */
+		clk_enable(udc->usb_slv_clk);
+
+		/* Enable clocking */
+		udc_clk_set(udc, 1);
+
+		/* ISP back to normal power mode */
+		udc->poweron = 1;
+		isp1301_set_powerstate(udc, 1);
+	}
+
+	return 0;
+}
+#else
+#define	lpc32xx_udc_suspend	NULL
+#define	lpc32xx_udc_resume	NULL
+#endif
+
+#ifdef CONFIG_OF
+static struct of_device_id lpc32xx_udc_of_match[] = {
+	{ .compatible = "nxp,lpc3220-udc", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, lpc32xx_udc_of_match);
+#endif
+
+static struct platform_driver lpc32xx_udc_driver = {
+	.remove		= __devexit_p(lpc32xx_udc_remove),
+	.shutdown	= lpc32xx_udc_shutdown,
+	.suspend	= lpc32xx_udc_suspend,
+	.resume		= lpc32xx_udc_resume,
+	.driver		= {
+		.name	= (char *) driver_name,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(lpc32xx_udc_of_match),
+	},
+};
+
+static int __init udc_init_module(void)
+{
+	return platform_driver_probe(&lpc32xx_udc_driver, lpc32xx_udc_probe);
+}
+module_init(udc_init_module);
+
+static void __exit udc_exit_module(void)
+{
+	platform_driver_unregister(&lpc32xx_udc_driver);
+}
+module_exit(udc_exit_module);
+
+MODULE_DESCRIPTION("LPC32XX udc driver");
+MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lpc32xx_udc");
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 3608b3b..8981fbb 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -390,7 +390,7 @@
 	int *counter;
 	int ret;
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 
 	BUG_ON(ep->pipenum);
 
@@ -558,7 +558,7 @@
 
 static void start_packet(struct m66592_ep *ep, struct m66592_request *req)
 {
-	if (ep->desc->bEndpointAddress & USB_DIR_IN)
+	if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
 		start_packet_write(ep, req);
 	else
 		start_packet_read(ep, req);
@@ -734,7 +734,7 @@
 
 	if (restart) {
 		req = list_entry(ep->queue.next, struct m66592_request, queue);
-		if (ep->desc)
+		if (ep->ep.desc)
 			start_packet(ep, req);
 	}
 }
@@ -917,7 +917,7 @@
 				ep = m66592->pipenum2ep[pipenum];
 				req = list_entry(ep->queue.next,
 						 struct m66592_request, queue);
-				if (ep->desc->bEndpointAddress & USB_DIR_IN)
+				if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
 					irq_packet_write(ep, req);
 				else
 					irq_packet_read(ep, req);
@@ -1377,7 +1377,7 @@
 	req->req.actual = 0;
 	req->req.status = -EINPROGRESS;
 
-	if (ep->desc == NULL)	/* control */
+	if (ep->ep.desc == NULL)	/* control */
 		start_ep0(ep, req);
 	else {
 		if (request && !ep->busy)
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
index 9d9f7e3..88c85b4 100644
--- a/drivers/usb/gadget/m66592-udc.h
+++ b/drivers/usb/gadget/m66592-udc.h
@@ -456,7 +456,7 @@
 	unsigned		use_dma:1;
 	u16			pipenum;
 	u16			type;
-	const struct usb_endpoint_descriptor	*desc;
+
 	/* register address */
 	unsigned long		fifoaddr;
 	unsigned long		fifosel;
diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h
index e2be951..9073436 100644
--- a/drivers/usb/gadget/mv_udc.h
+++ b/drivers/usb/gadget/mv_udc.h
@@ -232,7 +232,6 @@
 	struct mv_udc		*udc;
 	struct list_head	queue;
 	struct mv_dqh		*dqh;
-	const struct usb_endpoint_descriptor	*desc;
 	u32			direction;
 	char			name[14];
 	unsigned		stopped:1,
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index a73cf40..dbcd132 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -464,7 +464,7 @@
 	ep = container_of(_ep, struct mv_ep, ep);
 	udc = ep->udc;
 
-	if (!_ep || !desc || ep->desc
+	if (!_ep || !desc || ep->ep.desc
 			|| desc->bDescriptorType != USB_DT_ENDPOINT)
 		return -EINVAL;
 
@@ -528,7 +528,7 @@
 	dqh->size_ioc_int_sts = 0;
 
 	ep->ep.maxpacket = max;
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->stopped = 0;
 
 	/* Enable the endpoint for Rx or Tx and set the endpoint type */
@@ -580,7 +580,7 @@
 	unsigned long flags;
 
 	ep = container_of(_ep, struct mv_ep, ep);
-	if ((_ep == NULL) || !ep->desc)
+	if ((_ep == NULL) || !ep->ep.desc)
 		return -EINVAL;
 
 	udc = ep->udc;
@@ -606,7 +606,6 @@
 	/* nuke all pending requests (does flush) */
 	nuke(ep, -ESHUTDOWN);
 
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->stopped = 1;
 
@@ -651,7 +650,7 @@
 		return;
 
 	ep = container_of(_ep, struct mv_ep, ep);
-	if (!ep->desc)
+	if (!ep->ep.desc)
 		return;
 
 	udc = ep->udc;
@@ -715,11 +714,11 @@
 		dev_err(&udc->dev->dev, "%s, bad params", __func__);
 		return -EINVAL;
 	}
-	if (unlikely(!_ep || !ep->desc)) {
+	if (unlikely(!_ep || !ep->ep.desc)) {
 		dev_err(&udc->dev->dev, "%s, bad ep", __func__);
 		return -EINVAL;
 	}
-	if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+	if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
 		if (req->req.length > ep->ep.maxpacket)
 			return -EMSGSIZE;
 	}
@@ -925,12 +924,12 @@
 
 	ep = container_of(_ep, struct mv_ep, ep);
 	udc = ep->udc;
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		status = -EINVAL;
 		goto out;
 	}
 
-	if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+	if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
 		status = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1279,7 +1278,7 @@
 	ep->stopped = 0;
 	ep->ep.maxpacket = EP0_MAX_PKT_SIZE;
 	ep->ep_num = 0;
-	ep->desc = &mv_ep0_desc;
+	ep->ep.desc = &mv_ep0_desc;
 	INIT_LIST_HEAD(&ep->queue);
 
 	ep->ep_type = USB_ENDPOINT_XFER_CONTROL;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 3b4b6dd..7ba3246 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -153,7 +153,7 @@
 	u16		maxp;
 
 	/* catch various bogus parameters */
-	if (!_ep || !desc || ep->desc
+	if (!_ep || !desc || ep->ep.desc
 			|| desc->bDescriptorType != USB_DT_ENDPOINT
 			|| ep->bEndpointAddress != desc->bEndpointAddress
 			|| ep->maxpacket < usb_endpoint_maxp(desc)) {
@@ -200,7 +200,7 @@
 
 	spin_lock_irqsave(&udc->lock, flags);
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->irqs = 0;
 	ep->stopped = 0;
 	ep->ep.maxpacket = maxp;
@@ -242,14 +242,13 @@
 	struct omap_ep	*ep = container_of(_ep, struct omap_ep, ep);
 	unsigned long	flags;
 
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		DBG("%s, %s not enabled\n", __func__,
 			_ep ? ep->ep.name : NULL);
 		return -EINVAL;
 	}
 
 	spin_lock_irqsave(&ep->udc->lock, flags);
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	nuke (ep, -ESHUTDOWN);
 	ep->ep.maxpacket = ep->maxpacket;
@@ -917,7 +916,7 @@
 		DBG("%s, bad params\n", __func__);
 		return -EINVAL;
 	}
-	if (!_ep || (!ep->desc && ep->bEndpointAddress)) {
+	if (!_ep || (!ep->ep.desc && ep->bEndpointAddress)) {
 		DBG("%s, bad ep\n", __func__);
 		return -EINVAL;
 	}
@@ -1121,7 +1120,7 @@
 			status = 0;
 
 	/* otherwise, all active non-ISO endpoints can halt */
-	} else if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && ep->desc) {
+	} else if (ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && ep->ep.desc) {
 
 		/* IN endpoints must already be idle */
 		if ((ep->bEndpointAddress & USB_DIR_IN)
@@ -1625,7 +1624,7 @@
 				if (w_index & USB_DIR_IN)
 					ep += 16;
 				if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
-						|| !ep->desc)
+						|| !ep->ep.desc)
 					goto do_stall;
 				use_ep(ep, 0);
 				omap_writew(udc->clr_halt, UDC_CTRL);
@@ -1653,7 +1652,7 @@
 			if (w_index & USB_DIR_IN)
 				ep += 16;
 			if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
-					|| ep == ep0 || !ep->desc)
+					|| ep == ep0 || !ep->ep.desc)
 				goto do_stall;
 			if (use_dma && ep->has_dma) {
 				/* this has rude side-effects (aborts) and
@@ -1688,7 +1687,7 @@
 			ep = &udc->ep[w_index & 0xf];
 			if (w_index & USB_DIR_IN)
 				ep += 16;
-			if (!ep->desc)
+			if (!ep->ep.desc)
 				goto do_stall;
 
 			/* iso never stalls */
@@ -2509,7 +2508,7 @@
 		if (tmp & UDC_ADD) {
 			list_for_each_entry (ep, &udc->gadget.ep_list,
 					ep.ep_list) {
-				if (ep->desc)
+				if (ep->ep.desc)
 					proc_ep_show(s, ep);
 			}
 		}
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h
index 59d3b22..cfadeb5 100644
--- a/drivers/usb/gadget/omap_udc.h
+++ b/drivers/usb/gadget/omap_udc.h
@@ -140,7 +140,6 @@
 	struct list_head		queue;
 	unsigned long			irqs;
 	struct list_head		iso;
-	const struct usb_endpoint_descriptor	*desc;
 	char				name[14];
 	u16				maxpacket;
 	u8				bEndpointAddress;
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c
index 6530706..1cfcc9e 100644
--- a/drivers/usb/gadget/pch_udc.c
+++ b/drivers/usb/gadget/pch_udc.c
@@ -295,7 +295,6 @@
 	struct pch_udc_data_dma_desc	*td_data;
 	struct pch_udc_dev		*dev;
 	unsigned long			offset_addr;
-	const struct usb_endpoint_descriptor	*desc;
 	struct list_head		queue;
 	unsigned			num:5,
 					in:1,
@@ -1705,7 +1704,7 @@
 	if (!dev->driver || (dev->gadget.speed == USB_SPEED_UNKNOWN))
 		return -ESHUTDOWN;
 	spin_lock_irqsave(&dev->lock, iflags);
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->halted = 0;
 	pch_udc_ep_enable(ep, &ep->dev->cfg_data, desc);
 	ep->ep.maxpacket = usb_endpoint_maxp(desc);
@@ -1734,7 +1733,7 @@
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
 	dev = ep->dev;
-	if ((usbep->name == ep0_string) || !ep->desc)
+	if ((usbep->name == ep0_string) || !ep->ep.desc)
 		return -EINVAL;
 
 	spin_lock_irqsave(&ep->dev->lock, iflags);
@@ -1742,7 +1741,6 @@
 	ep->halted = 1;
 	pch_udc_ep_disable(ep);
 	pch_udc_disable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num));
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	INIT_LIST_HEAD(&ep->queue);
 	spin_unlock_irqrestore(&ep->dev->lock, iflags);
@@ -1849,7 +1847,7 @@
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
 	dev = ep->dev;
-	if (!ep->desc && ep->num)
+	if (!ep->ep.desc && ep->num)
 		return -EINVAL;
 	req = container_of(usbreq, struct pch_udc_request, req);
 	if (!list_empty(&req->queue))
@@ -1949,7 +1947,7 @@
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
 	dev = ep->dev;
-	if (!usbep || !usbreq || (!ep->desc && ep->num))
+	if (!usbep || !usbreq || (!ep->ep.desc && ep->num))
 		return ret;
 	req = container_of(usbreq, struct pch_udc_request, req);
 	spin_lock_irqsave(&ep->dev->lock, flags);
@@ -1988,7 +1986,7 @@
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
 	dev = ep->dev;
-	if (!ep->desc && !ep->num)
+	if (!ep->ep.desc && !ep->num)
 		return -EINVAL;
 	if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
 		return -ESHUTDOWN;
@@ -2033,7 +2031,7 @@
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
 	dev = ep->dev;
-	if (!ep->desc && !ep->num)
+	if (!ep->ep.desc && !ep->num)
 		return -EINVAL;
 	if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
 		return -ESHUTDOWN;
@@ -2065,7 +2063,7 @@
 		return;
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	if (ep->desc || !ep->num)
+	if (ep->ep.desc || !ep->num)
 		pch_udc_ep_fifo_flush(ep, ep->in);
 }
 
@@ -3282,7 +3280,6 @@
 
 MODULE_DEVICE_TABLE(pci, pch_udc_pcidev_id);
 
-
 static struct pci_driver pch_udc_driver = {
 	.name =	KBUILD_MODNAME,
 	.id_table =	pch_udc_pcidev_id,
@@ -3293,17 +3290,7 @@
 	.shutdown =	pch_udc_shutdown,
 };
 
-static int __init pch_udc_pci_init(void)
-{
-	return pci_register_driver(&pch_udc_driver);
-}
-module_init(pch_udc_pci_init);
-
-static void __exit pch_udc_pci_exit(void)
-{
-	pci_unregister_driver(&pch_udc_driver);
-}
-module_exit(pch_udc_pci_exit);
+module_pci_driver(pch_udc_driver);
 
 MODULE_DESCRIPTION("Intel EG20T USB Device Controller");
 MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>");
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 4e4dc1f..f1f9290 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -51,6 +51,7 @@
  * the runtime footprint, and giving us at least some parts of what
  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
  */
+#include "composite.c"
 #include "usbstring.c"
 #include "config.c"
 #include "epautoconf.c"
@@ -75,8 +76,6 @@
 	/* lock buffer lists during read/write calls */
 	struct mutex		lock_printer_io;
 	struct usb_gadget	*gadget;
-	struct usb_request	*req;		/* for control responses */
-	u8			config;
 	s8			interface;
 	struct usb_ep		*in_ep, *out_ep;
 
@@ -100,6 +99,7 @@
 	struct device		*pdev;
 	u8			printer_cdev_open;
 	wait_queue_head_t	wait;
+	struct usb_function	function;
 };
 
 static struct printer_dev usb_printer_gadget;
@@ -120,26 +120,6 @@
  * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
  */
 
-static ushort idVendor;
-module_param(idVendor, ushort, S_IRUGO);
-MODULE_PARM_DESC(idVendor, "USB Vendor ID");
-
-static ushort idProduct;
-module_param(idProduct, ushort, S_IRUGO);
-MODULE_PARM_DESC(idProduct, "USB Product ID");
-
-static ushort bcdDevice;
-module_param(bcdDevice, ushort, S_IRUGO);
-MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
-
-static char *iManufacturer;
-module_param(iManufacturer, charp, S_IRUGO);
-MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
-
-static char *iProduct;
-module_param(iProduct, charp, S_IRUGO);
-MODULE_PARM_DESC(iProduct, "USB Product string");
-
 static char *iSerialNum;
 module_param(iSerialNum, charp, S_IRUGO);
 MODULE_PARM_DESC(iSerialNum, "1");
@@ -154,47 +134,8 @@
 
 #define QLEN	qlen
 
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-#define DEVSPEED	USB_SPEED_HIGH
-#else   /* full speed (low speed doesn't do bulk) */
-#define DEVSPEED        USB_SPEED_FULL
-#endif
-
 /*-------------------------------------------------------------------------*/
 
-#define xprintk(d, level, fmt, args...) \
-	printk(level "%s: " fmt, DRIVER_DESC, ## args)
-
-#ifdef DEBUG
-#define DBG(dev, fmt, args...) \
-	xprintk(dev, KERN_DEBUG, fmt, ## args)
-#else
-#define DBG(dev, fmt, args...) \
-	do { } while (0)
-#endif /* DEBUG */
-
-#ifdef VERBOSE
-#define VDBG(dev, fmt, args...) \
-	xprintk(dev, KERN_DEBUG, fmt, ## args)
-#else
-#define VDBG(dev, fmt, args...) \
-	do { } while (0)
-#endif /* VERBOSE */
-
-#define ERROR(dev, fmt, args...) \
-	xprintk(dev, KERN_ERR, fmt, ## args)
-#define WARNING(dev, fmt, args...) \
-	xprintk(dev, KERN_WARNING, fmt, ## args)
-#define INFO(dev, fmt, args...) \
-	xprintk(dev, KERN_INFO, fmt, ## args)
-
-/*-------------------------------------------------------------------------*/
-
-/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
- * ep0 implementation:  descriptors, config management, setup().
- * also optional class-specific notification interrupt transfer.
- */
-
 /*
  * DESCRIPTORS ... most are static, but strings and (full) configuration
  * descriptors are built on demand.
@@ -227,24 +168,6 @@
 	.bNumConfigurations =	1
 };
 
-static struct usb_otg_descriptor otg_desc = {
-	.bLength =		sizeof otg_desc,
-	.bDescriptorType =	USB_DT_OTG,
-	.bmAttributes =		USB_OTG_SRP
-};
-
-static struct usb_config_descriptor config_desc = {
-	.bLength =		sizeof config_desc,
-	.bDescriptorType =	USB_DT_CONFIG,
-
-	/* compute wTotalLength on the fly */
-	.bNumInterfaces =	1,
-	.bConfigurationValue =	DEV_CONFIG_VALUE,
-	.iConfiguration =	0,
-	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
-};
-
 static struct usb_interface_descriptor intf_desc = {
 	.bLength =		sizeof intf_desc,
 	.bDescriptorType =	USB_DT_INTERFACE,
@@ -270,16 +193,13 @@
 	.bmAttributes =		USB_ENDPOINT_XFER_BULK
 };
 
-static const struct usb_descriptor_header *fs_printer_function [11] = {
-	(struct usb_descriptor_header *) &otg_desc,
+static struct usb_descriptor_header *fs_printer_function[] = {
 	(struct usb_descriptor_header *) &intf_desc,
 	(struct usb_descriptor_header *) &fs_ep_in_desc,
 	(struct usb_descriptor_header *) &fs_ep_out_desc,
 	NULL
 };
 
-#ifdef	CONFIG_USB_GADGET_DUALSPEED
-
 /*
  * usb 2.0 devices need to expose both high speed and full speed
  * descriptors, unless they only run at full speed.
@@ -307,24 +227,27 @@
 	.bNumConfigurations =	1
 };
 
-static const struct usb_descriptor_header *hs_printer_function [11] = {
-	(struct usb_descriptor_header *) &otg_desc,
+static struct usb_descriptor_header *hs_printer_function[] = {
 	(struct usb_descriptor_header *) &intf_desc,
 	(struct usb_descriptor_header *) &hs_ep_in_desc,
 	(struct usb_descriptor_header *) &hs_ep_out_desc,
 	NULL
 };
 
+static struct usb_otg_descriptor otg_descriptor = {
+	.bLength =              sizeof otg_descriptor,
+	.bDescriptorType =      USB_DT_OTG,
+	.bmAttributes =         USB_OTG_SRP,
+};
+
+static const struct usb_descriptor_header *otg_desc[] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
+	NULL,
+};
+
 /* maxpacket and other transfer characteristics vary by speed. */
 #define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs))
 
-#else
-
-/* if there's no high speed support, maxpacket doesn't change. */
-#define ep_desc(g, hs, fs) (((void)(g)), (fs))
-
-#endif	/* !CONFIG_USB_GADGET_DUALSPEED */
-
 /*-------------------------------------------------------------------------*/
 
 /* descriptors that are built on-demand */
@@ -343,11 +266,16 @@
 	{  }		/* end of list */
 };
 
-static struct usb_gadget_strings	stringtab = {
+static struct usb_gadget_strings	stringtab_dev = {
 	.language	= 0x0409,	/* en-us */
 	.strings	= strings,
 };
 
+static struct usb_gadget_strings *dev_strings[] = {
+	&stringtab_dev,
+	NULL,
+};
+
 /*-------------------------------------------------------------------------*/
 
 static struct usb_request *
@@ -937,82 +865,8 @@
 	dev->interface = -1;
 }
 
-/* change our operational config.  must agree with the code
- * that returns config descriptors, and altsetting code.
- */
-static int
-printer_set_config(struct printer_dev *dev, unsigned number)
-{
-	int			result = 0;
-	struct usb_gadget	*gadget = dev->gadget;
-
-	switch (number) {
-	case DEV_CONFIG_VALUE:
-		result = 0;
-		break;
-	default:
-		result = -EINVAL;
-		/* FALL THROUGH */
-	case 0:
-		break;
-	}
-
-	if (result) {
-		usb_gadget_vbus_draw(dev->gadget,
-				dev->gadget->is_otg ? 8 : 100);
-	} else {
-		unsigned power;
-
-		power = 2 * config_desc.bMaxPower;
-		usb_gadget_vbus_draw(dev->gadget, power);
-
-		dev->config = number;
-		INFO(dev, "%s config #%d: %d mA, %s\n",
-		     usb_speed_string(gadget->speed),
-		     number, power, driver_desc);
-	}
-	return result;
-}
-
-static int
-config_buf(enum usb_device_speed speed, u8 *buf, u8 type, unsigned index,
-		int is_otg)
-{
-	int					len;
-	const struct usb_descriptor_header	**function;
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-	int					hs = (speed == USB_SPEED_HIGH);
-
-	if (type == USB_DT_OTHER_SPEED_CONFIG)
-		hs = !hs;
-
-	if (hs) {
-		function = hs_printer_function;
-	} else {
-		function = fs_printer_function;
-	}
-#else
-	function = fs_printer_function;
-#endif
-
-	if (index >= device_desc.bNumConfigurations)
-		return -EINVAL;
-
-	/* for now, don't advertise srp-only devices */
-	if (!is_otg)
-		function++;
-
-	len = usb_gadget_config_buf(&config_desc, buf, USB_DESC_BUFSIZE,
-			function);
-	if (len < 0)
-		return len;
-	((struct usb_config_descriptor *) buf)->bDescriptorType = type;
-	return len;
-}
-
 /* Change our operational Interface. */
-static int
-set_interface(struct printer_dev *dev, unsigned number)
+static int set_interface(struct printer_dev *dev, unsigned number)
 {
 	int			result = 0;
 
@@ -1043,14 +897,6 @@
 	return result;
 }
 
-static void printer_setup_complete(struct usb_ep *ep, struct usb_request *req)
-{
-	if (req->status || req->actual != req->length)
-		DBG((struct printer_dev *) ep->driver_data,
-				"setup complete --> %d, %d/%d\n",
-				req->status, req->actual, req->length);
-}
-
 static void printer_soft_reset(struct printer_dev *dev)
 {
 	struct usb_request	*req;
@@ -1107,11 +953,12 @@
  * The setup() callback implements all the ep0 functionality that's not
  * handled lower down.
  */
-static int
-printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+static int printer_func_setup(struct usb_function *f,
+		const struct usb_ctrlrequest *ctrl)
 {
-	struct printer_dev	*dev = get_gadget_data(gadget);
-	struct usb_request	*req = dev->req;
+	struct printer_dev *dev = container_of(f, struct printer_dev, function);
+	struct usb_composite_dev *cdev = f->config->cdev;
+	struct usb_request	*req = cdev->req;
 	int			value = -EOPNOTSUPP;
 	u16			wIndex = le16_to_cpu(ctrl->wIndex);
 	u16			wValue = le16_to_cpu(ctrl->wValue);
@@ -1120,102 +967,7 @@
 	DBG(dev, "ctrl req%02x.%02x v%04x i%04x l%d\n",
 		ctrl->bRequestType, ctrl->bRequest, wValue, wIndex, wLength);
 
-	req->complete = printer_setup_complete;
-
 	switch (ctrl->bRequestType&USB_TYPE_MASK) {
-
-	case USB_TYPE_STANDARD:
-		switch (ctrl->bRequest) {
-
-		case USB_REQ_GET_DESCRIPTOR:
-			if (ctrl->bRequestType != USB_DIR_IN)
-				break;
-			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;
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-			case USB_DT_DEVICE_QUALIFIER:
-				if (!gadget_is_dualspeed(gadget))
-					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);
-				break;
-
-			case USB_DT_OTHER_SPEED_CONFIG:
-				if (!gadget_is_dualspeed(gadget))
-					break;
-				/* FALLTHROUGH */
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
-			case USB_DT_CONFIG:
-				value = config_buf(gadget->speed, req->buf,
-						wValue >> 8,
-						wValue & 0xff,
-						gadget->is_otg);
-				if (value >= 0)
-					value = min(wLength, (u16) value);
-				break;
-
-			case USB_DT_STRING:
-				value = usb_gadget_get_string(&stringtab,
-						wValue & 0xff, req->buf);
-				if (value >= 0)
-					value = min(wLength, (u16) value);
-				break;
-			}
-			break;
-
-		case USB_REQ_SET_CONFIGURATION:
-			if (ctrl->bRequestType != 0)
-				break;
-			if (gadget->a_hnp_support)
-				DBG(dev, "HNP available\n");
-			else if (gadget->a_alt_hnp_support)
-				DBG(dev, "HNP needs a different root port\n");
-			value = printer_set_config(dev, wValue);
-			if (!value)
-				value = set_interface(dev, PRINTER_INTERFACE);
-			break;
-		case USB_REQ_GET_CONFIGURATION:
-			if (ctrl->bRequestType != USB_DIR_IN)
-				break;
-			*(u8 *)req->buf = dev->config;
-			value = min(wLength, (u16) 1);
-			break;
-
-		case USB_REQ_SET_INTERFACE:
-			if (ctrl->bRequestType != USB_RECIP_INTERFACE ||
-					!dev->config)
-				break;
-
-			value = set_interface(dev, PRINTER_INTERFACE);
-			break;
-		case USB_REQ_GET_INTERFACE:
-			if (ctrl->bRequestType !=
-					(USB_DIR_IN|USB_RECIP_INTERFACE)
-					|| !dev->config)
-				break;
-
-			*(u8 *)req->buf = dev->interface;
-			value = min(wLength, (u16) 1);
-			break;
-
-		default:
-			goto unknown;
-		}
-		break;
-
 	case USB_TYPE_CLASS:
 		switch (ctrl->bRequest) {
 		case 0: /* Get the IEEE-1284 PNP String */
@@ -1261,44 +1013,50 @@
 			wValue, wIndex, wLength);
 		break;
 	}
-
-	/* respond with data transfer before status phase? */
-	if (value >= 0) {
-		req->length = value;
-		req->zero = value < wLength;
-		value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
-		if (value < 0) {
-			DBG(dev, "ep_queue --> %d\n", value);
-			req->status = 0;
-			printer_setup_complete(gadget->ep0, req);
-		}
-	}
-
 	/* host either stalls (value < 0) or reports success */
 	return value;
 }
 
-static void
-printer_disconnect(struct usb_gadget *gadget)
+static int __init printer_func_bind(struct usb_configuration *c,
+		struct usb_function *f)
 {
-	struct printer_dev	*dev = get_gadget_data(gadget);
+	return 0;
+}
+
+static void printer_func_unbind(struct usb_configuration *c,
+		struct usb_function *f)
+{
+}
+
+static int printer_func_set_alt(struct usb_function *f,
+		unsigned intf, unsigned alt)
+{
+	struct printer_dev *dev = container_of(f, struct printer_dev, function);
+	int ret = -ENOTSUPP;
+
+	if (!alt)
+		ret = set_interface(dev, PRINTER_INTERFACE);
+	return ret;
+}
+
+static void printer_func_disable(struct usb_function *f)
+{
+	struct printer_dev *dev = container_of(f, struct printer_dev, function);
 	unsigned long		flags;
 
 	DBG(dev, "%s\n", __func__);
 
 	spin_lock_irqsave(&dev->lock, flags);
-
 	printer_reset_interface(dev);
-
 	spin_unlock_irqrestore(&dev->lock, flags);
 }
 
-static void
-printer_unbind(struct usb_gadget *gadget)
+static void printer_cfg_unbind(struct usb_configuration *c)
 {
-	struct printer_dev	*dev = get_gadget_data(gadget);
+	struct printer_dev	*dev;
 	struct usb_request	*req;
 
+	dev = &usb_printer_gadget;
 
 	DBG(dev, "%s\n", __func__);
 
@@ -1336,18 +1094,18 @@
 		list_del(&req->list);
 		printer_req_free(dev->out_ep, req);
 	}
-
-	if (dev->req) {
-		printer_req_free(gadget->ep0, dev->req);
-		dev->req = NULL;
-	}
-
-	set_gadget_data(gadget, NULL);
 }
 
-static int __init
-printer_bind(struct usb_gadget *gadget)
+static struct usb_configuration printer_cfg_driver = {
+	.label			= "printer",
+	.unbind			= printer_cfg_unbind,
+	.bConfigurationValue	= 1,
+	.bmAttributes		= USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+};
+
+static int __init printer_bind_config(struct usb_configuration *c)
 {
+	struct usb_gadget	*gadget = c->cdev->gadget;
 	struct printer_dev	*dev;
 	struct usb_ep		*in_ep, *out_ep;
 	int			status = -ENOMEM;
@@ -1358,6 +1116,14 @@
 
 	dev = &usb_printer_gadget;
 
+	dev->function.name = shortname;
+	dev->function.descriptors = fs_printer_function;
+	dev->function.hs_descriptors = hs_printer_function;
+	dev->function.bind = printer_func_bind;
+	dev->function.setup = printer_func_setup;
+	dev->function.unbind = printer_func_unbind;
+	dev->function.set_alt = printer_func_set_alt;
+	dev->function.disable = printer_func_disable;
 
 	/* Setup the sysfs files for the printer gadget. */
 	dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
@@ -1393,29 +1159,6 @@
 		init_utsname()->sysname, init_utsname()->release,
 		gadget->name);
 
-	device_desc.idVendor =
-		cpu_to_le16(PRINTER_VENDOR_NUM);
-	device_desc.idProduct =
-		cpu_to_le16(PRINTER_PRODUCT_NUM);
-
-	/* support optional vendor/distro customization */
-	if (idVendor) {
-		if (!idProduct) {
-			dev_err(&gadget->dev, "idVendor needs idProduct!\n");
-			return -ENODEV;
-		}
-		device_desc.idVendor = cpu_to_le16(idVendor);
-		device_desc.idProduct = cpu_to_le16(idProduct);
-		if (bcdDevice)
-			device_desc.bcdDevice = cpu_to_le16(bcdDevice);
-	}
-
-	if (iManufacturer)
-		strlcpy(manufacturer, iManufacturer, sizeof manufacturer);
-
-	if (iProduct)
-		strlcpy(product_desc, iProduct, sizeof product_desc);
-
 	if (iSerialNum)
 		strlcpy(serial_num, iSerialNum, sizeof serial_num);
 
@@ -1442,17 +1185,16 @@
 		goto autoconf_fail;
 	out_ep->driver_data = out_ep;	/* claim */
 
-#ifdef	CONFIG_USB_GADGET_DUALSPEED
 	/* assumes 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 */
 
 	usb_gadget_set_selfpowered(gadget);
 
 	if (gadget->is_otg) {
-		otg_desc.bmAttributes |= USB_OTG_HNP,
-		config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		otg_descriptor.bmAttributes |= USB_OTG_HNP;
+		printer_cfg_driver.descriptors = otg_desc;
+		printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 	}
 
 	spin_lock_init(&dev->lock);
@@ -1466,7 +1208,6 @@
 	init_waitqueue_head(&dev->tx_wait);
 	init_waitqueue_head(&dev->tx_flush_wait);
 
-	dev->config = 0;
 	dev->interface = -1;
 	dev->printer_cdev_open = 0;
 	dev->printer_status = PRINTER_NOT_ERROR;
@@ -1477,14 +1218,6 @@
 	dev->in_ep = in_ep;
 	dev->out_ep = out_ep;
 
-	/* preallocate control message data and buffer */
-	dev->req = printer_req_alloc(gadget->ep0, USB_DESC_BUFSIZE,
-			GFP_KERNEL);
-	if (!dev->req) {
-		status = -ENOMEM;
-		goto fail;
-	}
-
 	for (i = 0; i < QLEN; i++) {
 		req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
 		if (!req) {
@@ -1513,45 +1246,37 @@
 		list_add(&req->list, &dev->rx_reqs);
 	}
 
-	dev->req->complete = printer_setup_complete;
-
 	/* finish hookup to lower layer ... */
 	dev->gadget = gadget;
-	set_gadget_data(gadget, dev);
-	gadget->ep0->driver_data = dev;
 
 	INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
 	INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name,
 			in_ep->name);
-
 	return 0;
 
 fail:
-	printer_unbind(gadget);
+	printer_cfg_unbind(c);
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
+static int printer_unbind(struct usb_composite_dev *cdev)
+{
+	return 0;
+}
 
-static struct usb_gadget_driver printer_driver = {
-	.max_speed	= DEVSPEED,
+static int __init printer_bind(struct usb_composite_dev *cdev)
+{
+	return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
+}
 
-	.function	= (char *) driver_desc,
+static struct usb_composite_driver printer_driver = {
+	.name           = shortname,
+	.dev            = &device_desc,
+	.strings        = dev_strings,
+	.max_speed      = USB_SPEED_HIGH,
 	.unbind		= printer_unbind,
-
-	.setup		= printer_setup,
-	.disconnect	= printer_disconnect,
-
-	.driver		= {
-		.name		= (char *) shortname,
-		.owner		= THIS_MODULE,
-	},
 };
 
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Craig Nadler");
-MODULE_LICENSE("GPL");
-
 static int __init
 init(void)
 {
@@ -1560,23 +1285,23 @@
 	usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget");
 	if (IS_ERR(usb_gadget_class)) {
 		status = PTR_ERR(usb_gadget_class);
-		ERROR(dev, "unable to create usb_gadget class %d\n", status);
+		pr_err("unable to create usb_gadget class %d\n", status);
 		return status;
 	}
 
 	status = alloc_chrdev_region(&g_printer_devno, 0, 1,
 			"USB printer gadget");
 	if (status) {
-		ERROR(dev, "alloc_chrdev_region %d\n", status);
+		pr_err("alloc_chrdev_region %d\n", status);
 		class_destroy(usb_gadget_class);
 		return status;
 	}
 
-	status = usb_gadget_probe_driver(&printer_driver, printer_bind);
+	status = usb_composite_probe(&printer_driver, printer_bind);
 	if (status) {
 		class_destroy(usb_gadget_class);
 		unregister_chrdev_region(g_printer_devno, 1);
-		DBG(dev, "usb_gadget_probe_driver %x\n", status);
+		pr_err("usb_gadget_probe_driver %x\n", status);
 	}
 
 	return status;
@@ -1586,15 +1311,14 @@
 static void __exit
 cleanup(void)
 {
-	int status;
-
 	mutex_lock(&usb_printer_gadget.lock_printer_io);
-	status = usb_gadget_unregister_driver(&printer_driver);
-	if (status)
-		ERROR(dev, "usb_gadget_unregister_driver %x\n", status);
-
+	usb_composite_unregister(&printer_driver);
 	unregister_chrdev_region(g_printer_devno, 1);
 	class_destroy(usb_gadget_class);
 	mutex_unlock(&usb_printer_gadget.lock_printer_io);
 }
 module_exit(cleanup);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Craig Nadler");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index 41ed69c..d7c8cb3 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -218,7 +218,7 @@
 	struct pxa25x_udc       *dev;
 
 	ep = container_of (_ep, struct pxa25x_ep, ep);
-	if (!_ep || !desc || ep->desc || _ep->name == ep0name
+	if (!_ep || !desc || ep->ep.desc || _ep->name == ep0name
 			|| desc->bDescriptorType != USB_DT_ENDPOINT
 			|| ep->bEndpointAddress != desc->bEndpointAddress
 			|| ep->fifo_size < usb_endpoint_maxp (desc)) {
@@ -249,7 +249,7 @@
 		return -ESHUTDOWN;
 	}
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->stopped = 0;
 	ep->pio_irqs = 0;
 	ep->ep.maxpacket = usb_endpoint_maxp (desc);
@@ -269,7 +269,7 @@
 	unsigned long		flags;
 
 	ep = container_of (_ep, struct pxa25x_ep, ep);
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		DMSG("%s, %s not enabled\n", __func__,
 			_ep ? ep->ep.name : NULL);
 		return -EINVAL;
@@ -281,7 +281,6 @@
 	/* flush fifo (mostly for IN buffers) */
 	pxa25x_ep_fifo_flush (_ep);
 
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->stopped = 1;
 
@@ -390,7 +389,7 @@
 {
 	unsigned		max;
 
-	max = usb_endpoint_maxp(ep->desc);
+	max = usb_endpoint_maxp(ep->ep.desc);
 	do {
 		unsigned	count;
 		int		is_last, is_short;
@@ -644,7 +643,7 @@
 	}
 
 	ep = container_of(_ep, struct pxa25x_ep, ep);
-	if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+	if (unlikely(!_ep || (!ep->ep.desc && ep->ep.name != ep0name))) {
 		DMSG("%s, bad ep\n", __func__);
 		return -EINVAL;
 	}
@@ -660,7 +659,7 @@
 	 * we can report per-packet status.  that also helps with dma.
 	 */
 	if (unlikely (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
-		        && req->req.length > usb_endpoint_maxp (ep->desc)))
+			&& req->req.length > usb_endpoint_maxp(ep->ep.desc)))
 		return -EMSGSIZE;
 
 	DBG(DBG_NOISY, "%s queue req %p, len %d buf %p\n",
@@ -673,7 +672,7 @@
 
 	/* kickstart this i/o queue? */
 	if (list_empty(&ep->queue) && !ep->stopped) {
-		if (ep->desc == NULL/* ep0 */) {
+		if (ep->ep.desc == NULL/* ep0 */) {
 			unsigned	length = _req->length;
 
 			switch (dev->ep0state) {
@@ -722,7 +721,7 @@
 			req = NULL;
 		}
 
-		if (likely (req && ep->desc))
+		if (likely(req && ep->ep.desc))
 			pio_irq_enable(ep->bEndpointAddress);
 	}
 
@@ -749,7 +748,7 @@
 				queue);
 		done(ep, req, status);
 	}
-	if (ep->desc)
+	if (ep->ep.desc)
 		pio_irq_disable (ep->bEndpointAddress);
 }
 
@@ -792,7 +791,7 @@
 
 	ep = container_of(_ep, struct pxa25x_ep, ep);
 	if (unlikely (!_ep
-			|| (!ep->desc && ep->ep.name != ep0name))
+			|| (!ep->ep.desc && ep->ep.name != ep0name))
 			|| ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
 		DMSG("%s, bad ep\n", __func__);
 		return -EINVAL;
@@ -820,7 +819,7 @@
 	*ep->reg_udccs = UDCCS_BI_FST|UDCCS_BI_FTF;
 
 	/* ep0 needs special care */
-	if (!ep->desc) {
+	if (!ep->ep.desc) {
 		start_watchdog(ep->dev);
 		ep->dev->req_pending = 0;
 		ep->dev->ep0state = EP0_STALL;
@@ -1087,7 +1086,7 @@
 		if (i != 0) {
 			const struct usb_endpoint_descriptor	*desc;
 
-			desc = ep->desc;
+			desc = ep->ep.desc;
 			if (!desc)
 				continue;
 			tmp = *dev->ep [i].reg_udccs;
@@ -1191,7 +1190,6 @@
 		if (i != 0)
 			list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
 
-		ep->desc = NULL;
 		ep->ep.desc = NULL;
 		ep->stopped = 0;
 		INIT_LIST_HEAD (&ep->queue);
diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h
index 893e917..861f4df 100644
--- a/drivers/usb/gadget/pxa25x_udc.h
+++ b/drivers/usb/gadget/pxa25x_udc.h
@@ -41,7 +41,6 @@
 	struct usb_ep				ep;
 	struct pxa25x_udc			*dev;
 
-	const struct usb_endpoint_descriptor	*desc;
 	struct list_head			queue;
 	unsigned long				pio_irqs;
 
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index c4401e7..f3ac2a2 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -459,7 +459,7 @@
 	unsigned char *counter;
 	int ret;
 
-	ep->desc = desc;
+	ep->ep.desc = desc;
 
 	if (ep->pipenum)	/* already allocated pipe  */
 		return 0;
@@ -648,7 +648,7 @@
 	/* set SUDMAC parameters */
 	dma = &r8a66597->dma;
 	dma->used = 1;
-	if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+	if (ep->ep.desc->bEndpointAddress & USB_DIR_IN) {
 		dma->dir = 1;
 	} else {
 		dma->dir = 0;
@@ -770,7 +770,7 @@
 
 static void start_packet(struct r8a66597_ep *ep, struct r8a66597_request *req)
 {
-	if (ep->desc->bEndpointAddress & USB_DIR_IN)
+	if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
 		start_packet_write(ep, req);
 	else
 		start_packet_read(ep, req);
@@ -930,7 +930,7 @@
 
 	if (restart) {
 		req = get_request_from_ep(ep);
-		if (ep->desc)
+		if (ep->ep.desc)
 			start_packet(ep, req);
 	}
 }
@@ -1116,7 +1116,7 @@
 				r8a66597_write(r8a66597, ~check, BRDYSTS);
 				ep = r8a66597->pipenum2ep[pipenum];
 				req = get_request_from_ep(ep);
-				if (ep->desc->bEndpointAddress & USB_DIR_IN)
+				if (ep->ep.desc->bEndpointAddress & USB_DIR_IN)
 					irq_packet_write(ep, req);
 				else
 					irq_packet_read(ep, req);
@@ -1170,7 +1170,7 @@
 
 	switch (ctrl->bRequestType & USB_RECIP_MASK) {
 	case USB_RECIP_DEVICE:
-		status = 1 << USB_DEVICE_SELF_POWERED;
+		status = r8a66597->device_status;
 		break;
 	case USB_RECIP_INTERFACE:
 		status = 0;
@@ -1627,7 +1627,7 @@
 	req->req.actual = 0;
 	req->req.status = -EINPROGRESS;
 
-	if (ep->desc == NULL)	/* control */
+	if (ep->ep.desc == NULL)	/* control */
 		start_ep0(ep, req);
 	else {
 		if (request && !ep->busy)
@@ -1692,7 +1692,7 @@
 
 	ep = container_of(_ep, struct r8a66597_ep, ep);
 
-	if (!ep || !ep->desc)
+	if (!ep || !ep->ep.desc)
 		return -EINVAL;
 
 	spin_lock_irqsave(&ep->r8a66597->lock, flags);
@@ -1800,11 +1800,24 @@
 	return 0;
 }
 
+static int r8a66597_set_selfpowered(struct usb_gadget *gadget, int is_self)
+{
+	struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
+
+	if (is_self)
+		r8a66597->device_status |= 1 << USB_DEVICE_SELF_POWERED;
+	else
+		r8a66597->device_status &= ~(1 << USB_DEVICE_SELF_POWERED);
+
+	return 0;
+}
+
 static struct usb_gadget_ops r8a66597_gadget_ops = {
 	.get_frame		= r8a66597_get_frame,
 	.udc_start		= r8a66597_start,
 	.udc_stop		= r8a66597_stop,
 	.pullup			= r8a66597_pullup,
+	.set_selfpowered	= r8a66597_set_selfpowered,
 };
 
 static int __exit r8a66597_remove(struct platform_device *pdev)
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
index 8e3de61..99908c7 100644
--- a/drivers/usb/gadget/r8a66597-udc.h
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -72,7 +72,7 @@
 	unsigned		use_dma:1;
 	u16			pipenum;
 	u16			type;
-	const struct usb_endpoint_descriptor	*desc;
+
 	/* register address */
 	unsigned char		fifoaddr;
 	unsigned char		fifosel;
@@ -111,6 +111,7 @@
 	u16			old_vbus;
 	u16			scount;
 	u16			old_dvsq;
+	u16			device_status;	/* for GET_STATUS */
 
 	/* pipe config */
 	unsigned char bulk;
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 105b206..f4abb0e 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -1,4 +1,5 @@
-/* linux/drivers/usb/gadget/s3c-hsotg.c
+/**
+ * linux/drivers/usb/gadget/s3c-hsotg.c
  *
  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com
@@ -13,7 +14,7 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
-*/
+ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -27,21 +28,25 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <mach/map.h>
 
-#include <plat/regs-usb-hsotg-phy.h>
-#include <plat/regs-usb-hsotg.h>
-#include <mach/regs-sys.h>
-#include <plat/udc-hs.h>
-#include <plat/cpu.h>
+#include "s3c-hsotg.h"
 
 #define DMA_ADDR_INVALID (~((dma_addr_t)0))
 
-/* EP0_MPS_LIMIT
+static const char * const s3c_hsotg_supply_names[] = {
+	"vusb_d",		/* digital USB supply, 1.2V */
+	"vusb_a",		/* analog USB supply, 1.1V */
+};
+
+/*
+ * EP0_MPS_LIMIT
  *
  * Unfortunately there seems to be a limit of the amount of data that can
  * be transferred by IN transactions on EP0. This is either 127 bytes or 3
@@ -125,8 +130,6 @@
 	char			name[10];
 };
 
-#define S3C_HSOTG_EPS	(8+1)	/* limit to 9 for the moment */
-
 /**
  * struct s3c_hsotg - driver state.
  * @dev: The parent device supplied to the probe function
@@ -135,7 +138,9 @@
  * @regs: The memory area mapped for accessing registers.
  * @regs_res: The resource that was allocated when claiming register space.
  * @irq: The IRQ number we are using
+ * @supplies: Definition of USB power supplies
  * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos.
+ * @num_of_eps: Number of available EPs (excluding EP0)
  * @debug_root: root directrory for debugfs.
  * @debug_file: main status file for debugfs.
  * @debug_fifo: FIFO status file for debugfs.
@@ -143,6 +148,8 @@
  * @ep0_buff: Buffer for EP0 reply data, if needed.
  * @ctrl_buff: Buffer for EP0 control requests.
  * @ctrl_req: Request for EP0 control packets.
+ * @setup: NAK management for EP0 SETUP
+ * @last_rst: Time of last reset
  * @eps: The endpoints being supplied to the gadget framework
  */
 struct s3c_hsotg {
@@ -155,7 +162,10 @@
 	int			irq;
 	struct clk		*clk;
 
+	struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)];
+
 	unsigned int		dedicated_fifos:1;
+	unsigned char           num_of_eps;
 
 	struct dentry		*debug_root;
 	struct dentry		*debug_file;
@@ -167,7 +177,9 @@
 	u8			ctrl_buff[8];
 
 	struct usb_gadget	gadget;
-	struct s3c_hsotg_ep	eps[];
+	unsigned int		setup;
+	unsigned long           last_rst;
+	struct s3c_hsotg_ep	*eps;
 };
 
 /**
@@ -244,14 +256,14 @@
  */
 static void s3c_hsotg_en_gsint(struct s3c_hsotg *hsotg, u32 ints)
 {
-	u32 gsintmsk = readl(hsotg->regs + S3C_GINTMSK);
+	u32 gsintmsk = readl(hsotg->regs + GINTMSK);
 	u32 new_gsintmsk;
 
 	new_gsintmsk = gsintmsk | ints;
 
 	if (new_gsintmsk != gsintmsk) {
 		dev_dbg(hsotg->dev, "gsintmsk now 0x%08x\n", new_gsintmsk);
-		writel(new_gsintmsk, hsotg->regs + S3C_GINTMSK);
+		writel(new_gsintmsk, hsotg->regs + GINTMSK);
 	}
 }
 
@@ -262,13 +274,13 @@
  */
 static void s3c_hsotg_disable_gsint(struct s3c_hsotg *hsotg, u32 ints)
 {
-	u32 gsintmsk = readl(hsotg->regs + S3C_GINTMSK);
+	u32 gsintmsk = readl(hsotg->regs + GINTMSK);
 	u32 new_gsintmsk;
 
 	new_gsintmsk = gsintmsk & ~ints;
 
 	if (new_gsintmsk != gsintmsk)
-		writel(new_gsintmsk, hsotg->regs + S3C_GINTMSK);
+		writel(new_gsintmsk, hsotg->regs + GINTMSK);
 }
 
 /**
@@ -293,12 +305,12 @@
 		bit <<= 16;
 
 	local_irq_save(flags);
-	daint = readl(hsotg->regs + S3C_DAINTMSK);
+	daint = readl(hsotg->regs + DAINTMSK);
 	if (en)
 		daint |= bit;
 	else
 		daint &= ~bit;
-	writel(daint, hsotg->regs + S3C_DAINTMSK);
+	writel(daint, hsotg->regs + DAINTMSK);
 	local_irq_restore(flags);
 }
 
@@ -314,52 +326,51 @@
 	int timeout;
 	u32 val;
 
-	/* the ryu 2.6.24 release ahs
-	   writel(0x1C0, hsotg->regs + S3C_GRXFSIZ);
-	   writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) |
-		S3C_GNPTXFSIZ_NPTxFDep(0x1C0),
-		hsotg->regs + S3C_GNPTXFSIZ);
-	*/
-
 	/* set FIFO sizes to 2048/1024 */
 
-	writel(2048, hsotg->regs + S3C_GRXFSIZ);
-	writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) |
-	       S3C_GNPTXFSIZ_NPTxFDep(1024),
-	       hsotg->regs + S3C_GNPTXFSIZ);
+	writel(2048, hsotg->regs + GRXFSIZ);
+	writel(GNPTXFSIZ_NPTxFStAddr(2048) |
+	       GNPTXFSIZ_NPTxFDep(1024),
+	       hsotg->regs + GNPTXFSIZ);
 
-	/* arange all the rest of the TX FIFOs, as some versions of this
+	/*
+	 * arange all the rest of the TX FIFOs, as some versions of this
 	 * block have overlapping default addresses. This also ensures
 	 * that if the settings have been changed, then they are set to
-	 * known values. */
+	 * known values.
+	 */
 
 	/* start at the end of the GNPTXFSIZ, rounded up */
 	addr = 2048 + 1024;
 	size = 768;
 
-	/* currently we allocate TX FIFOs for all possible endpoints,
-	 * and assume that they are all the same size. */
+	/*
+	 * currently we allocate TX FIFOs for all possible endpoints,
+	 * and assume that they are all the same size.
+	 */
 
 	for (ep = 1; ep <= 15; ep++) {
 		val = addr;
-		val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
+		val |= size << DPTXFSIZn_DPTxFSize_SHIFT;
 		addr += size;
 
-		writel(val, hsotg->regs + S3C_DPTXFSIZn(ep));
+		writel(val, hsotg->regs + DPTXFSIZn(ep));
 	}
 
-	/* according to p428 of the design guide, we need to ensure that
-	 * all fifos are flushed before continuing */
+	/*
+	 * according to p428 of the design guide, we need to ensure that
+	 * all fifos are flushed before continuing
+	 */
 
-	writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh |
-	       S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL);
+	writel(GRSTCTL_TxFNum(0x10) | GRSTCTL_TxFFlsh |
+	       GRSTCTL_RxFFlsh, hsotg->regs + GRSTCTL);
 
 	/* wait until the fifos are both flushed */
 	timeout = 100;
 	while (1) {
-		val = readl(hsotg->regs + S3C_GRSTCTL);
+		val = readl(hsotg->regs + GRSTCTL);
 
-		if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0)
+		if ((val & (GRSTCTL_TxFFlsh | GRSTCTL_RxFFlsh)) == 0)
 			break;
 
 		if (--timeout == 0) {
@@ -415,7 +426,7 @@
  *
  * This is the reverse of s3c_hsotg_map_dma(), called for the completion
  * of a request to ensure the buffer is ready for access by the caller.
-*/
+ */
 static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg,
 				struct s3c_hsotg_ep *hs_ep,
 				struct s3c_hsotg_req *hs_req)
@@ -456,13 +467,13 @@
  * otherwise -ENOSPC is returned if the FIFO space was used up.
  *
  * This routine is only needed for PIO
-*/
+ */
 static int s3c_hsotg_write_fifo(struct s3c_hsotg *hsotg,
 				struct s3c_hsotg_ep *hs_ep,
 				struct s3c_hsotg_req *hs_req)
 {
 	bool periodic = is_ep_periodic(hs_ep);
-	u32 gnptxsts = readl(hsotg->regs + S3C_GNPTXSTS);
+	u32 gnptxsts = readl(hsotg->regs + GNPTXSTS);
 	int buf_pos = hs_req->req.actual;
 	int to_write = hs_ep->size_loaded;
 	void *data;
@@ -476,20 +487,23 @@
 		return 0;
 
 	if (periodic && !hsotg->dedicated_fifos) {
-		u32 epsize = readl(hsotg->regs + S3C_DIEPTSIZ(hs_ep->index));
+		u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
 		int size_left;
 		int size_done;
 
-		/* work out how much data was loaded so we can calculate
-		 * how much data is left in the fifo. */
+		/*
+		 * work out how much data was loaded so we can calculate
+		 * how much data is left in the fifo.
+		 */
 
-		size_left = S3C_DxEPTSIZ_XferSize_GET(epsize);
+		size_left = DxEPTSIZ_XferSize_GET(epsize);
 
-		/* if shared fifo, we cannot write anything until the
+		/*
+		 * if shared fifo, we cannot write anything until the
 		 * previous data has been completely sent.
 		 */
 		if (hs_ep->fifo_load != 0) {
-			s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_PTxFEmp);
+			s3c_hsotg_en_gsint(hsotg, GINTSTS_PTxFEmp);
 			return -ENOSPC;
 		}
 
@@ -510,47 +524,50 @@
 			__func__, can_write);
 
 		if (can_write <= 0) {
-			s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_PTxFEmp);
+			s3c_hsotg_en_gsint(hsotg, GINTSTS_PTxFEmp);
 			return -ENOSPC;
 		}
 	} else if (hsotg->dedicated_fifos && hs_ep->index != 0) {
-		can_write = readl(hsotg->regs + S3C_DTXFSTS(hs_ep->index));
+		can_write = readl(hsotg->regs + DTXFSTS(hs_ep->index));
 
 		can_write &= 0xffff;
 		can_write *= 4;
 	} else {
-		if (S3C_GNPTXSTS_NPTxQSpcAvail_GET(gnptxsts) == 0) {
+		if (GNPTXSTS_NPTxQSpcAvail_GET(gnptxsts) == 0) {
 			dev_dbg(hsotg->dev,
 				"%s: no queue slots available (0x%08x)\n",
 				__func__, gnptxsts);
 
-			s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_NPTxFEmp);
+			s3c_hsotg_en_gsint(hsotg, GINTSTS_NPTxFEmp);
 			return -ENOSPC;
 		}
 
-		can_write = S3C_GNPTXSTS_NPTxFSpcAvail_GET(gnptxsts);
+		can_write = GNPTXSTS_NPTxFSpcAvail_GET(gnptxsts);
 		can_write *= 4;	/* fifo size is in 32bit quantities. */
 	}
 
 	dev_dbg(hsotg->dev, "%s: GNPTXSTS=%08x, can=%d, to=%d, mps %d\n",
 		 __func__, gnptxsts, can_write, to_write, hs_ep->ep.maxpacket);
 
-	/* limit to 512 bytes of data, it seems at least on the non-periodic
+	/*
+	 * limit to 512 bytes of data, it seems at least on the non-periodic
 	 * FIFO, requests of >512 cause the endpoint to get stuck with a
 	 * fragment of the end of the transfer in it.
 	 */
 	if (can_write > 512)
 		can_write = 512;
 
-	/* limit the write to one max-packet size worth of data, but allow
+	/*
+	 * limit the write to one max-packet size worth of data, but allow
 	 * the transfer to return that it did not run out of fifo space
-	 * doing it. */
+	 * doing it.
+	 */
 	if (to_write > hs_ep->ep.maxpacket) {
 		to_write = hs_ep->ep.maxpacket;
 
 		s3c_hsotg_en_gsint(hsotg,
-				   periodic ? S3C_GINTSTS_PTxFEmp :
-				   S3C_GINTSTS_NPTxFEmp);
+				   periodic ? GINTSTS_PTxFEmp :
+				   GINTSTS_NPTxFEmp);
 	}
 
 	/* see if we can write data */
@@ -559,8 +576,8 @@
 		to_write = can_write;
 		pkt_round = to_write % hs_ep->ep.maxpacket;
 
-		/* Not sure, but we probably shouldn't be writing partial
-		 * packets into the FIFO, so round the write down to an
+		/*
+		 * Round the write down to an
 		 * exact number of packets.
 		 *
 		 * Note, we do not currently check to see if we can ever
@@ -570,12 +587,14 @@
 		if (pkt_round)
 			to_write -= pkt_round;
 
-		/* enable correct FIFO interrupt to alert us when there
-		 * is more room left. */
+		/*
+		 * enable correct FIFO interrupt to alert us when there
+		 * is more room left.
+		 */
 
 		s3c_hsotg_en_gsint(hsotg,
-				   periodic ? S3C_GINTSTS_PTxFEmp :
-				   S3C_GINTSTS_NPTxFEmp);
+				   periodic ? GINTSTS_PTxFEmp :
+				   GINTSTS_NPTxFEmp);
 	}
 
 	dev_dbg(hsotg->dev, "write %d/%d, can_write %d, done %d\n",
@@ -593,7 +612,7 @@
 	to_write = DIV_ROUND_UP(to_write, 4);
 	data = hs_req->req.buf + buf_pos;
 
-	writesl(hsotg->regs + S3C_EPFIFO(hs_ep->index), data, to_write);
+	writesl(hsotg->regs + EPFIFO(hs_ep->index), data, to_write);
 
 	return (to_write >= can_write) ? -ENOSPC : 0;
 }
@@ -612,12 +631,12 @@
 	unsigned maxpkt;
 
 	if (index != 0) {
-		maxsize = S3C_DxEPTSIZ_XferSize_LIMIT + 1;
-		maxpkt = S3C_DxEPTSIZ_PktCnt_LIMIT + 1;
+		maxsize = DxEPTSIZ_XferSize_LIMIT + 1;
+		maxpkt = DxEPTSIZ_PktCnt_LIMIT + 1;
 	} else {
 		maxsize = 64+64;
 		if (hs_ep->dir_in)
-			maxpkt = S3C_DIEPTSIZ0_PktCnt_LIMIT + 1;
+			maxpkt = DIEPTSIZ0_PktCnt_LIMIT + 1;
 		else
 			maxpkt = 2;
 	}
@@ -626,8 +645,10 @@
 	maxpkt--;
 	maxsize--;
 
-	/* constrain by packet count if maxpkts*pktsize is greater
-	 * than the length register size. */
+	/*
+	 * constrain by packet count if maxpkts*pktsize is greater
+	 * than the length register size.
+	 */
 
 	if ((maxpkt * hs_ep->ep.maxpacket) < maxsize)
 		maxsize = maxpkt * hs_ep->ep.maxpacket;
@@ -674,8 +695,8 @@
 		}
 	}
 
-	epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index);
-	epsize_reg = dir_in ? S3C_DIEPTSIZ(index) : S3C_DOEPTSIZ(index);
+	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
+	epsize_reg = dir_in ? DIEPTSIZ(index) : DOEPTSIZ(index);
 
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x, ep %d, dir %s\n",
 		__func__, readl(hsotg->regs + epctrl_reg), index,
@@ -684,13 +705,14 @@
 	/* If endpoint is stalled, we will restart request later */
 	ctrl = readl(hsotg->regs + epctrl_reg);
 
-	if (ctrl & S3C_DxEPCTL_Stall) {
+	if (ctrl & DxEPCTL_Stall) {
 		dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
 		return;
 	}
 
 	length = ureq->length - ureq->actual;
-
+	dev_dbg(hsotg->dev, "ureq->length:%d ureq->actual:%d\n",
+		ureq->length, ureq->actual);
 	if (0)
 		dev_dbg(hsotg->dev,
 			"REQ buf %p len %d dma 0x%08x noi=%d zp=%d snok=%d\n",
@@ -717,20 +739,22 @@
 		packets = 1;	/* send one packet if length is zero. */
 
 	if (dir_in && index != 0)
-		epsize = S3C_DxEPTSIZ_MC(1);
+		epsize = DxEPTSIZ_MC(1);
 	else
 		epsize = 0;
 
 	if (index != 0 && ureq->zero) {
-		/* test for the packets being exactly right for the
-		 * transfer */
+		/*
+		 * test for the packets being exactly right for the
+		 * transfer
+		 */
 
 		if (length == (packets * hs_ep->ep.maxpacket))
 			packets++;
 	}
 
-	epsize |= S3C_DxEPTSIZ_PktCnt(packets);
-	epsize |= S3C_DxEPTSIZ_XferSize(length);
+	epsize |= DxEPTSIZ_PktCnt(packets);
+	epsize |= DxEPTSIZ_XferSize(length);
 
 	dev_dbg(hsotg->dev, "%s: %d@%d/%d, 0x%08x => 0x%08x\n",
 		__func__, packets, length, ureq->length, epsize, epsize_reg);
@@ -744,26 +768,38 @@
 	if (using_dma(hsotg) && !continuing) {
 		unsigned int dma_reg;
 
-		/* write DMA address to control register, buffer already
-		 * synced by s3c_hsotg_ep_queue().  */
+		/*
+		 * write DMA address to control register, buffer already
+		 * synced by s3c_hsotg_ep_queue().
+		 */
 
-		dma_reg = dir_in ? S3C_DIEPDMA(index) : S3C_DOEPDMA(index);
+		dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index);
 		writel(ureq->dma, hsotg->regs + dma_reg);
 
 		dev_dbg(hsotg->dev, "%s: 0x%08x => 0x%08x\n",
 			__func__, ureq->dma, dma_reg);
 	}
 
-	ctrl |= S3C_DxEPCTL_EPEna;	/* ensure ep enabled */
-	ctrl |= S3C_DxEPCTL_USBActEp;
-	ctrl |= S3C_DxEPCTL_CNAK;	/* clear NAK set by core */
+	ctrl |= DxEPCTL_EPEna;	/* ensure ep enabled */
+	ctrl |= DxEPCTL_USBActEp;
+
+	dev_dbg(hsotg->dev, "setup req:%d\n", hsotg->setup);
+
+	/* For Setup request do not clear NAK */
+	if (hsotg->setup && index == 0)
+		hsotg->setup = 0;
+	else
+		ctrl |= DxEPCTL_CNAK;	/* clear NAK set by core */
+
 
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl);
 	writel(ctrl, hsotg->regs + epctrl_reg);
 
-	/* set these, it seems that DMA support increments past the end
+	/*
+	 * set these, it seems that DMA support increments past the end
 	 * of the packet buffer so we need to calculate the length from
-	 * this information. */
+	 * this information.
+	 */
 	hs_ep->size_loaded = length;
 	hs_ep->last_load = ureq->actual;
 
@@ -774,17 +810,21 @@
 		s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req);
 	}
 
-	/* clear the INTknTXFEmpMsk when we start request, more as a aide
-	 * to debugging to see what is going on. */
+	/*
+	 * clear the INTknTXFEmpMsk when we start request, more as a aide
+	 * to debugging to see what is going on.
+	 */
 	if (dir_in)
-		writel(S3C_DIEPMSK_INTknTXFEmpMsk,
-		       hsotg->regs + S3C_DIEPINT(index));
+		writel(DIEPMSK_INTknTXFEmpMsk,
+		       hsotg->regs + DIEPINT(index));
 
-	/* Note, trying to clear the NAK here causes problems with transmit
-	 * on the S3C6400 ending up with the TXFIFO becoming full. */
+	/*
+	 * Note, trying to clear the NAK here causes problems with transmit
+	 * on the S3C6400 ending up with the TXFIFO becoming full.
+	 */
 
 	/* check ep is enabled */
-	if (!(readl(hsotg->regs + epctrl_reg) & S3C_DxEPCTL_EPEna))
+	if (!(readl(hsotg->regs + epctrl_reg) & DxEPCTL_EPEna))
 		dev_warn(hsotg->dev,
 			 "ep%d: failed to become enabled (DxEPCTL=0x%08x)?\n",
 			 index, readl(hsotg->regs + epctrl_reg));
@@ -804,7 +844,7 @@
  * then ensure the buffer has been synced to memory. If our buffer has no
  * DMA memory, then we map the memory and mark our request to allow us to
  * cleanup on completion.
-*/
+ */
 static int s3c_hsotg_map_dma(struct s3c_hsotg *hsotg,
 			     struct s3c_hsotg_ep *hs_ep,
 			     struct usb_request *req)
@@ -922,7 +962,7 @@
  *
  * Convert the given wIndex into a pointer to an driver endpoint
  * structure, or return NULL if it is not a valid endpoint.
-*/
+ */
 static struct s3c_hsotg_ep *ep_from_windex(struct s3c_hsotg *hsotg,
 					   u32 windex)
 {
@@ -933,7 +973,7 @@
 	if (windex >= 0x100)
 		return NULL;
 
-	if (idx > S3C_HSOTG_EPS)
+	if (idx > hsotg->num_of_eps)
 		return NULL;
 
 	if (idx && ep->dir_in != dir)
@@ -1151,24 +1191,28 @@
 		 ctrl->bRequest, ctrl->bRequestType,
 		 ctrl->wValue, ctrl->wLength);
 
-	/* record the direction of the request, for later use when enquing
-	 * packets onto EP0. */
+	/*
+	 * record the direction of the request, for later use when enquing
+	 * packets onto EP0.
+	 */
 
 	ep0->dir_in = (ctrl->bRequestType & USB_DIR_IN) ? 1 : 0;
 	dev_dbg(hsotg->dev, "ctrl: dir_in=%d\n", ep0->dir_in);
 
-	/* if we've no data with this request, then the last part of the
-	 * transaction is going to implicitly be IN. */
+	/*
+	 * if we've no data with this request, then the last part of the
+	 * transaction is going to implicitly be IN.
+	 */
 	if (ctrl->wLength == 0)
 		ep0->dir_in = 1;
 
 	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
 		switch (ctrl->bRequest) {
 		case USB_REQ_SET_ADDRESS:
-			dcfg = readl(hsotg->regs + S3C_DCFG);
-			dcfg &= ~S3C_DCFG_DevAddr_MASK;
-			dcfg |= ctrl->wValue << S3C_DCFG_DevAddr_SHIFT;
-			writel(dcfg, hsotg->regs + S3C_DCFG);
+			dcfg = readl(hsotg->regs + DCFG);
+			dcfg &= ~DCFG_DevAddr_MASK;
+			dcfg |= ctrl->wValue << DCFG_DevAddr_SHIFT;
+			writel(dcfg, hsotg->regs + DCFG);
 
 			dev_info(hsotg->dev, "new address %d\n", ctrl->wValue);
 
@@ -1194,7 +1238,8 @@
 			dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret);
 	}
 
-	/* the request is either unhandlable, or is not formatted correctly
+	/*
+	 * the request is either unhandlable, or is not formatted correctly
 	 * so respond with a STALL for the status stage to indicate failure.
 	 */
 
@@ -1203,22 +1248,26 @@
 		u32 ctrl;
 
 		dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in);
-		reg = (ep0->dir_in) ? S3C_DIEPCTL0 : S3C_DOEPCTL0;
+		reg = (ep0->dir_in) ? DIEPCTL0 : DOEPCTL0;
 
-		/* S3C_DxEPCTL_Stall will be cleared by EP once it has
-		 * taken effect, so no need to clear later. */
+		/*
+		 * DxEPCTL_Stall will be cleared by EP once it has
+		 * taken effect, so no need to clear later.
+		 */
 
 		ctrl = readl(hsotg->regs + reg);
-		ctrl |= S3C_DxEPCTL_Stall;
-		ctrl |= S3C_DxEPCTL_CNAK;
+		ctrl |= DxEPCTL_Stall;
+		ctrl |= DxEPCTL_CNAK;
 		writel(ctrl, hsotg->regs + reg);
 
 		dev_dbg(hsotg->dev,
 			"written DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n",
 			ctrl, reg, readl(hsotg->regs + reg));
 
-		/* don't believe we need to anything more to get the EP
-		 * to reply with a STALL packet */
+		/*
+		 * don't believe we need to anything more to get the EP
+		 * to reply with a STALL packet
+		 */
 	}
 }
 
@@ -1279,8 +1328,10 @@
 	ret = s3c_hsotg_ep_queue(&hsotg->eps[0].ep, req, GFP_ATOMIC);
 	if (ret < 0) {
 		dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret);
-		/* Don't think there's much we can do other than watch the
-		 * driver fail. */
+		/*
+		 * Don't think there's much we can do other than watch the
+		 * driver fail.
+		 */
 	}
 }
 
@@ -1296,7 +1347,7 @@
  * on the endpoint.
  *
  * Note, expects the ep to already be locked as appropriate.
-*/
+ */
 static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg,
 				       struct s3c_hsotg_ep *hs_ep,
 				       struct s3c_hsotg_req *hs_req,
@@ -1312,8 +1363,10 @@
 	dev_dbg(hsotg->dev, "complete: ep %p %s, req %p, %d => %p\n",
 		hs_ep, hs_ep->ep.name, hs_req, result, hs_req->req.complete);
 
-	/* only replace the status if we've not already set an error
-	 * from a previous transaction */
+	/*
+	 * only replace the status if we've not already set an error
+	 * from a previous transaction
+	 */
 
 	if (hs_req->req.status == -EINPROGRESS)
 		hs_req->req.status = result;
@@ -1324,8 +1377,10 @@
 	if (using_dma(hsotg))
 		s3c_hsotg_unmap_dma(hsotg, hs_ep, hs_req);
 
-	/* call the complete request with the locks off, just in case the
-	 * request tries to queue more work for this endpoint. */
+	/*
+	 * call the complete request with the locks off, just in case the
+	 * request tries to queue more work for this endpoint.
+	 */
 
 	if (hs_req->req.complete) {
 		spin_unlock(&hs_ep->lock);
@@ -1333,9 +1388,11 @@
 		spin_lock(&hs_ep->lock);
 	}
 
-	/* Look to see if there is anything else to do. Note, the completion
+	/*
+	 * Look to see if there is anything else to do. Note, the completion
 	 * of the previous request may have caused a new request to be started
-	 * so be careful when doing this. */
+	 * so be careful when doing this.
+	 */
 
 	if (!hs_ep->req && result >= 0) {
 		restart = !list_empty(&hs_ep->queue);
@@ -1355,7 +1412,7 @@
  *
  * See s3c_hsotg_complete_request(), but called with the endpoint's
  * lock held.
-*/
+ */
 static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg,
 					    struct s3c_hsotg_ep *hs_ep,
 					    struct s3c_hsotg_req *hs_req,
@@ -1382,13 +1439,13 @@
 {
 	struct s3c_hsotg_ep *hs_ep = &hsotg->eps[ep_idx];
 	struct s3c_hsotg_req *hs_req = hs_ep->req;
-	void __iomem *fifo = hsotg->regs + S3C_EPFIFO(ep_idx);
+	void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx);
 	int to_read;
 	int max_req;
 	int read_ptr;
 
 	if (!hs_req) {
-		u32 epctl = readl(hsotg->regs + S3C_DOEPCTL(ep_idx));
+		u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx));
 		int ptr;
 
 		dev_warn(hsotg->dev,
@@ -1412,7 +1469,8 @@
 		__func__, to_read, max_req, read_ptr, hs_req->req.length);
 
 	if (to_read > max_req) {
-		/* more data appeared than we where willing
+		/*
+		 * more data appeared than we where willing
 		 * to deal with in this request.
 		 */
 
@@ -1424,8 +1482,10 @@
 	hs_req->req.actual += to_read;
 	to_read = DIV_ROUND_UP(to_read, 4);
 
-	/* note, we might over-write the buffer end by 3 bytes depending on
-	 * alignment of the data. */
+	/*
+	 * note, we might over-write the buffer end by 3 bytes depending on
+	 * alignment of the data.
+	 */
 	readsl(fifo, hs_req->req.buf + read_ptr, to_read);
 
 	spin_unlock(&hs_ep->lock);
@@ -1465,14 +1525,14 @@
 	dev_dbg(hsotg->dev, "sending zero-length packet\n");
 
 	/* issue a zero-sized packet to terminate this */
-	writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) |
-	       S3C_DxEPTSIZ_XferSize(0), hsotg->regs + S3C_DIEPTSIZ(0));
+	writel(DxEPTSIZ_MC(1) | DxEPTSIZ_PktCnt(1) |
+	       DxEPTSIZ_XferSize(0), hsotg->regs + DIEPTSIZ(0));
 
-	ctrl = readl(hsotg->regs + S3C_DIEPCTL0);
-	ctrl |= S3C_DxEPCTL_CNAK;  /* clear NAK set by core */
-	ctrl |= S3C_DxEPCTL_EPEna; /* ensure ep enabled */
-	ctrl |= S3C_DxEPCTL_USBActEp;
-	writel(ctrl, hsotg->regs + S3C_DIEPCTL0);
+	ctrl = readl(hsotg->regs + DIEPCTL0);
+	ctrl |= DxEPCTL_CNAK;  /* clear NAK set by core */
+	ctrl |= DxEPCTL_EPEna; /* ensure ep enabled */
+	ctrl |= DxEPCTL_USBActEp;
+	writel(ctrl, hsotg->regs + DIEPCTL0);
 }
 
 /**
@@ -1484,15 +1544,15 @@
  * The RXFIFO has delivered an OutDone event, which means that the data
  * transfer for an OUT endpoint has been completed, either by a short
  * packet or by the finish of a transfer.
-*/
+ */
 static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg,
 				     int epnum, bool was_setup)
 {
-	u32 epsize = readl(hsotg->regs + S3C_DOEPTSIZ(epnum));
+	u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum));
 	struct s3c_hsotg_ep *hs_ep = &hsotg->eps[epnum];
 	struct s3c_hsotg_req *hs_req = hs_ep->req;
 	struct usb_request *req = &hs_req->req;
-	unsigned size_left = S3C_DxEPTSIZ_XferSize_GET(epsize);
+	unsigned size_left = DxEPTSIZ_XferSize_GET(epsize);
 	int result = 0;
 
 	if (!hs_req) {
@@ -1503,7 +1563,8 @@
 	if (using_dma(hsotg)) {
 		unsigned size_done;
 
-		/* Calculate the size of the transfer by checking how much
+		/*
+		 * Calculate the size of the transfer by checking how much
 		 * is left in the endpoint size register and then working it
 		 * out from the amount we loaded for the transfer.
 		 *
@@ -1521,17 +1582,29 @@
 	if (req->actual < req->length && size_left == 0) {
 		s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true);
 		return;
+	} else if (epnum == 0) {
+		/*
+		 * After was_setup = 1 =>
+		 * set CNAK for non Setup requests
+		 */
+		hsotg->setup = was_setup ? 0 : 1;
 	}
 
 	if (req->actual < req->length && req->short_not_ok) {
 		dev_dbg(hsotg->dev, "%s: got %d/%d (short not ok) => error\n",
 			__func__, req->actual, req->length);
 
-		/* todo - what should we return here? there's no one else
-		 * even bothering to check the status. */
+		/*
+		 * todo - what should we return here? there's no one else
+		 * even bothering to check the status.
+		 */
 	}
 
 	if (epnum == 0) {
+		/*
+		 * Condition req->complete != s3c_hsotg_complete_setup says:
+		 * send ZLP when we have an asynchronous request from gadget
+		 */
 		if (!was_setup && req->complete != s3c_hsotg_complete_setup)
 			s3c_hsotg_send_zlp(hsotg, hs_req);
 	}
@@ -1544,14 +1617,14 @@
  * @hsotg: The device instance
  *
  * Return the current frame number
-*/
+ */
 static u32 s3c_hsotg_read_frameno(struct s3c_hsotg *hsotg)
 {
 	u32 dsts;
 
-	dsts = readl(hsotg->regs + S3C_DSTS);
-	dsts &= S3C_DSTS_SOFFN_MASK;
-	dsts >>= S3C_DSTS_SOFFN_SHIFT;
+	dsts = readl(hsotg->regs + DSTS);
+	dsts &= DSTS_SOFFN_MASK;
+	dsts >>= DSTS_SOFFN_SHIFT;
 
 	return dsts;
 }
@@ -1574,29 +1647,29 @@
  */
 static void s3c_hsotg_handle_rx(struct s3c_hsotg *hsotg)
 {
-	u32 grxstsr = readl(hsotg->regs + S3C_GRXSTSP);
+	u32 grxstsr = readl(hsotg->regs + GRXSTSP);
 	u32 epnum, status, size;
 
 	WARN_ON(using_dma(hsotg));
 
-	epnum = grxstsr & S3C_GRXSTS_EPNum_MASK;
-	status = grxstsr & S3C_GRXSTS_PktSts_MASK;
+	epnum = grxstsr & GRXSTS_EPNum_MASK;
+	status = grxstsr & GRXSTS_PktSts_MASK;
 
-	size = grxstsr & S3C_GRXSTS_ByteCnt_MASK;
-	size >>= S3C_GRXSTS_ByteCnt_SHIFT;
+	size = grxstsr & GRXSTS_ByteCnt_MASK;
+	size >>= GRXSTS_ByteCnt_SHIFT;
 
 	if (1)
 		dev_dbg(hsotg->dev, "%s: GRXSTSP=0x%08x (%d@%d)\n",
 			__func__, grxstsr, size, epnum);
 
-#define __status(x) ((x) >> S3C_GRXSTS_PktSts_SHIFT)
+#define __status(x) ((x) >> GRXSTS_PktSts_SHIFT)
 
-	switch (status >> S3C_GRXSTS_PktSts_SHIFT) {
-	case __status(S3C_GRXSTS_PktSts_GlobalOutNAK):
+	switch (status >> GRXSTS_PktSts_SHIFT) {
+	case __status(GRXSTS_PktSts_GlobalOutNAK):
 		dev_dbg(hsotg->dev, "GlobalOutNAK\n");
 		break;
 
-	case __status(S3C_GRXSTS_PktSts_OutDone):
+	case __status(GRXSTS_PktSts_OutDone):
 		dev_dbg(hsotg->dev, "OutDone (Frame=0x%08x)\n",
 			s3c_hsotg_read_frameno(hsotg));
 
@@ -1604,24 +1677,24 @@
 			s3c_hsotg_handle_outdone(hsotg, epnum, false);
 		break;
 
-	case __status(S3C_GRXSTS_PktSts_SetupDone):
+	case __status(GRXSTS_PktSts_SetupDone):
 		dev_dbg(hsotg->dev,
 			"SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
 			s3c_hsotg_read_frameno(hsotg),
-			readl(hsotg->regs + S3C_DOEPCTL(0)));
+			readl(hsotg->regs + DOEPCTL(0)));
 
 		s3c_hsotg_handle_outdone(hsotg, epnum, true);
 		break;
 
-	case __status(S3C_GRXSTS_PktSts_OutRX):
+	case __status(GRXSTS_PktSts_OutRX):
 		s3c_hsotg_rx_data(hsotg, epnum, size);
 		break;
 
-	case __status(S3C_GRXSTS_PktSts_SetupRX):
+	case __status(GRXSTS_PktSts_SetupRX):
 		dev_dbg(hsotg->dev,
 			"SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
 			s3c_hsotg_read_frameno(hsotg),
-			readl(hsotg->regs + S3C_DOEPCTL(0)));
+			readl(hsotg->regs + DOEPCTL(0)));
 
 		s3c_hsotg_rx_data(hsotg, epnum, size);
 		break;
@@ -1638,18 +1711,18 @@
 /**
  * s3c_hsotg_ep0_mps - turn max packet size into register setting
  * @mps: The maximum packet size in bytes.
-*/
+ */
 static u32 s3c_hsotg_ep0_mps(unsigned int mps)
 {
 	switch (mps) {
 	case 64:
-		return S3C_D0EPCTL_MPS_64;
+		return D0EPCTL_MPS_64;
 	case 32:
-		return S3C_D0EPCTL_MPS_32;
+		return D0EPCTL_MPS_32;
 	case 16:
-		return S3C_D0EPCTL_MPS_16;
+		return D0EPCTL_MPS_16;
 	case 8:
-		return S3C_D0EPCTL_MPS_8;
+		return D0EPCTL_MPS_8;
 	}
 
 	/* bad max packet size, warn and return invalid result */
@@ -1680,7 +1753,7 @@
 		if (mpsval > 3)
 			goto bad_mps;
 	} else {
-		if (mps >= S3C_DxEPCTL_MPS_LIMIT+1)
+		if (mps >= DxEPCTL_MPS_LIMIT+1)
 			goto bad_mps;
 
 		mpsval = mps;
@@ -1688,19 +1761,21 @@
 
 	hs_ep->ep.maxpacket = mps;
 
-	/* update both the in and out endpoint controldir_ registers, even
-	 * if one of the directions may not be in use. */
+	/*
+	 * update both the in and out endpoint controldir_ registers, even
+	 * if one of the directions may not be in use.
+	 */
 
-	reg = readl(regs + S3C_DIEPCTL(ep));
-	reg &= ~S3C_DxEPCTL_MPS_MASK;
+	reg = readl(regs + DIEPCTL(ep));
+	reg &= ~DxEPCTL_MPS_MASK;
 	reg |= mpsval;
-	writel(reg, regs + S3C_DIEPCTL(ep));
+	writel(reg, regs + DIEPCTL(ep));
 
 	if (ep) {
-		reg = readl(regs + S3C_DOEPCTL(ep));
-		reg &= ~S3C_DxEPCTL_MPS_MASK;
+		reg = readl(regs + DOEPCTL(ep));
+		reg &= ~DxEPCTL_MPS_MASK;
 		reg |= mpsval;
-		writel(reg, regs + S3C_DOEPCTL(ep));
+		writel(reg, regs + DOEPCTL(ep));
 	}
 
 	return;
@@ -1719,16 +1794,16 @@
 	int timeout;
 	int val;
 
-	writel(S3C_GRSTCTL_TxFNum(idx) | S3C_GRSTCTL_TxFFlsh,
-		hsotg->regs + S3C_GRSTCTL);
+	writel(GRSTCTL_TxFNum(idx) | GRSTCTL_TxFFlsh,
+		hsotg->regs + GRSTCTL);
 
 	/* wait until the fifo is flushed */
 	timeout = 100;
 
 	while (1) {
-		val = readl(hsotg->regs + S3C_GRSTCTL);
+		val = readl(hsotg->regs + GRSTCTL);
 
-		if ((val & (S3C_GRSTCTL_TxFFlsh)) == 0)
+		if ((val & (GRSTCTL_TxFFlsh)) == 0)
 			break;
 
 		if (--timeout == 0) {
@@ -1778,7 +1853,7 @@
 				  struct s3c_hsotg_ep *hs_ep)
 {
 	struct s3c_hsotg_req *hs_req = hs_ep->req;
-	u32 epsize = readl(hsotg->regs + S3C_DIEPTSIZ(hs_ep->index));
+	u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
 	int size_left, size_done;
 
 	if (!hs_req) {
@@ -1786,7 +1861,15 @@
 		return;
 	}
 
-	/* Calculate the size of the transfer by checking how much is left
+	/* Finish ZLP handling for IN EP0 transactions */
+	if (hsotg->eps[0].sent_zlp) {
+		dev_dbg(hsotg->dev, "zlp packet received\n");
+		s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0);
+		return;
+	}
+
+	/*
+	 * Calculate the size of the transfer by checking how much is left
 	 * in the endpoint size register and then working it out from
 	 * the amount we loaded for the transfer.
 	 *
@@ -1795,7 +1878,7 @@
 	 * aligned).
 	 */
 
-	size_left = S3C_DxEPTSIZ_XferSize_GET(epsize);
+	size_left = DxEPTSIZ_XferSize_GET(epsize);
 
 	size_done = hs_ep->size_loaded - size_left;
 	size_done += hs_ep->last_load;
@@ -1805,9 +1888,28 @@
 			__func__, hs_req->req.actual, size_done);
 
 	hs_req->req.actual = size_done;
+	dev_dbg(hsotg->dev, "req->length:%d req->actual:%d req->zero:%d\n",
+		hs_req->req.length, hs_req->req.actual, hs_req->req.zero);
 
-	/* if we did all of the transfer, and there is more data left
-	 * around, then try restarting the rest of the request */
+	/*
+	 * Check if dealing with Maximum Packet Size(MPS) IN transfer at EP0
+	 * When sent data is a multiple MPS size (e.g. 64B ,128B ,192B
+	 * ,256B ... ), after last MPS sized packet send IN ZLP packet to
+	 * inform the host that no more data is available.
+	 * The state of req.zero member is checked to be sure that the value to
+	 * send is smaller than wValue expected from host.
+	 * Check req.length to NOT send another ZLP when the current one is
+	 * under completion (the one for which this completion has been called).
+	 */
+	if (hs_req->req.length && hs_ep->index == 0 && hs_req->req.zero &&
+	    hs_req->req.length == hs_req->req.actual &&
+	    !(hs_req->req.length % hs_ep->ep.maxpacket)) {
+
+		dev_dbg(hsotg->dev, "ep0 zlp IN packet sent\n");
+		s3c_hsotg_send_zlp(hsotg, hs_req);
+
+		return;
+	}
 
 	if (!size_left && hs_req->req.actual < hs_req->req.length) {
 		dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__);
@@ -1823,14 +1925,14 @@
  * @dir_in: Set if this is an IN endpoint
  *
  * Process and clear any interrupt pending for an individual endpoint
-*/
+ */
 static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
 			    int dir_in)
 {
 	struct s3c_hsotg_ep *hs_ep = &hsotg->eps[idx];
-	u32 epint_reg = dir_in ? S3C_DIEPINT(idx) : S3C_DOEPINT(idx);
-	u32 epctl_reg = dir_in ? S3C_DIEPCTL(idx) : S3C_DOEPCTL(idx);
-	u32 epsiz_reg = dir_in ? S3C_DIEPTSIZ(idx) : S3C_DOEPTSIZ(idx);
+	u32 epint_reg = dir_in ? DIEPINT(idx) : DOEPINT(idx);
+	u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx);
+	u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx);
 	u32 ints;
 
 	ints = readl(hsotg->regs + epint_reg);
@@ -1841,28 +1943,32 @@
 	dev_dbg(hsotg->dev, "%s: ep%d(%s) DxEPINT=0x%08x\n",
 		__func__, idx, dir_in ? "in" : "out", ints);
 
-	if (ints & S3C_DxEPINT_XferCompl) {
+	if (ints & DxEPINT_XferCompl) {
 		dev_dbg(hsotg->dev,
 			"%s: XferCompl: DxEPCTL=0x%08x, DxEPTSIZ=%08x\n",
 			__func__, readl(hsotg->regs + epctl_reg),
 			readl(hsotg->regs + epsiz_reg));
 
-		/* we get OutDone from the FIFO, so we only need to look
-		 * at completing IN requests here */
+		/*
+		 * we get OutDone from the FIFO, so we only need to look
+		 * at completing IN requests here
+		 */
 		if (dir_in) {
 			s3c_hsotg_complete_in(hsotg, hs_ep);
 
 			if (idx == 0 && !hs_ep->req)
 				s3c_hsotg_enqueue_setup(hsotg);
 		} else if (using_dma(hsotg)) {
-			/* We're using DMA, we need to fire an OutDone here
-			 * as we ignore the RXFIFO. */
+			/*
+			 * We're using DMA, we need to fire an OutDone here
+			 * as we ignore the RXFIFO.
+			 */
 
 			s3c_hsotg_handle_outdone(hsotg, idx, false);
 		}
 	}
 
-	if (ints & S3C_DxEPINT_EPDisbld) {
+	if (ints & DxEPINT_EPDisbld) {
 		dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__);
 
 		if (dir_in) {
@@ -1870,27 +1976,29 @@
 
 			s3c_hsotg_txfifo_flush(hsotg, idx);
 
-			if ((epctl & S3C_DxEPCTL_Stall) &&
-				(epctl & S3C_DxEPCTL_EPType_Bulk)) {
-				int dctl = readl(hsotg->regs + S3C_DCTL);
+			if ((epctl & DxEPCTL_Stall) &&
+				(epctl & DxEPCTL_EPType_Bulk)) {
+				int dctl = readl(hsotg->regs + DCTL);
 
-				dctl |= S3C_DCTL_CGNPInNAK;
-				writel(dctl, hsotg->regs + S3C_DCTL);
+				dctl |= DCTL_CGNPInNAK;
+				writel(dctl, hsotg->regs + DCTL);
 			}
 		}
 	}
 
-	if (ints & S3C_DxEPINT_AHBErr)
+	if (ints & DxEPINT_AHBErr)
 		dev_dbg(hsotg->dev, "%s: AHBErr\n", __func__);
 
-	if (ints & S3C_DxEPINT_Setup) {  /* Setup or Timeout */
+	if (ints & DxEPINT_Setup) {  /* Setup or Timeout */
 		dev_dbg(hsotg->dev, "%s: Setup/Timeout\n",  __func__);
 
 		if (using_dma(hsotg) && idx == 0) {
-			/* this is the notification we've received a
+			/*
+			 * this is the notification we've received a
 			 * setup packet. In non-DMA mode we'd get this
 			 * from the RXFIFO, instead we need to process
-			 * the setup here. */
+			 * the setup here.
+			 */
 
 			if (dir_in)
 				WARN_ON_ONCE(1);
@@ -1899,26 +2007,25 @@
 		}
 	}
 
-	if (ints & S3C_DxEPINT_Back2BackSetup)
+	if (ints & DxEPINT_Back2BackSetup)
 		dev_dbg(hsotg->dev, "%s: B2BSetup/INEPNakEff\n", __func__);
 
 	if (dir_in) {
-		/* not sure if this is important, but we'll clear it anyway
-		 */
-		if (ints & S3C_DIEPMSK_INTknTXFEmpMsk) {
+		/* not sure if this is important, but we'll clear it anyway */
+		if (ints & DIEPMSK_INTknTXFEmpMsk) {
 			dev_dbg(hsotg->dev, "%s: ep%d: INTknTXFEmpMsk\n",
 				__func__, idx);
 		}
 
 		/* this probably means something bad is happening */
-		if (ints & S3C_DIEPMSK_INTknEPMisMsk) {
+		if (ints & DIEPMSK_INTknEPMisMsk) {
 			dev_warn(hsotg->dev, "%s: ep%d: INTknEP\n",
 				 __func__, idx);
 		}
 
 		/* FIFO has space or is empty (see GAHBCFG) */
 		if (hsotg->dedicated_fifos &&
-		    ints & S3C_DIEPMSK_TxFIFOEmpty) {
+		    ints & DIEPMSK_TxFIFOEmpty) {
 			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
 				__func__, idx);
 			if (!using_dma(hsotg))
@@ -1933,40 +2040,45 @@
  *
  * Handle updating the device settings after the enumeration phase has
  * been completed.
-*/
+ */
 static void s3c_hsotg_irq_enumdone(struct s3c_hsotg *hsotg)
 {
-	u32 dsts = readl(hsotg->regs + S3C_DSTS);
+	u32 dsts = readl(hsotg->regs + DSTS);
 	int ep0_mps = 0, ep_mps;
 
-	/* This should signal the finish of the enumeration phase
+	/*
+	 * This should signal the finish of the enumeration phase
 	 * of the USB handshaking, so we should now know what rate
-	 * we connected at. */
+	 * we connected at.
+	 */
 
 	dev_dbg(hsotg->dev, "EnumDone (DSTS=0x%08x)\n", dsts);
 
-	/* note, since we're limited by the size of transfer on EP0, and
+	/*
+	 * note, since we're limited by the size of transfer on EP0, and
 	 * it seems IN transfers must be a even number of packets we do
-	 * not advertise a 64byte MPS on EP0. */
+	 * not advertise a 64byte MPS on EP0.
+	 */
 
 	/* catch both EnumSpd_FS and EnumSpd_FS48 */
-	switch (dsts & S3C_DSTS_EnumSpd_MASK) {
-	case S3C_DSTS_EnumSpd_FS:
-	case S3C_DSTS_EnumSpd_FS48:
+	switch (dsts & DSTS_EnumSpd_MASK) {
+	case DSTS_EnumSpd_FS:
+	case DSTS_EnumSpd_FS48:
 		hsotg->gadget.speed = USB_SPEED_FULL;
 		ep0_mps = EP0_MPS_LIMIT;
 		ep_mps = 64;
 		break;
 
-	case S3C_DSTS_EnumSpd_HS:
+	case DSTS_EnumSpd_HS:
 		hsotg->gadget.speed = USB_SPEED_HIGH;
 		ep0_mps = EP0_MPS_LIMIT;
 		ep_mps = 512;
 		break;
 
-	case S3C_DSTS_EnumSpd_LS:
+	case DSTS_EnumSpd_LS:
 		hsotg->gadget.speed = USB_SPEED_LOW;
-		/* note, we don't actually support LS in this driver at the
+		/*
+		 * note, we don't actually support LS in this driver at the
 		 * moment, and the documentation seems to imply that it isn't
 		 * supported by the PHYs on some of the devices.
 		 */
@@ -1975,13 +2087,15 @@
 	dev_info(hsotg->dev, "new device is %s\n",
 		 usb_speed_string(hsotg->gadget.speed));
 
-	/* we should now know the maximum packet size for an
-	 * endpoint, so set the endpoints to a default value. */
+	/*
+	 * we should now know the maximum packet size for an
+	 * endpoint, so set the endpoints to a default value.
+	 */
 
 	if (ep0_mps) {
 		int i;
 		s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps);
-		for (i = 1; i < S3C_HSOTG_EPS; i++)
+		for (i = 1; i < hsotg->num_of_eps; i++)
 			s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps);
 	}
 
@@ -1990,8 +2104,8 @@
 	s3c_hsotg_enqueue_setup(hsotg);
 
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + S3C_DIEPCTL0),
-		readl(hsotg->regs + S3C_DOEPCTL0));
+		readl(hsotg->regs + DIEPCTL0),
+		readl(hsotg->regs + DOEPCTL0));
 }
 
 /**
@@ -2014,8 +2128,10 @@
 	spin_lock_irqsave(&ep->lock, flags);
 
 	list_for_each_entry_safe(req, treq, &ep->queue, queue) {
-		/* currently, we can't do much about an already
-		 * running request on an in endpoint */
+		/*
+		 * currently, we can't do much about an already
+		 * running request on an in endpoint
+		 */
 
 		if (ep->req == req && ep->dir_in && !force)
 			continue;
@@ -2033,18 +2149,18 @@
 		(_hs)->driver->_entry(&(_hs)->gadget);
 
 /**
- * s3c_hsotg_disconnect_irq - disconnect irq service
+ * s3c_hsotg_disconnect - disconnect service
  * @hsotg: The device state.
  *
- * A disconnect IRQ has been received, meaning that the host has
- * lost contact with the bus. Remove all current transactions
- * and signal the gadget driver that this has happened.
-*/
-static void s3c_hsotg_disconnect_irq(struct s3c_hsotg *hsotg)
+ * The device has been disconnected. Remove all current
+ * transactions and signal the gadget driver that this
+ * has happened.
+ */
+static void s3c_hsotg_disconnect(struct s3c_hsotg *hsotg)
 {
 	unsigned ep;
 
-	for (ep = 0; ep < S3C_HSOTG_EPS; ep++)
+	for (ep = 0; ep < hsotg->num_of_eps; ep++)
 		kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true);
 
 	call_gadget(hsotg, disconnect);
@@ -2062,7 +2178,7 @@
 
 	/* look through for any more data to transmit */
 
-	for (epno = 0; epno < S3C_HSOTG_EPS; epno++) {
+	for (epno = 0; epno < hsotg->num_of_eps; epno++) {
 		ep = &hsotg->eps[epno];
 
 		if (!ep->dir_in)
@@ -2078,12 +2194,187 @@
 	}
 }
 
-static struct s3c_hsotg *our_hsotg;
-
 /* IRQ flags which will trigger a retry around the IRQ loop */
-#define IRQ_RETRY_MASK (S3C_GINTSTS_NPTxFEmp | \
-			S3C_GINTSTS_PTxFEmp |  \
-			S3C_GINTSTS_RxFLvl)
+#define IRQ_RETRY_MASK (GINTSTS_NPTxFEmp | \
+			GINTSTS_PTxFEmp |  \
+			GINTSTS_RxFLvl)
+
+/**
+ * s3c_hsotg_corereset - issue softreset to the core
+ * @hsotg: The device state
+ *
+ * Issue a soft reset to the core, and await the core finishing it.
+ */
+static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg)
+{
+	int timeout;
+	u32 grstctl;
+
+	dev_dbg(hsotg->dev, "resetting core\n");
+
+	/* issue soft reset */
+	writel(GRSTCTL_CSftRst, hsotg->regs + GRSTCTL);
+
+	timeout = 1000;
+	do {
+		grstctl = readl(hsotg->regs + GRSTCTL);
+	} while ((grstctl & GRSTCTL_CSftRst) && timeout-- > 0);
+
+	if (grstctl & GRSTCTL_CSftRst) {
+		dev_err(hsotg->dev, "Failed to get CSftRst asserted\n");
+		return -EINVAL;
+	}
+
+	timeout = 1000;
+
+	while (1) {
+		u32 grstctl = readl(hsotg->regs + GRSTCTL);
+
+		if (timeout-- < 0) {
+			dev_info(hsotg->dev,
+				 "%s: reset failed, GRSTCTL=%08x\n",
+				 __func__, grstctl);
+			return -ETIMEDOUT;
+		}
+
+		if (!(grstctl & GRSTCTL_AHBIdle))
+			continue;
+
+		break;		/* reset done */
+	}
+
+	dev_dbg(hsotg->dev, "reset successful\n");
+	return 0;
+}
+
+/**
+ * s3c_hsotg_core_init - issue softreset to the core
+ * @hsotg: The device state
+ *
+ * Issue a soft reset to the core, and await the core finishing it.
+ */
+static void s3c_hsotg_core_init(struct s3c_hsotg *hsotg)
+{
+	s3c_hsotg_corereset(hsotg);
+
+	/*
+	 * we must now enable ep0 ready for host detection and then
+	 * set configuration.
+	 */
+
+	/* set the PLL on, remove the HNP/SRP and set the PHY */
+	writel(GUSBCFG_PHYIf16 | GUSBCFG_TOutCal(7) |
+	       (0x5 << 10), hsotg->regs + GUSBCFG);
+
+	s3c_hsotg_init_fifo(hsotg);
+
+	__orr32(hsotg->regs + DCTL, DCTL_SftDiscon);
+
+	writel(1 << 18 | DCFG_DevSpd_HS,  hsotg->regs + DCFG);
+
+	/* Clear any pending OTG interrupts */
+	writel(0xffffffff, hsotg->regs + GOTGINT);
+
+	/* Clear any pending interrupts */
+	writel(0xffffffff, hsotg->regs + GINTSTS);
+
+	writel(GINTSTS_ErlySusp | GINTSTS_SessReqInt |
+	       GINTSTS_GOUTNakEff | GINTSTS_GINNakEff |
+	       GINTSTS_ConIDStsChng | GINTSTS_USBRst |
+	       GINTSTS_EnumDone | GINTSTS_OTGInt |
+	       GINTSTS_USBSusp | GINTSTS_WkUpInt,
+	       hsotg->regs + GINTMSK);
+
+	if (using_dma(hsotg))
+		writel(GAHBCFG_GlblIntrEn | GAHBCFG_DMAEn |
+		       GAHBCFG_HBstLen_Incr4,
+		       hsotg->regs + GAHBCFG);
+	else
+		writel(GAHBCFG_GlblIntrEn, hsotg->regs + GAHBCFG);
+
+	/*
+	 * Enabling INTknTXFEmpMsk here seems to be a big mistake, we end
+	 * up being flooded with interrupts if the host is polling the
+	 * endpoint to try and read data.
+	 */
+
+	writel(((hsotg->dedicated_fifos) ? DIEPMSK_TxFIFOEmpty : 0) |
+	       DIEPMSK_EPDisbldMsk | DIEPMSK_XferComplMsk |
+	       DIEPMSK_TimeOUTMsk | DIEPMSK_AHBErrMsk |
+	       DIEPMSK_INTknEPMisMsk,
+	       hsotg->regs + DIEPMSK);
+
+	/*
+	 * don't need XferCompl, we get that from RXFIFO in slave mode. In
+	 * DMA mode we may need this.
+	 */
+	writel((using_dma(hsotg) ? (DIEPMSK_XferComplMsk |
+				    DIEPMSK_TimeOUTMsk) : 0) |
+	       DOEPMSK_EPDisbldMsk | DOEPMSK_AHBErrMsk |
+	       DOEPMSK_SetupMsk,
+	       hsotg->regs + DOEPMSK);
+
+	writel(0, hsotg->regs + DAINTMSK);
+
+	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
+		readl(hsotg->regs + DIEPCTL0),
+		readl(hsotg->regs + DOEPCTL0));
+
+	/* enable in and out endpoint interrupts */
+	s3c_hsotg_en_gsint(hsotg, GINTSTS_OEPInt | GINTSTS_IEPInt);
+
+	/*
+	 * Enable the RXFIFO when in slave mode, as this is how we collect
+	 * the data. In DMA mode, we get events from the FIFO but also
+	 * things we cannot process, so do not use it.
+	 */
+	if (!using_dma(hsotg))
+		s3c_hsotg_en_gsint(hsotg, GINTSTS_RxFLvl);
+
+	/* Enable interrupts for EP0 in and out */
+	s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1);
+	s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1);
+
+	__orr32(hsotg->regs + DCTL, DCTL_PWROnPrgDone);
+	udelay(10);  /* see openiboot */
+	__bic32(hsotg->regs + DCTL, DCTL_PWROnPrgDone);
+
+	dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL));
+
+	/*
+	 * DxEPCTL_USBActEp says RO in manual, but seems to be set by
+	 * writing to the EPCTL register..
+	 */
+
+	/* set to read 1 8byte packet */
+	writel(DxEPTSIZ_MC(1) | DxEPTSIZ_PktCnt(1) |
+	       DxEPTSIZ_XferSize(8), hsotg->regs + DOEPTSIZ0);
+
+	writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) |
+	       DxEPCTL_CNAK | DxEPCTL_EPEna |
+	       DxEPCTL_USBActEp,
+	       hsotg->regs + DOEPCTL0);
+
+	/* enable, but don't activate EP0in */
+	writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) |
+	       DxEPCTL_USBActEp, hsotg->regs + DIEPCTL0);
+
+	s3c_hsotg_enqueue_setup(hsotg);
+
+	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
+		readl(hsotg->regs + DIEPCTL0),
+		readl(hsotg->regs + DOEPCTL0));
+
+	/* clear global NAKs */
+	writel(DCTL_CGOUTNak | DCTL_CGNPInNAK,
+	       hsotg->regs + DCTL);
+
+	/* must be at-least 3ms to allow bus to see disconnect */
+	mdelay(3);
+
+	/* remove the soft-disconnect and let's go */
+	__bic32(hsotg->regs + DCTL, DCTL_SftDiscon);
+}
 
 /**
  * s3c_hsotg_irq - handle device interrupt
@@ -2098,52 +2389,45 @@
 	u32 gintmsk;
 
 irq_retry:
-	gintsts = readl(hsotg->regs + S3C_GINTSTS);
-	gintmsk = readl(hsotg->regs + S3C_GINTMSK);
+	gintsts = readl(hsotg->regs + GINTSTS);
+	gintmsk = readl(hsotg->regs + GINTMSK);
 
 	dev_dbg(hsotg->dev, "%s: %08x %08x (%08x) retry %d\n",
 		__func__, gintsts, gintsts & gintmsk, gintmsk, retry_count);
 
 	gintsts &= gintmsk;
 
-	if (gintsts & S3C_GINTSTS_OTGInt) {
-		u32 otgint = readl(hsotg->regs + S3C_GOTGINT);
+	if (gintsts & GINTSTS_OTGInt) {
+		u32 otgint = readl(hsotg->regs + GOTGINT);
 
 		dev_info(hsotg->dev, "OTGInt: %08x\n", otgint);
 
-		writel(otgint, hsotg->regs + S3C_GOTGINT);
+		writel(otgint, hsotg->regs + GOTGINT);
 	}
 
-	if (gintsts & S3C_GINTSTS_DisconnInt) {
-		dev_dbg(hsotg->dev, "%s: DisconnInt\n", __func__);
-		writel(S3C_GINTSTS_DisconnInt, hsotg->regs + S3C_GINTSTS);
-
-		s3c_hsotg_disconnect_irq(hsotg);
-	}
-
-	if (gintsts & S3C_GINTSTS_SessReqInt) {
+	if (gintsts & GINTSTS_SessReqInt) {
 		dev_dbg(hsotg->dev, "%s: SessReqInt\n", __func__);
-		writel(S3C_GINTSTS_SessReqInt, hsotg->regs + S3C_GINTSTS);
+		writel(GINTSTS_SessReqInt, hsotg->regs + GINTSTS);
 	}
 
-	if (gintsts & S3C_GINTSTS_EnumDone) {
-		writel(S3C_GINTSTS_EnumDone, hsotg->regs + S3C_GINTSTS);
+	if (gintsts & GINTSTS_EnumDone) {
+		writel(GINTSTS_EnumDone, hsotg->regs + GINTSTS);
 
 		s3c_hsotg_irq_enumdone(hsotg);
 	}
 
-	if (gintsts & S3C_GINTSTS_ConIDStsChng) {
+	if (gintsts & GINTSTS_ConIDStsChng) {
 		dev_dbg(hsotg->dev, "ConIDStsChg (DSTS=0x%08x, GOTCTL=%08x)\n",
-			readl(hsotg->regs + S3C_DSTS),
-			readl(hsotg->regs + S3C_GOTGCTL));
+			readl(hsotg->regs + DSTS),
+			readl(hsotg->regs + GOTGCTL));
 
-		writel(S3C_GINTSTS_ConIDStsChng, hsotg->regs + S3C_GINTSTS);
+		writel(GINTSTS_ConIDStsChng, hsotg->regs + GINTSTS);
 	}
 
-	if (gintsts & (S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt)) {
-		u32 daint = readl(hsotg->regs + S3C_DAINT);
-		u32 daint_out = daint >> S3C_DAINT_OutEP_SHIFT;
-		u32 daint_in = daint & ~(daint_out << S3C_DAINT_OutEP_SHIFT);
+	if (gintsts & (GINTSTS_OEPInt | GINTSTS_IEPInt)) {
+		u32 daint = readl(hsotg->regs + DAINT);
+		u32 daint_out = daint >> DAINT_OutEP_SHIFT;
+		u32 daint_in = daint & ~(daint_out << DAINT_OutEP_SHIFT);
 		int ep;
 
 		dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
@@ -2159,102 +2443,116 @@
 		}
 	}
 
-	if (gintsts & S3C_GINTSTS_USBRst) {
+	if (gintsts & GINTSTS_USBRst) {
+
+		u32 usb_status = readl(hsotg->regs + GOTGCTL);
+
 		dev_info(hsotg->dev, "%s: USBRst\n", __func__);
 		dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
-			readl(hsotg->regs + S3C_GNPTXSTS));
+			readl(hsotg->regs + GNPTXSTS));
 
-		writel(S3C_GINTSTS_USBRst, hsotg->regs + S3C_GINTSTS);
+		writel(GINTSTS_USBRst, hsotg->regs + GINTSTS);
 
-		kill_all_requests(hsotg, &hsotg->eps[0], -ECONNRESET, true);
+		if (usb_status & GOTGCTL_BSESVLD) {
+			if (time_after(jiffies, hsotg->last_rst +
+				       msecs_to_jiffies(200))) {
 
-		/* it seems after a reset we can end up with a situation
-		 * where the TXFIFO still has data in it... the docs
-		 * suggest resetting all the fifos, so use the init_fifo
-		 * code to relayout and flush the fifos.
-		 */
+				kill_all_requests(hsotg, &hsotg->eps[0],
+							  -ECONNRESET, true);
 
-		s3c_hsotg_init_fifo(hsotg);
-
-		s3c_hsotg_enqueue_setup(hsotg);
+				s3c_hsotg_core_init(hsotg);
+				hsotg->last_rst = jiffies;
+			}
+		}
 	}
 
 	/* check both FIFOs */
 
-	if (gintsts & S3C_GINTSTS_NPTxFEmp) {
+	if (gintsts & GINTSTS_NPTxFEmp) {
 		dev_dbg(hsotg->dev, "NPTxFEmp\n");
 
-		/* Disable the interrupt to stop it happening again
+		/*
+		 * Disable the interrupt to stop it happening again
 		 * unless one of these endpoint routines decides that
-		 * it needs re-enabling */
+		 * it needs re-enabling
+		 */
 
-		s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_NPTxFEmp);
+		s3c_hsotg_disable_gsint(hsotg, GINTSTS_NPTxFEmp);
 		s3c_hsotg_irq_fifoempty(hsotg, false);
 	}
 
-	if (gintsts & S3C_GINTSTS_PTxFEmp) {
+	if (gintsts & GINTSTS_PTxFEmp) {
 		dev_dbg(hsotg->dev, "PTxFEmp\n");
 
-		/* See note in S3C_GINTSTS_NPTxFEmp */
+		/* See note in GINTSTS_NPTxFEmp */
 
-		s3c_hsotg_disable_gsint(hsotg, S3C_GINTSTS_PTxFEmp);
+		s3c_hsotg_disable_gsint(hsotg, GINTSTS_PTxFEmp);
 		s3c_hsotg_irq_fifoempty(hsotg, true);
 	}
 
-	if (gintsts & S3C_GINTSTS_RxFLvl) {
-		/* note, since GINTSTS_RxFLvl doubles as FIFO-not-empty,
+	if (gintsts & GINTSTS_RxFLvl) {
+		/*
+		 * note, since GINTSTS_RxFLvl doubles as FIFO-not-empty,
 		 * we need to retry s3c_hsotg_handle_rx if this is still
-		 * set. */
+		 * set.
+		 */
 
 		s3c_hsotg_handle_rx(hsotg);
 	}
 
-	if (gintsts & S3C_GINTSTS_ModeMis) {
+	if (gintsts & GINTSTS_ModeMis) {
 		dev_warn(hsotg->dev, "warning, mode mismatch triggered\n");
-		writel(S3C_GINTSTS_ModeMis, hsotg->regs + S3C_GINTSTS);
+		writel(GINTSTS_ModeMis, hsotg->regs + GINTSTS);
 	}
 
-	if (gintsts & S3C_GINTSTS_USBSusp) {
-		dev_info(hsotg->dev, "S3C_GINTSTS_USBSusp\n");
-		writel(S3C_GINTSTS_USBSusp, hsotg->regs + S3C_GINTSTS);
+	if (gintsts & GINTSTS_USBSusp) {
+		dev_info(hsotg->dev, "GINTSTS_USBSusp\n");
+		writel(GINTSTS_USBSusp, hsotg->regs + GINTSTS);
 
 		call_gadget(hsotg, suspend);
+		s3c_hsotg_disconnect(hsotg);
 	}
 
-	if (gintsts & S3C_GINTSTS_WkUpInt) {
-		dev_info(hsotg->dev, "S3C_GINTSTS_WkUpIn\n");
-		writel(S3C_GINTSTS_WkUpInt, hsotg->regs + S3C_GINTSTS);
+	if (gintsts & GINTSTS_WkUpInt) {
+		dev_info(hsotg->dev, "GINTSTS_WkUpIn\n");
+		writel(GINTSTS_WkUpInt, hsotg->regs + GINTSTS);
 
 		call_gadget(hsotg, resume);
 	}
 
-	if (gintsts & S3C_GINTSTS_ErlySusp) {
-		dev_dbg(hsotg->dev, "S3C_GINTSTS_ErlySusp\n");
-		writel(S3C_GINTSTS_ErlySusp, hsotg->regs + S3C_GINTSTS);
+	if (gintsts & GINTSTS_ErlySusp) {
+		dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
+		writel(GINTSTS_ErlySusp, hsotg->regs + GINTSTS);
+
+		s3c_hsotg_disconnect(hsotg);
 	}
 
-	/* these next two seem to crop-up occasionally causing the core
+	/*
+	 * these next two seem to crop-up occasionally causing the core
 	 * to shutdown the USB transfer, so try clearing them and logging
-	 * the occurrence. */
+	 * the occurrence.
+	 */
 
-	if (gintsts & S3C_GINTSTS_GOUTNakEff) {
+	if (gintsts & GINTSTS_GOUTNakEff) {
 		dev_info(hsotg->dev, "GOUTNakEff triggered\n");
 
-		writel(S3C_DCTL_CGOUTNak, hsotg->regs + S3C_DCTL);
+		writel(DCTL_CGOUTNak, hsotg->regs + DCTL);
 
 		s3c_hsotg_dump(hsotg);
 	}
 
-	if (gintsts & S3C_GINTSTS_GINNakEff) {
+	if (gintsts & GINTSTS_GINNakEff) {
 		dev_info(hsotg->dev, "GINNakEff triggered\n");
 
-		writel(S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL);
+		writel(DCTL_CGNPInNAK, hsotg->regs + DCTL);
 
 		s3c_hsotg_dump(hsotg);
 	}
 
-	/* if we've had fifo events, we should try and go around the
-	 * loop again to see if there's any point in returning yet. */
+	/*
+	 * if we've had fifo events, we should try and go around the
+	 * loop again to see if there's any point in returning yet.
+	 */
 
 	if (gintsts & IRQ_RETRY_MASK && --retry_count > 0)
 			goto irq_retry;
@@ -2268,7 +2566,7 @@
  * @desc: The USB endpoint descriptor to configure with.
  *
  * This is called from the USB gadget code's usb_ep_enable().
-*/
+ */
 static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 			       const struct usb_endpoint_descriptor *desc)
 {
@@ -2300,7 +2598,7 @@
 
 	/* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */
 
-	epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index);
+	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
 	epctrl = readl(hsotg->regs + epctrl_reg);
 
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n",
@@ -2308,20 +2606,23 @@
 
 	spin_lock_irqsave(&hs_ep->lock, flags);
 
-	epctrl &= ~(S3C_DxEPCTL_EPType_MASK | S3C_DxEPCTL_MPS_MASK);
-	epctrl |= S3C_DxEPCTL_MPS(mps);
+	epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK);
+	epctrl |= DxEPCTL_MPS(mps);
 
-	/* mark the endpoint as active, otherwise the core may ignore
-	 * transactions entirely for this endpoint */
-	epctrl |= S3C_DxEPCTL_USBActEp;
+	/*
+	 * mark the endpoint as active, otherwise the core may ignore
+	 * transactions entirely for this endpoint
+	 */
+	epctrl |= DxEPCTL_USBActEp;
 
-	/* set the NAK status on the endpoint, otherwise we might try and
+	/*
+	 * set the NAK status on the endpoint, otherwise we might try and
 	 * do something with data that we've yet got a request to process
 	 * since the RXFIFO will take data for an endpoint even if the
 	 * size register hasn't been set.
 	 */
 
-	epctrl |= S3C_DxEPCTL_SNAK;
+	epctrl |= DxEPCTL_SNAK;
 
 	/* update the endpoint state */
 	hs_ep->ep.maxpacket = mps;
@@ -2336,37 +2637,40 @@
 		goto out;
 
 	case USB_ENDPOINT_XFER_BULK:
-		epctrl |= S3C_DxEPCTL_EPType_Bulk;
+		epctrl |= DxEPCTL_EPType_Bulk;
 		break;
 
 	case USB_ENDPOINT_XFER_INT:
 		if (dir_in) {
-			/* Allocate our TxFNum by simply using the index
+			/*
+			 * Allocate our TxFNum by simply using the index
 			 * of the endpoint for the moment. We could do
 			 * something better if the host indicates how
-			 * many FIFOs we are expecting to use. */
+			 * many FIFOs we are expecting to use.
+			 */
 
 			hs_ep->periodic = 1;
-			epctrl |= S3C_DxEPCTL_TxFNum(index);
+			epctrl |= DxEPCTL_TxFNum(index);
 		}
 
-		epctrl |= S3C_DxEPCTL_EPType_Intterupt;
+		epctrl |= DxEPCTL_EPType_Intterupt;
 		break;
 
 	case USB_ENDPOINT_XFER_CONTROL:
-		epctrl |= S3C_DxEPCTL_EPType_Control;
+		epctrl |= DxEPCTL_EPType_Control;
 		break;
 	}
 
-	/* if the hardware has dedicated fifos, we must give each IN EP
+	/*
+	 * if the hardware has dedicated fifos, we must give each IN EP
 	 * a unique tx-fifo even if it is non-periodic.
 	 */
 	if (dir_in && hsotg->dedicated_fifos)
-		epctrl |= S3C_DxEPCTL_TxFNum(index);
+		epctrl |= DxEPCTL_TxFNum(index);
 
 	/* for non control endpoints, set PID to D0 */
 	if (index)
-		epctrl |= S3C_DxEPCTL_SetD0PID;
+		epctrl |= DxEPCTL_SetD0PID;
 
 	dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n",
 		__func__, epctrl);
@@ -2383,6 +2687,10 @@
 	return ret;
 }
 
+/**
+ * s3c_hsotg_ep_disable - disable given endpoint
+ * @ep: The endpoint to disable.
+ */
 static int s3c_hsotg_ep_disable(struct usb_ep *ep)
 {
 	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
@@ -2400,7 +2708,7 @@
 		return -EINVAL;
 	}
 
-	epctrl_reg = dir_in ? S3C_DIEPCTL(index) : S3C_DOEPCTL(index);
+	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
 
 	/* terminate all requests with shutdown */
 	kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false);
@@ -2408,9 +2716,9 @@
 	spin_lock_irqsave(&hs_ep->lock, flags);
 
 	ctrl = readl(hsotg->regs + epctrl_reg);
-	ctrl &= ~S3C_DxEPCTL_EPEna;
-	ctrl &= ~S3C_DxEPCTL_USBActEp;
-	ctrl |= S3C_DxEPCTL_SNAK;
+	ctrl &= ~DxEPCTL_EPEna;
+	ctrl &= ~DxEPCTL_USBActEp;
+	ctrl |= DxEPCTL_SNAK;
 
 	dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl);
 	writel(ctrl, hsotg->regs + epctrl_reg);
@@ -2426,7 +2734,7 @@
  * on_list - check request is on the given endpoint
  * @ep: The endpoint to check.
  * @test: The request to test if it is on the endpoint.
-*/
+ */
 static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test)
 {
 	struct s3c_hsotg_req *req, *treq;
@@ -2439,6 +2747,11 @@
 	return false;
 }
 
+/**
+ * s3c_hsotg_ep_dequeue - dequeue given endpoint
+ * @ep: The endpoint to dequeue.
+ * @req: The request to be removed from a queue.
+ */
 static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
 {
 	struct s3c_hsotg_req *hs_req = our_req(req);
@@ -2461,6 +2774,11 @@
 	return 0;
 }
 
+/**
+ * s3c_hsotg_ep_sethalt - set halt on a given endpoint
+ * @ep: The endpoint to set halt.
+ * @value: Set or unset the halt.
+ */
 static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 {
 	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
@@ -2477,34 +2795,34 @@
 
 	/* write both IN and OUT control registers */
 
-	epreg = S3C_DIEPCTL(index);
+	epreg = DIEPCTL(index);
 	epctl = readl(hs->regs + epreg);
 
 	if (value) {
-		epctl |= S3C_DxEPCTL_Stall + S3C_DxEPCTL_SNAK;
-		if (epctl & S3C_DxEPCTL_EPEna)
-			epctl |= S3C_DxEPCTL_EPDis;
+		epctl |= DxEPCTL_Stall + DxEPCTL_SNAK;
+		if (epctl & DxEPCTL_EPEna)
+			epctl |= DxEPCTL_EPDis;
 	} else {
-		epctl &= ~S3C_DxEPCTL_Stall;
-		xfertype = epctl & S3C_DxEPCTL_EPType_MASK;
-		if (xfertype == S3C_DxEPCTL_EPType_Bulk ||
-			xfertype == S3C_DxEPCTL_EPType_Intterupt)
-				epctl |= S3C_DxEPCTL_SetD0PID;
+		epctl &= ~DxEPCTL_Stall;
+		xfertype = epctl & DxEPCTL_EPType_MASK;
+		if (xfertype == DxEPCTL_EPType_Bulk ||
+			xfertype == DxEPCTL_EPType_Intterupt)
+				epctl |= DxEPCTL_SetD0PID;
 	}
 
 	writel(epctl, hs->regs + epreg);
 
-	epreg = S3C_DOEPCTL(index);
+	epreg = DOEPCTL(index);
 	epctl = readl(hs->regs + epreg);
 
 	if (value)
-		epctl |= S3C_DxEPCTL_Stall;
+		epctl |= DxEPCTL_Stall;
 	else {
-		epctl &= ~S3C_DxEPCTL_Stall;
-		xfertype = epctl & S3C_DxEPCTL_EPType_MASK;
-		if (xfertype == S3C_DxEPCTL_EPType_Bulk ||
-			xfertype == S3C_DxEPCTL_EPType_Intterupt)
-				epctl |= S3C_DxEPCTL_SetD0PID;
+		epctl &= ~DxEPCTL_Stall;
+		xfertype = epctl & DxEPCTL_EPType_MASK;
+		if (xfertype == DxEPCTL_EPType_Bulk ||
+			xfertype == DxEPCTL_EPType_Intterupt)
+				epctl |= DxEPCTL_SetD0PID;
 	}
 
 	writel(epctl, hs->regs + epreg);
@@ -2526,57 +2844,91 @@
 };
 
 /**
- * s3c_hsotg_corereset - issue softreset to the core
- * @hsotg: The device state
+ * s3c_hsotg_phy_enable - enable platform phy dev
+ * @hsotg: The driver state
  *
- * Issue a soft reset to the core, and await the core finishing it.
-*/
-static int s3c_hsotg_corereset(struct s3c_hsotg *hsotg)
+ * A wrapper for platform code responsible for controlling
+ * low-level USB code
+ */
+static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
 {
-	int timeout;
-	u32 grstctl;
+	struct platform_device *pdev = to_platform_device(hsotg->dev);
 
-	dev_dbg(hsotg->dev, "resetting core\n");
-
-	/* issue soft reset */
-	writel(S3C_GRSTCTL_CSftRst, hsotg->regs + S3C_GRSTCTL);
-
-	timeout = 1000;
-	do {
-		grstctl = readl(hsotg->regs + S3C_GRSTCTL);
-	} while ((grstctl & S3C_GRSTCTL_CSftRst) && timeout-- > 0);
-
-	if (grstctl & S3C_GRSTCTL_CSftRst) {
-		dev_err(hsotg->dev, "Failed to get CSftRst asserted\n");
-		return -EINVAL;
-	}
-
-	timeout = 1000;
-
-	while (1) {
-		u32 grstctl = readl(hsotg->regs + S3C_GRSTCTL);
-
-		if (timeout-- < 0) {
-			dev_info(hsotg->dev,
-				 "%s: reset failed, GRSTCTL=%08x\n",
-				 __func__, grstctl);
-			return -ETIMEDOUT;
-		}
-
-		if (!(grstctl & S3C_GRSTCTL_AHBIdle))
-			continue;
-
-		break;		/* reset done */
-	}
-
-	dev_dbg(hsotg->dev, "reset successful\n");
-	return 0;
+	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
+	if (hsotg->plat->phy_init)
+		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
 }
 
-static int s3c_hsotg_start(struct usb_gadget_driver *driver,
-		int (*bind)(struct usb_gadget *))
+/**
+ * s3c_hsotg_phy_disable - disable platform phy dev
+ * @hsotg: The driver state
+ *
+ * A wrapper for platform code responsible for controlling
+ * low-level USB code
+ */
+static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
 {
-	struct s3c_hsotg *hsotg = our_hsotg;
+	struct platform_device *pdev = to_platform_device(hsotg->dev);
+
+	if (hsotg->plat->phy_exit)
+		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
+}
+
+/**
+ * s3c_hsotg_init - initalize the usb core
+ * @hsotg: The driver state
+ */
+static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
+{
+	/* unmask subset of endpoint interrupts */
+
+	writel(DIEPMSK_TimeOUTMsk | DIEPMSK_AHBErrMsk |
+	       DIEPMSK_EPDisbldMsk | DIEPMSK_XferComplMsk,
+	       hsotg->regs + DIEPMSK);
+
+	writel(DOEPMSK_SetupMsk | DOEPMSK_AHBErrMsk |
+	       DOEPMSK_EPDisbldMsk | DOEPMSK_XferComplMsk,
+	       hsotg->regs + DOEPMSK);
+
+	writel(0, hsotg->regs + DAINTMSK);
+
+	/* Be in disconnected state until gadget is registered */
+	__orr32(hsotg->regs + DCTL, DCTL_SftDiscon);
+
+	if (0) {
+		/* post global nak until we're ready */
+		writel(DCTL_SGNPInNAK | DCTL_SGOUTNak,
+		       hsotg->regs + DCTL);
+	}
+
+	/* setup fifos */
+
+	dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
+		readl(hsotg->regs + GRXFSIZ),
+		readl(hsotg->regs + GNPTXFSIZ));
+
+	s3c_hsotg_init_fifo(hsotg);
+
+	/* set the PLL on, remove the HNP/SRP and set the PHY */
+	writel(GUSBCFG_PHYIf16 | GUSBCFG_TOutCal(7) | (0x5 << 10),
+	       hsotg->regs + GUSBCFG);
+
+	writel(using_dma(hsotg) ? GAHBCFG_DMAEn : 0x0,
+	       hsotg->regs + GAHBCFG);
+}
+
+/**
+ * s3c_hsotg_udc_start - prepare the udc for work
+ * @gadget: The usb gadget state
+ * @driver: The usb gadget driver
+ *
+ * Perform initialization to prepare udc device and driver
+ * to work.
+ */
+static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
+			   struct usb_gadget_driver *driver)
+{
+	struct s3c_hsotg *hsotg = to_hsotg(gadget);
 	int ret;
 
 	if (!hsotg) {
@@ -2592,7 +2944,7 @@
 	if (driver->max_speed < USB_SPEED_FULL)
 		dev_err(hsotg->dev, "%s: bad speed\n", __func__);
 
-	if (!bind || !driver->setup) {
+	if (!driver->setup) {
 		dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
 		return -EINVAL;
 	}
@@ -2605,135 +2957,17 @@
 	hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask;
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 
-	ret = device_add(&hsotg->gadget.dev);
+	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+				    hsotg->supplies);
 	if (ret) {
-		dev_err(hsotg->dev, "failed to register gadget device\n");
+		dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret);
 		goto err;
 	}
 
-	ret = bind(&hsotg->gadget);
-	if (ret) {
-		dev_err(hsotg->dev, "failed bind %s\n", driver->driver.name);
+	s3c_hsotg_phy_enable(hsotg);
 
-		hsotg->gadget.dev.driver = NULL;
-		hsotg->driver = NULL;
-		goto err;
-	}
-
-	/* we must now enable ep0 ready for host detection and then
-	 * set configuration. */
-
-	s3c_hsotg_corereset(hsotg);
-
-	/* set the PLL on, remove the HNP/SRP and set the PHY */
-	writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) |
-	       (0x5 << 10), hsotg->regs + S3C_GUSBCFG);
-
-	/* looks like soft-reset changes state of FIFOs */
-	s3c_hsotg_init_fifo(hsotg);
-
-	__orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
-
-	writel(1 << 18 | S3C_DCFG_DevSpd_HS,  hsotg->regs + S3C_DCFG);
-
-	/* Clear any pending OTG interrupts */
-	writel(0xffffffff, hsotg->regs + S3C_GOTGINT);
-
-	/* Clear any pending interrupts */
-	writel(0xffffffff, hsotg->regs + S3C_GINTSTS);
-
-	writel(S3C_GINTSTS_DisconnInt | S3C_GINTSTS_SessReqInt |
-	       S3C_GINTSTS_ConIDStsChng | S3C_GINTSTS_USBRst |
-	       S3C_GINTSTS_EnumDone | S3C_GINTSTS_OTGInt |
-	       S3C_GINTSTS_USBSusp | S3C_GINTSTS_WkUpInt |
-	       S3C_GINTSTS_GOUTNakEff | S3C_GINTSTS_GINNakEff |
-	       S3C_GINTSTS_ErlySusp,
-	       hsotg->regs + S3C_GINTMSK);
-
-	if (using_dma(hsotg))
-		writel(S3C_GAHBCFG_GlblIntrEn | S3C_GAHBCFG_DMAEn |
-		       S3C_GAHBCFG_HBstLen_Incr4,
-		       hsotg->regs + S3C_GAHBCFG);
-	else
-		writel(S3C_GAHBCFG_GlblIntrEn, hsotg->regs + S3C_GAHBCFG);
-
-	/* Enabling INTknTXFEmpMsk here seems to be a big mistake, we end
-	 * up being flooded with interrupts if the host is polling the
-	 * endpoint to try and read data. */
-
-	writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk |
-	       S3C_DIEPMSK_INTknEPMisMsk |
-	       S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk |
-	       ((hsotg->dedicated_fifos) ? S3C_DIEPMSK_TxFIFOEmpty : 0),
-	       hsotg->regs + S3C_DIEPMSK);
-
-	/* don't need XferCompl, we get that from RXFIFO in slave mode. In
-	 * DMA mode we may need this. */
-	writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk |
-	       S3C_DOEPMSK_EPDisbldMsk |
-	       (using_dma(hsotg) ? (S3C_DIEPMSK_XferComplMsk |
-				   S3C_DIEPMSK_TimeOUTMsk) : 0),
-	       hsotg->regs + S3C_DOEPMSK);
-
-	writel(0, hsotg->regs + S3C_DAINTMSK);
-
-	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + S3C_DIEPCTL0),
-		readl(hsotg->regs + S3C_DOEPCTL0));
-
-	/* enable in and out endpoint interrupts */
-	s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_OEPInt | S3C_GINTSTS_IEPInt);
-
-	/* Enable the RXFIFO when in slave mode, as this is how we collect
-	 * the data. In DMA mode, we get events from the FIFO but also
-	 * things we cannot process, so do not use it. */
-	if (!using_dma(hsotg))
-		s3c_hsotg_en_gsint(hsotg, S3C_GINTSTS_RxFLvl);
-
-	/* Enable interrupts for EP0 in and out */
-	s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1);
-	s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1);
-
-	__orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone);
-	udelay(10);  /* see openiboot */
-	__bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_PWROnPrgDone);
-
-	dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + S3C_DCTL));
-
-	/* S3C_DxEPCTL_USBActEp says RO in manual, but seems to be set by
-	   writing to the EPCTL register.. */
-
-	/* set to read 1 8byte packet */
-	writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) |
-	       S3C_DxEPTSIZ_XferSize(8), hsotg->regs + DOEPTSIZ0);
-
-	writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) |
-	       S3C_DxEPCTL_CNAK | S3C_DxEPCTL_EPEna |
-	       S3C_DxEPCTL_USBActEp,
-	       hsotg->regs + S3C_DOEPCTL0);
-
-	/* enable, but don't activate EP0in */
-	writel(s3c_hsotg_ep0_mps(hsotg->eps[0].ep.maxpacket) |
-	       S3C_DxEPCTL_USBActEp, hsotg->regs + S3C_DIEPCTL0);
-
-	s3c_hsotg_enqueue_setup(hsotg);
-
-	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + S3C_DIEPCTL0),
-		readl(hsotg->regs + S3C_DOEPCTL0));
-
-	/* clear global NAKs */
-	writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK,
-	       hsotg->regs + S3C_DCTL);
-
-	/* must be at-least 3ms to allow bus to see disconnect */
-	msleep(3);
-
-	/* remove the soft-disconnect and let's go */
-	__bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
-
-	/* report to the user, and return */
-
+	s3c_hsotg_core_init(hsotg);
+	hsotg->last_rst = jiffies;
 	dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 	return 0;
 
@@ -2743,9 +2977,17 @@
 	return ret;
 }
 
-static int s3c_hsotg_stop(struct usb_gadget_driver *driver)
+/**
+ * s3c_hsotg_udc_stop - stop the udc
+ * @gadget: The usb gadget state
+ * @driver: The usb gadget driver
+ *
+ * Stop udc hw block and stay tunned for future transmissions
+ */
+static int s3c_hsotg_udc_stop(struct usb_gadget *gadget,
+			  struct usb_gadget_driver *driver)
 {
-	struct s3c_hsotg *hsotg = our_hsotg;
+	struct s3c_hsotg *hsotg = to_hsotg(gadget);
 	int ep;
 
 	if (!hsotg)
@@ -2755,16 +2997,15 @@
 		return -EINVAL;
 
 	/* all endpoints should be shutdown */
-	for (ep = 0; ep < S3C_HSOTG_EPS; ep++)
+	for (ep = 0; ep < hsotg->num_of_eps; ep++)
 		s3c_hsotg_ep_disable(&hsotg->eps[ep].ep);
 
-	call_gadget(hsotg, disconnect);
+	s3c_hsotg_phy_disable(hsotg);
+	regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
 
-	driver->unbind(&hsotg->gadget);
 	hsotg->driver = NULL;
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
-
-	device_del(&hsotg->gadget.dev);
+	hsotg->gadget.dev.driver = NULL;
 
 	dev_info(hsotg->dev, "unregistered gadget driver '%s'\n",
 		 driver->driver.name);
@@ -2772,6 +3013,12 @@
 	return 0;
 }
 
+/**
+ * s3c_hsotg_gadget_getframe - read the frame number
+ * @gadget: The usb gadget state
+ *
+ * Read the {micro} frame number
+ */
 static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget)
 {
 	return s3c_hsotg_read_frameno(to_hsotg(gadget));
@@ -2779,8 +3026,8 @@
 
 static struct usb_gadget_ops s3c_hsotg_gadget_ops = {
 	.get_frame	= s3c_hsotg_gadget_getframe,
-	.start		= s3c_hsotg_start,
-	.stop		= s3c_hsotg_stop,
+	.udc_start		= s3c_hsotg_udc_start,
+	.udc_stop		= s3c_hsotg_udc_stop,
 };
 
 /**
@@ -2827,112 +3074,43 @@
 	hs_ep->ep.maxpacket = epnum ? 512 : EP0_MPS_LIMIT;
 	hs_ep->ep.ops = &s3c_hsotg_ep_ops;
 
-	/* Read the FIFO size for the Periodic TX FIFO, even if we're
+	/*
+	 * Read the FIFO size for the Periodic TX FIFO, even if we're
 	 * an OUT endpoint, we may as well do this if in future the
 	 * code is changed to make each endpoint's direction changeable.
 	 */
 
-	ptxfifo = readl(hsotg->regs + S3C_DPTXFSIZn(epnum));
-	hs_ep->fifo_size = S3C_DPTXFSIZn_DPTxFSize_GET(ptxfifo) * 4;
+	ptxfifo = readl(hsotg->regs + DPTXFSIZn(epnum));
+	hs_ep->fifo_size = DPTXFSIZn_DPTxFSize_GET(ptxfifo) * 4;
 
-	/* if we're using dma, we need to set the next-endpoint pointer
+	/*
+	 * if we're using dma, we need to set the next-endpoint pointer
 	 * to be something valid.
 	 */
 
 	if (using_dma(hsotg)) {
-		u32 next = S3C_DxEPCTL_NextEp((epnum + 1) % 15);
-		writel(next, hsotg->regs + S3C_DIEPCTL(epnum));
-		writel(next, hsotg->regs + S3C_DOEPCTL(epnum));
+		u32 next = DxEPCTL_NextEp((epnum + 1) % 15);
+		writel(next, hsotg->regs + DIEPCTL(epnum));
+		writel(next, hsotg->regs + DOEPCTL(epnum));
 	}
 }
 
 /**
- * s3c_hsotg_otgreset - reset the OtG phy block
- * @hsotg: The host state.
+ * s3c_hsotg_hw_cfg - read HW configuration registers
+ * @param: The device state
  *
- * Power up the phy, set the basic configuration and start the PHY.
+ * Read the USB core HW configuration registers
  */
-static void s3c_hsotg_otgreset(struct s3c_hsotg *hsotg)
+static void s3c_hsotg_hw_cfg(struct s3c_hsotg *hsotg)
 {
-	struct clk *xusbxti;
-	u32 pwr, osc;
-
-	pwr = readl(S3C_PHYPWR);
-	pwr &= ~0x19;
-	writel(pwr, S3C_PHYPWR);
-	mdelay(1);
-
-	osc = hsotg->plat->is_osc ? S3C_PHYCLK_EXT_OSC : 0;
-
-	xusbxti = clk_get(hsotg->dev, "xusbxti");
-	if (xusbxti && !IS_ERR(xusbxti)) {
-		switch (clk_get_rate(xusbxti)) {
-		case 12*MHZ:
-			osc |= S3C_PHYCLK_CLKSEL_12M;
-			break;
-		case 24*MHZ:
-			osc |= S3C_PHYCLK_CLKSEL_24M;
-			break;
-		default:
-		case 48*MHZ:
-			/* default reference clock */
-			break;
-		}
-		clk_put(xusbxti);
-	}
-
-	writel(osc | 0x10, S3C_PHYCLK);
-
-	/* issue a full set of resets to the otg and core */
-
-	writel(S3C_RSTCON_PHY, S3C_RSTCON);
-	udelay(20);	/* at-least 10uS */
-	writel(0, S3C_RSTCON);
-}
-
-
-static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
-{
-	u32 cfg4;
-
-	/* unmask subset of endpoint interrupts */
-
-	writel(S3C_DIEPMSK_TimeOUTMsk | S3C_DIEPMSK_AHBErrMsk |
-	       S3C_DIEPMSK_EPDisbldMsk | S3C_DIEPMSK_XferComplMsk,
-	       hsotg->regs + S3C_DIEPMSK);
-
-	writel(S3C_DOEPMSK_SetupMsk | S3C_DOEPMSK_AHBErrMsk |
-	       S3C_DOEPMSK_EPDisbldMsk | S3C_DOEPMSK_XferComplMsk,
-	       hsotg->regs + S3C_DOEPMSK);
-
-	writel(0, hsotg->regs + S3C_DAINTMSK);
-
-	/* Be in disconnected state until gadget is registered */
-	__orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
-
-	if (0) {
-		/* post global nak until we're ready */
-		writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak,
-		       hsotg->regs + S3C_DCTL);
-	}
-
-	/* setup fifos */
-
-	dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-		readl(hsotg->regs + S3C_GRXFSIZ),
-		readl(hsotg->regs + S3C_GNPTXFSIZ));
-
-	s3c_hsotg_init_fifo(hsotg);
-
-	/* set the PLL on, remove the HNP/SRP and set the PHY */
-	writel(S3C_GUSBCFG_PHYIf16 | S3C_GUSBCFG_TOutCal(7) | (0x5 << 10),
-	       hsotg->regs + S3C_GUSBCFG);
-
-	writel(using_dma(hsotg) ? S3C_GAHBCFG_DMAEn : 0x0,
-	       hsotg->regs + S3C_GAHBCFG);
-
+	u32 cfg2, cfg4;
 	/* check hardware configuration */
 
+	cfg2 = readl(hsotg->regs + 0x48);
+	hsotg->num_of_eps = (cfg2 >> 10) & 0xF;
+
+	dev_info(hsotg->dev, "EPs:%d\n", hsotg->num_of_eps);
+
 	cfg4 = readl(hsotg->regs + 0x50);
 	hsotg->dedicated_fifos = (cfg4 >> 25) & 1;
 
@@ -2940,6 +3118,10 @@
 		 hsotg->dedicated_fifos ? "dedicated" : "shared");
 }
 
+/**
+ * s3c_hsotg_dump - dump state of the udc
+ * @param: The device state
+ */
 static void s3c_hsotg_dump(struct s3c_hsotg *hsotg)
 {
 #ifdef DEBUG
@@ -2949,46 +3131,45 @@
 	int idx;
 
 	dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n",
-		 readl(regs + S3C_DCFG), readl(regs + S3C_DCTL),
-		 readl(regs + S3C_DIEPMSK));
+		 readl(regs + DCFG), readl(regs + DCTL),
+		 readl(regs + DIEPMSK));
 
 	dev_info(dev, "GAHBCFG=0x%08x, 0x44=0x%08x\n",
-		 readl(regs + S3C_GAHBCFG), readl(regs + 0x44));
+		 readl(regs + GAHBCFG), readl(regs + 0x44));
 
 	dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-		 readl(regs + S3C_GRXFSIZ), readl(regs + S3C_GNPTXFSIZ));
+		 readl(regs + GRXFSIZ), readl(regs + GNPTXFSIZ));
 
 	/* show periodic fifo settings */
 
 	for (idx = 1; idx <= 15; idx++) {
-		val = readl(regs + S3C_DPTXFSIZn(idx));
+		val = readl(regs + DPTXFSIZn(idx));
 		dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx,
-			 val >> S3C_DPTXFSIZn_DPTxFSize_SHIFT,
-			 val & S3C_DPTXFSIZn_DPTxFStAddr_MASK);
+			 val >> DPTXFSIZn_DPTxFSize_SHIFT,
+			 val & DPTXFSIZn_DPTxFStAddr_MASK);
 	}
 
 	for (idx = 0; idx < 15; idx++) {
 		dev_info(dev,
 			 "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx,
-			 readl(regs + S3C_DIEPCTL(idx)),
-			 readl(regs + S3C_DIEPTSIZ(idx)),
-			 readl(regs + S3C_DIEPDMA(idx)));
+			 readl(regs + DIEPCTL(idx)),
+			 readl(regs + DIEPTSIZ(idx)),
+			 readl(regs + DIEPDMA(idx)));
 
-		val = readl(regs + S3C_DOEPCTL(idx));
+		val = readl(regs + DOEPCTL(idx));
 		dev_info(dev,
 			 "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n",
-			 idx, readl(regs + S3C_DOEPCTL(idx)),
-			 readl(regs + S3C_DOEPTSIZ(idx)),
-			 readl(regs + S3C_DOEPDMA(idx)));
+			 idx, readl(regs + DOEPCTL(idx)),
+			 readl(regs + DOEPTSIZ(idx)),
+			 readl(regs + DOEPDMA(idx)));
 
 	}
 
 	dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n",
-		 readl(regs + S3C_DVBUSDIS), readl(regs + S3C_DVBUSPULSE));
+		 readl(regs + DVBUSDIS), readl(regs + DVBUSPULSE));
 #endif
 }
 
-
 /**
  * state_show - debugfs: show overall driver and device state.
  * @seq: The seq file to write to.
@@ -3005,38 +3186,38 @@
 	int idx;
 
 	seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n",
-		 readl(regs + S3C_DCFG),
-		 readl(regs + S3C_DCTL),
-		 readl(regs + S3C_DSTS));
+		 readl(regs + DCFG),
+		 readl(regs + DCTL),
+		 readl(regs + DSTS));
 
 	seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n",
-		   readl(regs + S3C_DIEPMSK), readl(regs + S3C_DOEPMSK));
+		   readl(regs + DIEPMSK), readl(regs + DOEPMSK));
 
 	seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n",
-		   readl(regs + S3C_GINTMSK),
-		   readl(regs + S3C_GINTSTS));
+		   readl(regs + GINTMSK),
+		   readl(regs + GINTSTS));
 
 	seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n",
-		   readl(regs + S3C_DAINTMSK),
-		   readl(regs + S3C_DAINT));
+		   readl(regs + DAINTMSK),
+		   readl(regs + DAINT));
 
 	seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n",
-		   readl(regs + S3C_GNPTXSTS),
-		   readl(regs + S3C_GRXSTSR));
+		   readl(regs + GNPTXSTS),
+		   readl(regs + GRXSTSR));
 
 	seq_printf(seq, "\nEndpoint status:\n");
 
 	for (idx = 0; idx < 15; idx++) {
 		u32 in, out;
 
-		in = readl(regs + S3C_DIEPCTL(idx));
-		out = readl(regs + S3C_DOEPCTL(idx));
+		in = readl(regs + DIEPCTL(idx));
+		out = readl(regs + DOEPCTL(idx));
 
 		seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x",
 			   idx, in, out);
 
-		in = readl(regs + S3C_DIEPTSIZ(idx));
-		out = readl(regs + S3C_DOEPTSIZ(idx));
+		in = readl(regs + DIEPTSIZ(idx));
+		out = readl(regs + DOEPTSIZ(idx));
 
 		seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x",
 			   in, out);
@@ -3067,7 +3248,7 @@
  *
  * Show the FIFO information for the overall fifo and all the
  * periodic transmission FIFOs.
-*/
+ */
 static int fifo_show(struct seq_file *seq, void *v)
 {
 	struct s3c_hsotg *hsotg = seq->private;
@@ -3076,21 +3257,21 @@
 	int idx;
 
 	seq_printf(seq, "Non-periodic FIFOs:\n");
-	seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + S3C_GRXFSIZ));
+	seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ));
 
-	val = readl(regs + S3C_GNPTXFSIZ);
+	val = readl(regs + GNPTXFSIZ);
 	seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n",
-		   val >> S3C_GNPTXFSIZ_NPTxFDep_SHIFT,
-		   val & S3C_GNPTXFSIZ_NPTxFStAddr_MASK);
+		   val >> GNPTXFSIZ_NPTxFDep_SHIFT,
+		   val & GNPTXFSIZ_NPTxFStAddr_MASK);
 
 	seq_printf(seq, "\nPeriodic TXFIFOs:\n");
 
 	for (idx = 1; idx <= 15; idx++) {
-		val = readl(regs + S3C_DPTXFSIZn(idx));
+		val = readl(regs + DPTXFSIZn(idx));
 
 		seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx,
-			   val >> S3C_DPTXFSIZn_DPTxFSize_SHIFT,
-			   val & S3C_DPTXFSIZn_DPTxFStAddr_MASK);
+			   val >> DPTXFSIZn_DPTxFSize_SHIFT,
+			   val & DPTXFSIZn_DPTxFStAddr_MASK);
 	}
 
 	return 0;
@@ -3122,7 +3303,7 @@
  *
  * This debugfs entry shows the state of the given endpoint (one is
  * registered for each available).
-*/
+ */
 static int ep_show(struct seq_file *seq, void *v)
 {
 	struct s3c_hsotg_ep *ep = seq->private;
@@ -3139,20 +3320,20 @@
 	/* first show the register state */
 
 	seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n",
-		   readl(regs + S3C_DIEPCTL(index)),
-		   readl(regs + S3C_DOEPCTL(index)));
+		   readl(regs + DIEPCTL(index)),
+		   readl(regs + DOEPCTL(index)));
 
 	seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n",
-		   readl(regs + S3C_DIEPDMA(index)),
-		   readl(regs + S3C_DOEPDMA(index)));
+		   readl(regs + DIEPDMA(index)),
+		   readl(regs + DOEPDMA(index)));
 
 	seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n",
-		   readl(regs + S3C_DIEPINT(index)),
-		   readl(regs + S3C_DOEPINT(index)));
+		   readl(regs + DIEPINT(index)),
+		   readl(regs + DOEPINT(index)));
 
 	seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n",
-		   readl(regs + S3C_DIEPTSIZ(index)),
-		   readl(regs + S3C_DOEPTSIZ(index)));
+		   readl(regs + DIEPTSIZ(index)),
+		   readl(regs + DOEPTSIZ(index)));
 
 	seq_printf(seq, "\n");
 	seq_printf(seq, "mps %d\n", ep->ep.maxpacket);
@@ -3202,7 +3383,7 @@
  * about the state of the system. The directory name is created
  * with the same name as the device itself, in case we end up
  * with multiple blocks in future systems.
-*/
+ */
 static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg)
 {
 	struct dentry *root;
@@ -3231,7 +3412,7 @@
 
 	/* create one file for each endpoint */
 
-	for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) {
+	for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
 		struct s3c_hsotg_ep *ep = &hsotg->eps[epidx];
 
 		ep->debugfs = debugfs_create_file(ep->name, 0444,
@@ -3248,12 +3429,12 @@
  * @hsotg: The driver state
  *
  * Cleanup (remove) the debugfs files for use on module exit.
-*/
+ */
 static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg)
 {
 	unsigned epidx;
 
-	for (epidx = 0; epidx < S3C_HSOTG_EPS; epidx++) {
+	for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
 		struct s3c_hsotg_ep *ep = &hsotg->eps[epidx];
 		debugfs_remove(ep->debugfs);
 	}
@@ -3264,48 +3445,39 @@
 }
 
 /**
- * s3c_hsotg_gate - set the hardware gate for the block
- * @pdev: The device we bound to
- * @on: On or off.
- *
- * Set the hardware gate setting into the block. If we end up on
- * something other than an S3C64XX, then we might need to change this
- * to using a platform data callback, or some other mechanism.
+ * s3c_hsotg_release - release callback for hsotg device
+ * @dev: Device to for which release is called
  */
-static void s3c_hsotg_gate(struct platform_device *pdev, bool on)
+static void s3c_hsotg_release(struct device *dev)
 {
-	unsigned long flags;
-	u32 others;
+	struct s3c_hsotg *hsotg = dev_get_drvdata(dev);
 
-	local_irq_save(flags);
-
-	others = __raw_readl(S3C64XX_OTHERS);
-	if (on)
-		others |= S3C64XX_OTHERS_USBMASK;
-	else
-		others &= ~S3C64XX_OTHERS_USBMASK;
-	__raw_writel(others, S3C64XX_OTHERS);
-
-	local_irq_restore(flags);
+	kfree(hsotg);
 }
 
-static struct s3c_hsotg_plat s3c_hsotg_default_pdata;
+/**
+ * s3c_hsotg_probe - probe function for hsotg driver
+ * @pdev: The platform information for the driver
+ */
 
 static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
 {
 	struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
 	struct device *dev = &pdev->dev;
+	struct s3c_hsotg_ep *eps;
 	struct s3c_hsotg *hsotg;
 	struct resource *res;
 	int epnum;
 	int ret;
+	int i;
 
-	if (!plat)
-		plat = &s3c_hsotg_default_pdata;
+	plat = pdev->dev.platform_data;
+	if (!plat) {
+		dev_err(&pdev->dev, "no platform data defined\n");
+		return -EINVAL;
+	}
 
-	hsotg = kzalloc(sizeof(struct s3c_hsotg) +
-			sizeof(struct s3c_hsotg_ep) * S3C_HSOTG_EPS,
-			GFP_KERNEL);
+	hsotg = kzalloc(sizeof(struct s3c_hsotg), GFP_KERNEL);
 	if (!hsotg) {
 		dev_err(dev, "cannot get memory\n");
 		return -ENOMEM;
@@ -3371,6 +3543,54 @@
 
 	hsotg->gadget.dev.parent = dev;
 	hsotg->gadget.dev.dma_mask = dev->dma_mask;
+	hsotg->gadget.dev.release = s3c_hsotg_release;
+
+	/* reset the system */
+
+	clk_prepare_enable(hsotg->clk);
+
+	/* regulators */
+
+	for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
+		hsotg->supplies[i].supply = s3c_hsotg_supply_names[i];
+
+	ret = regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
+				 hsotg->supplies);
+	if (ret) {
+		dev_err(dev, "failed to request supplies: %d\n", ret);
+		goto err_irq;
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+				    hsotg->supplies);
+
+	if (ret) {
+		dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret);
+		goto err_supplies;
+	}
+
+	/* usb phy enable */
+	s3c_hsotg_phy_enable(hsotg);
+
+	s3c_hsotg_corereset(hsotg);
+	s3c_hsotg_init(hsotg);
+	s3c_hsotg_hw_cfg(hsotg);
+
+	/* hsotg->num_of_eps holds number of EPs other than ep0 */
+
+	if (hsotg->num_of_eps == 0) {
+		dev_err(dev, "wrong number of EPs (zero)\n");
+		goto err_supplies;
+	}
+
+	eps = kcalloc(hsotg->num_of_eps + 1, sizeof(struct s3c_hsotg_ep),
+		      GFP_KERNEL);
+	if (!eps) {
+		dev_err(dev, "cannot get memory\n");
+		goto err_supplies;
+	}
+
+	hsotg->eps = eps;
 
 	/* setup endpoint information */
 
@@ -3383,39 +3603,47 @@
 						     GFP_KERNEL);
 	if (!hsotg->ctrl_req) {
 		dev_err(dev, "failed to allocate ctrl req\n");
-		goto err_regs;
+		goto err_ep_mem;
 	}
 
-	/* reset the system */
-
-	clk_enable(hsotg->clk);
-
-	s3c_hsotg_gate(pdev, true);
-
-	s3c_hsotg_otgreset(hsotg);
-	s3c_hsotg_corereset(hsotg);
-	s3c_hsotg_init(hsotg);
-
 	/* initialise the endpoints now the core has been initialised */
-	for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++)
+	for (epnum = 0; epnum < hsotg->num_of_eps; epnum++)
 		s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum);
 
+	/* disable power and clock */
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
+				    hsotg->supplies);
+	if (ret) {
+		dev_err(hsotg->dev, "failed to disable supplies: %d\n", ret);
+		goto err_ep_mem;
+	}
+
+	s3c_hsotg_phy_disable(hsotg);
+
+	ret = device_add(&hsotg->gadget.dev);
+	if (ret) {
+		put_device(&hsotg->gadget.dev);
+		goto err_ep_mem;
+	}
+
 	ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
 	if (ret)
-		goto err_add_udc;
+		goto err_ep_mem;
 
 	s3c_hsotg_create_debug(hsotg);
 
 	s3c_hsotg_dump(hsotg);
 
-	our_hsotg = hsotg;
 	return 0;
 
-err_add_udc:
-	s3c_hsotg_gate(pdev, false);
-	clk_disable(hsotg->clk);
-	clk_put(hsotg->clk);
-
+err_ep_mem:
+	kfree(eps);
+err_supplies:
+	s3c_hsotg_phy_disable(hsotg);
+	regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+err_irq:
+	free_irq(hsotg->irq, hsotg);
 err_regs:
 	iounmap(hsotg->regs);
 
@@ -3423,12 +3651,17 @@
 	release_resource(hsotg->regs_res);
 	kfree(hsotg->regs_res);
 err_clk:
+	clk_disable_unprepare(hsotg->clk);
 	clk_put(hsotg->clk);
 err_mem:
 	kfree(hsotg);
 	return ret;
 }
 
+/**
+ * s3c_hsotg_remove - remove function for hsotg driver
+ * @pdev: The platform information for the driver
+ */
 static int __devexit s3c_hsotg_remove(struct platform_device *pdev)
 {
 	struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
@@ -3437,7 +3670,10 @@
 
 	s3c_hsotg_delete_debug(hsotg);
 
-	usb_gadget_unregister_driver(hsotg->driver);
+	if (hsotg->driver) {
+		/* should have been done already by driver model core */
+		usb_gadget_unregister_driver(hsotg->driver);
+	}
 
 	free_irq(hsotg->irq, hsotg);
 	iounmap(hsotg->regs);
@@ -3445,12 +3681,13 @@
 	release_resource(hsotg->regs_res);
 	kfree(hsotg->regs_res);
 
-	s3c_hsotg_gate(pdev, false);
+	s3c_hsotg_phy_disable(hsotg);
+	regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
 
-	clk_disable(hsotg->clk);
+	clk_disable_unprepare(hsotg->clk);
 	clk_put(hsotg->clk);
 
-	kfree(hsotg);
+	device_unregister(&hsotg->gadget.dev);
 	return 0;
 }
 
diff --git a/drivers/usb/gadget/s3c-hsotg.h b/drivers/usb/gadget/s3c-hsotg.h
new file mode 100644
index 0000000..d650b12
--- /dev/null
+++ b/drivers/usb/gadget/s3c-hsotg.h
@@ -0,0 +1,377 @@
+/* drivers/usb/gadget/s3c-hsotg.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *      http://armlinux.simtec.co.uk/
+ *      Ben Dooks <ben@simtec.co.uk>
+ *
+ * USB2.0 Highspeed/OtG Synopsis DWC2 device block registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __REGS_USB_HSOTG_H
+#define __REGS_USB_HSOTG_H __FILE__
+
+#define HSOTG_REG(x) (x)
+
+#define GOTGCTL				HSOTG_REG(0x000)
+#define GOTGCTL_BSESVLD			(1 << 19)
+#define GOTGCTL_ASESVLD			(1 << 18)
+#define GOTGCTL_DBNC_SHORT			(1 << 17)
+#define GOTGCTL_CONID_B			(1 << 16)
+#define GOTGCTL_DEVHNPEN			(1 << 11)
+#define GOTGCTL_HSSETHNPEN			(1 << 10)
+#define GOTGCTL_HNPREQ				(1 << 9)
+#define GOTGCTL_HSTNEGSCS			(1 << 8)
+#define GOTGCTL_SESREQ				(1 << 1)
+#define GOTGCTL_SESREQSCS			(1 << 0)
+
+#define GOTGINT				HSOTG_REG(0x004)
+#define GOTGINT_DbnceDone			(1 << 19)
+#define GOTGINT_ADevTOUTChg			(1 << 18)
+#define GOTGINT_HstNegDet			(1 << 17)
+#define GOTGINT_HstnegSucStsChng		(1 << 9)
+#define GOTGINT_SesReqSucStsChng		(1 << 8)
+#define GOTGINT_SesEndDet			(1 << 2)
+
+#define GAHBCFG				HSOTG_REG(0x008)
+#define GAHBCFG_PTxFEmpLvl			(1 << 8)
+#define GAHBCFG_NPTxFEmpLvl			(1 << 7)
+#define GAHBCFG_DMAEn				(1 << 5)
+#define GAHBCFG_HBstLen_MASK			(0xf << 1)
+#define GAHBCFG_HBstLen_SHIFT			(1)
+#define GAHBCFG_HBstLen_Single			(0x0 << 1)
+#define GAHBCFG_HBstLen_Incr			(0x1 << 1)
+#define GAHBCFG_HBstLen_Incr4			(0x3 << 1)
+#define GAHBCFG_HBstLen_Incr8			(0x5 << 1)
+#define GAHBCFG_HBstLen_Incr16			(0x7 << 1)
+#define GAHBCFG_GlblIntrEn			(1 << 0)
+
+#define GUSBCFG				HSOTG_REG(0x00C)
+#define GUSBCFG_PHYLPClkSel			(1 << 15)
+#define GUSBCFG_HNPCap				(1 << 9)
+#define GUSBCFG_SRPCap				(1 << 8)
+#define GUSBCFG_PHYIf16			(1 << 3)
+#define GUSBCFG_TOutCal_MASK			(0x7 << 0)
+#define GUSBCFG_TOutCal_SHIFT			(0)
+#define GUSBCFG_TOutCal_LIMIT			(0x7)
+#define GUSBCFG_TOutCal(_x)			((_x) << 0)
+
+#define GRSTCTL				HSOTG_REG(0x010)
+
+#define GRSTCTL_AHBIdle			(1 << 31)
+#define GRSTCTL_DMAReq				(1 << 30)
+#define GRSTCTL_TxFNum_MASK			(0x1f << 6)
+#define GRSTCTL_TxFNum_SHIFT			(6)
+#define GRSTCTL_TxFNum_LIMIT			(0x1f)
+#define GRSTCTL_TxFNum(_x)			((_x) << 6)
+#define GRSTCTL_TxFFlsh			(1 << 5)
+#define GRSTCTL_RxFFlsh			(1 << 4)
+#define GRSTCTL_INTknQFlsh			(1 << 3)
+#define GRSTCTL_FrmCntrRst			(1 << 2)
+#define GRSTCTL_HSftRst			(1 << 1)
+#define GRSTCTL_CSftRst			(1 << 0)
+
+#define GINTSTS				HSOTG_REG(0x014)
+#define GINTMSK				HSOTG_REG(0x018)
+
+#define GINTSTS_WkUpInt			(1 << 31)
+#define GINTSTS_SessReqInt			(1 << 30)
+#define GINTSTS_DisconnInt			(1 << 29)
+#define GINTSTS_ConIDStsChng			(1 << 28)
+#define GINTSTS_PTxFEmp			(1 << 26)
+#define GINTSTS_HChInt				(1 << 25)
+#define GINTSTS_PrtInt				(1 << 24)
+#define GINTSTS_FetSusp			(1 << 22)
+#define GINTSTS_incompIP			(1 << 21)
+#define GINTSTS_IncomplSOIN			(1 << 20)
+#define GINTSTS_OEPInt				(1 << 19)
+#define GINTSTS_IEPInt				(1 << 18)
+#define GINTSTS_EPMis				(1 << 17)
+#define GINTSTS_EOPF				(1 << 15)
+#define GINTSTS_ISOutDrop			(1 << 14)
+#define GINTSTS_EnumDone			(1 << 13)
+#define GINTSTS_USBRst				(1 << 12)
+#define GINTSTS_USBSusp			(1 << 11)
+#define GINTSTS_ErlySusp			(1 << 10)
+#define GINTSTS_GOUTNakEff			(1 << 7)
+#define GINTSTS_GINNakEff			(1 << 6)
+#define GINTSTS_NPTxFEmp			(1 << 5)
+#define GINTSTS_RxFLvl				(1 << 4)
+#define GINTSTS_SOF				(1 << 3)
+#define GINTSTS_OTGInt				(1 << 2)
+#define GINTSTS_ModeMis			(1 << 1)
+#define GINTSTS_CurMod_Host			(1 << 0)
+
+#define GRXSTSR				HSOTG_REG(0x01C)
+#define GRXSTSP				HSOTG_REG(0x020)
+
+#define GRXSTS_FN_MASK				(0x7f << 25)
+#define GRXSTS_FN_SHIFT			(25)
+
+#define GRXSTS_PktSts_MASK			(0xf << 17)
+#define GRXSTS_PktSts_SHIFT			(17)
+#define GRXSTS_PktSts_GlobalOutNAK		(0x1 << 17)
+#define GRXSTS_PktSts_OutRX			(0x2 << 17)
+#define GRXSTS_PktSts_OutDone			(0x3 << 17)
+#define GRXSTS_PktSts_SetupDone		(0x4 << 17)
+#define GRXSTS_PktSts_SetupRX			(0x6 << 17)
+
+#define GRXSTS_DPID_MASK			(0x3 << 15)
+#define GRXSTS_DPID_SHIFT			(15)
+#define GRXSTS_ByteCnt_MASK			(0x7ff << 4)
+#define GRXSTS_ByteCnt_SHIFT			(4)
+#define GRXSTS_EPNum_MASK			(0xf << 0)
+#define GRXSTS_EPNum_SHIFT			(0)
+
+#define GRXFSIZ				HSOTG_REG(0x024)
+
+#define GNPTXFSIZ				HSOTG_REG(0x028)
+
+#define GNPTXFSIZ_NPTxFDep_MASK		(0xffff << 16)
+#define GNPTXFSIZ_NPTxFDep_SHIFT		(16)
+#define GNPTXFSIZ_NPTxFDep_LIMIT		(0xffff)
+#define GNPTXFSIZ_NPTxFDep(_x)			((_x) << 16)
+#define GNPTXFSIZ_NPTxFStAddr_MASK		(0xffff << 0)
+#define GNPTXFSIZ_NPTxFStAddr_SHIFT		(0)
+#define GNPTXFSIZ_NPTxFStAddr_LIMIT		(0xffff)
+#define GNPTXFSIZ_NPTxFStAddr(_x)		((_x) << 0)
+
+#define GNPTXSTS				HSOTG_REG(0x02C)
+
+#define GNPTXSTS_NPtxQTop_MASK			(0x7f << 24)
+#define GNPTXSTS_NPtxQTop_SHIFT		(24)
+
+#define GNPTXSTS_NPTxQSpcAvail_MASK		(0xff << 16)
+#define GNPTXSTS_NPTxQSpcAvail_SHIFT		(16)
+#define GNPTXSTS_NPTxQSpcAvail_GET(_v)		(((_v) >> 16) & 0xff)
+
+#define GNPTXSTS_NPTxFSpcAvail_MASK		(0xffff << 0)
+#define GNPTXSTS_NPTxFSpcAvail_SHIFT		(0)
+#define GNPTXSTS_NPTxFSpcAvail_GET(_v)		(((_v) >> 0) & 0xffff)
+
+
+#define HPTXFSIZ				HSOTG_REG(0x100)
+
+#define DPTXFSIZn(_a)		HSOTG_REG(0x104 + (((_a) - 1) * 4))
+
+#define DPTXFSIZn_DPTxFSize_MASK		(0xffff << 16)
+#define DPTXFSIZn_DPTxFSize_SHIFT		(16)
+#define DPTXFSIZn_DPTxFSize_GET(_v)		(((_v) >> 16) & 0xffff)
+#define DPTXFSIZn_DPTxFSize_LIMIT		(0xffff)
+#define DPTXFSIZn_DPTxFSize(_x)		((_x) << 16)
+
+#define DPTXFSIZn_DPTxFStAddr_MASK		(0xffff << 0)
+#define DPTXFSIZn_DPTxFStAddr_SHIFT		(0)
+
+/* Device mode registers */
+#define DCFG					HSOTG_REG(0x800)
+
+#define DCFG_EPMisCnt_MASK			(0x1f << 18)
+#define DCFG_EPMisCnt_SHIFT			(18)
+#define DCFG_EPMisCnt_LIMIT			(0x1f)
+#define DCFG_EPMisCnt(_x)			((_x) << 18)
+
+#define DCFG_PerFrInt_MASK			(0x3 << 11)
+#define DCFG_PerFrInt_SHIFT			(11)
+#define DCFG_PerFrInt_LIMIT			(0x3)
+#define DCFG_PerFrInt(_x)			((_x) << 11)
+
+#define DCFG_DevAddr_MASK			(0x7f << 4)
+#define DCFG_DevAddr_SHIFT			(4)
+#define DCFG_DevAddr_LIMIT			(0x7f)
+#define DCFG_DevAddr(_x)			((_x) << 4)
+
+#define DCFG_NZStsOUTHShk			(1 << 2)
+
+#define DCFG_DevSpd_MASK			(0x3 << 0)
+#define DCFG_DevSpd_SHIFT			(0)
+#define DCFG_DevSpd_HS				(0x0 << 0)
+#define DCFG_DevSpd_FS				(0x1 << 0)
+#define DCFG_DevSpd_LS				(0x2 << 0)
+#define DCFG_DevSpd_FS48			(0x3 << 0)
+
+#define DCTL					HSOTG_REG(0x804)
+
+#define DCTL_PWROnPrgDone			(1 << 11)
+#define DCTL_CGOUTNak				(1 << 10)
+#define DCTL_SGOUTNak				(1 << 9)
+#define DCTL_CGNPInNAK				(1 << 8)
+#define DCTL_SGNPInNAK				(1 << 7)
+#define DCTL_TstCtl_MASK			(0x7 << 4)
+#define DCTL_TstCtl_SHIFT			(4)
+#define DCTL_GOUTNakSts			(1 << 3)
+#define DCTL_GNPINNakSts			(1 << 2)
+#define DCTL_SftDiscon				(1 << 1)
+#define DCTL_RmtWkUpSig			(1 << 0)
+
+#define DSTS					HSOTG_REG(0x808)
+
+#define DSTS_SOFFN_MASK			(0x3fff << 8)
+#define DSTS_SOFFN_SHIFT			(8)
+#define DSTS_SOFFN_LIMIT			(0x3fff)
+#define DSTS_SOFFN(_x)				((_x) << 8)
+#define DSTS_ErraticErr			(1 << 3)
+#define DSTS_EnumSpd_MASK			(0x3 << 1)
+#define DSTS_EnumSpd_SHIFT			(1)
+#define DSTS_EnumSpd_HS			(0x0 << 1)
+#define DSTS_EnumSpd_FS			(0x1 << 1)
+#define DSTS_EnumSpd_LS			(0x2 << 1)
+#define DSTS_EnumSpd_FS48			(0x3 << 1)
+
+#define DSTS_SuspSts				(1 << 0)
+
+#define DIEPMSK				HSOTG_REG(0x810)
+
+#define DIEPMSK_TxFIFOEmpty			(1 << 7)
+#define DIEPMSK_INEPNakEffMsk			(1 << 6)
+#define DIEPMSK_INTknEPMisMsk			(1 << 5)
+#define DIEPMSK_INTknTXFEmpMsk			(1 << 4)
+#define DIEPMSK_TimeOUTMsk			(1 << 3)
+#define DIEPMSK_AHBErrMsk			(1 << 2)
+#define DIEPMSK_EPDisbldMsk			(1 << 1)
+#define DIEPMSK_XferComplMsk			(1 << 0)
+
+#define DOEPMSK				HSOTG_REG(0x814)
+
+#define DOEPMSK_Back2BackSetup			(1 << 6)
+#define DOEPMSK_OUTTknEPdisMsk			(1 << 4)
+#define DOEPMSK_SetupMsk			(1 << 3)
+#define DOEPMSK_AHBErrMsk			(1 << 2)
+#define DOEPMSK_EPDisbldMsk			(1 << 1)
+#define DOEPMSK_XferComplMsk			(1 << 0)
+
+#define DAINT					HSOTG_REG(0x818)
+#define DAINTMSK				HSOTG_REG(0x81C)
+
+#define DAINT_OutEP_SHIFT			(16)
+#define DAINT_OutEP(x)				(1 << ((x) + 16))
+#define DAINT_InEP(x)				(1 << (x))
+
+#define DTKNQR1				HSOTG_REG(0x820)
+#define DTKNQR2				HSOTG_REG(0x824)
+#define DTKNQR3				HSOTG_REG(0x830)
+#define DTKNQR4				HSOTG_REG(0x834)
+
+#define DVBUSDIS				HSOTG_REG(0x828)
+#define DVBUSPULSE				HSOTG_REG(0x82C)
+
+#define DIEPCTL0				HSOTG_REG(0x900)
+#define DOEPCTL0				HSOTG_REG(0xB00)
+#define DIEPCTL(_a)			HSOTG_REG(0x900 + ((_a) * 0x20))
+#define DOEPCTL(_a)			HSOTG_REG(0xB00 + ((_a) * 0x20))
+
+/* EP0 specialness:
+ * bits[29..28] - reserved (no SetD0PID, SetD1PID)
+ * bits[25..22] - should always be zero, this isn't a periodic endpoint
+ * bits[10..0] - MPS setting differenct for EP0
+ */
+#define D0EPCTL_MPS_MASK			(0x3 << 0)
+#define D0EPCTL_MPS_SHIFT			(0)
+#define D0EPCTL_MPS_64				(0x0 << 0)
+#define D0EPCTL_MPS_32				(0x1 << 0)
+#define D0EPCTL_MPS_16				(0x2 << 0)
+#define D0EPCTL_MPS_8				(0x3 << 0)
+
+#define DxEPCTL_EPEna				(1 << 31)
+#define DxEPCTL_EPDis				(1 << 30)
+#define DxEPCTL_SetD1PID			(1 << 29)
+#define DxEPCTL_SetOddFr			(1 << 29)
+#define DxEPCTL_SetD0PID			(1 << 28)
+#define DxEPCTL_SetEvenFr			(1 << 28)
+#define DxEPCTL_SNAK				(1 << 27)
+#define DxEPCTL_CNAK				(1 << 26)
+#define DxEPCTL_TxFNum_MASK			(0xf << 22)
+#define DxEPCTL_TxFNum_SHIFT			(22)
+#define DxEPCTL_TxFNum_LIMIT			(0xf)
+#define DxEPCTL_TxFNum(_x)			((_x) << 22)
+
+#define DxEPCTL_Stall				(1 << 21)
+#define DxEPCTL_Snp				(1 << 20)
+#define DxEPCTL_EPType_MASK			(0x3 << 18)
+#define DxEPCTL_EPType_SHIFT			(18)
+#define DxEPCTL_EPType_Control			(0x0 << 18)
+#define DxEPCTL_EPType_Iso			(0x1 << 18)
+#define DxEPCTL_EPType_Bulk			(0x2 << 18)
+#define DxEPCTL_EPType_Intterupt		(0x3 << 18)
+
+#define DxEPCTL_NAKsts				(1 << 17)
+#define DxEPCTL_DPID				(1 << 16)
+#define DxEPCTL_EOFrNum			(1 << 16)
+#define DxEPCTL_USBActEp			(1 << 15)
+#define DxEPCTL_NextEp_MASK			(0xf << 11)
+#define DxEPCTL_NextEp_SHIFT			(11)
+#define DxEPCTL_NextEp_LIMIT			(0xf)
+#define DxEPCTL_NextEp(_x)			((_x) << 11)
+
+#define DxEPCTL_MPS_MASK			(0x7ff << 0)
+#define DxEPCTL_MPS_SHIFT			(0)
+#define DxEPCTL_MPS_LIMIT			(0x7ff)
+#define DxEPCTL_MPS(_x)			((_x) << 0)
+
+#define DIEPINT(_a)			HSOTG_REG(0x908 + ((_a) * 0x20))
+#define DOEPINT(_a)			HSOTG_REG(0xB08 + ((_a) * 0x20))
+
+#define DxEPINT_INEPNakEff			(1 << 6)
+#define DxEPINT_Back2BackSetup			(1 << 6)
+#define DxEPINT_INTknEPMis			(1 << 5)
+#define DxEPINT_INTknTXFEmp			(1 << 4)
+#define DxEPINT_OUTTknEPdis			(1 << 4)
+#define DxEPINT_Timeout			(1 << 3)
+#define DxEPINT_Setup				(1 << 3)
+#define DxEPINT_AHBErr				(1 << 2)
+#define DxEPINT_EPDisbld			(1 << 1)
+#define DxEPINT_XferCompl			(1 << 0)
+
+#define DIEPTSIZ0				HSOTG_REG(0x910)
+
+#define DIEPTSIZ0_PktCnt_MASK			(0x3 << 19)
+#define DIEPTSIZ0_PktCnt_SHIFT			(19)
+#define DIEPTSIZ0_PktCnt_LIMIT			(0x3)
+#define DIEPTSIZ0_PktCnt(_x)			((_x) << 19)
+
+#define DIEPTSIZ0_XferSize_MASK		(0x7f << 0)
+#define DIEPTSIZ0_XferSize_SHIFT		(0)
+#define DIEPTSIZ0_XferSize_LIMIT		(0x7f)
+#define DIEPTSIZ0_XferSize(_x)			((_x) << 0)
+
+#define DOEPTSIZ0				HSOTG_REG(0xB10)
+#define DOEPTSIZ0_SUPCnt_MASK			(0x3 << 29)
+#define DOEPTSIZ0_SUPCnt_SHIFT			(29)
+#define DOEPTSIZ0_SUPCnt_LIMIT			(0x3)
+#define DOEPTSIZ0_SUPCnt(_x)			((_x) << 29)
+
+#define DOEPTSIZ0_PktCnt			(1 << 19)
+#define DOEPTSIZ0_XferSize_MASK		(0x7f << 0)
+#define DOEPTSIZ0_XferSize_SHIFT		(0)
+
+#define DIEPTSIZ(_a)			HSOTG_REG(0x910 + ((_a) * 0x20))
+#define DOEPTSIZ(_a)			HSOTG_REG(0xB10 + ((_a) * 0x20))
+
+#define DxEPTSIZ_MC_MASK			(0x3 << 29)
+#define DxEPTSIZ_MC_SHIFT			(29)
+#define DxEPTSIZ_MC_LIMIT			(0x3)
+#define DxEPTSIZ_MC(_x)			((_x) << 29)
+
+#define DxEPTSIZ_PktCnt_MASK			(0x3ff << 19)
+#define DxEPTSIZ_PktCnt_SHIFT			(19)
+#define DxEPTSIZ_PktCnt_GET(_v)		(((_v) >> 19) & 0x3ff)
+#define DxEPTSIZ_PktCnt_LIMIT			(0x3ff)
+#define DxEPTSIZ_PktCnt(_x)			((_x) << 19)
+
+#define DxEPTSIZ_XferSize_MASK			(0x7ffff << 0)
+#define DxEPTSIZ_XferSize_SHIFT		(0)
+#define DxEPTSIZ_XferSize_GET(_v)		(((_v) >> 0) & 0x7ffff)
+#define DxEPTSIZ_XferSize_LIMIT		(0x7ffff)
+#define DxEPTSIZ_XferSize(_x)			((_x) << 0)
+
+#define DIEPDMA(_a)			HSOTG_REG(0x914 + ((_a) * 0x20))
+#define DOEPDMA(_a)			HSOTG_REG(0xB14 + ((_a) * 0x20))
+#define DTXFSTS(_a)			HSOTG_REG(0x918 + ((_a) * 0x20))
+
+#define EPFIFO(_a)			HSOTG_REG(0x1000 + ((_a) * 0x1000))
+
+#endif /* __REGS_USB_HSOTG_H */
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c
index cef9b82..36c6836 100644
--- a/drivers/usb/gadget/s3c-hsudc.c
+++ b/drivers/usb/gadget/s3c-hsudc.c
@@ -110,7 +110,6 @@
 	struct usb_ep ep;
 	char name[20];
 	struct s3c_hsudc *dev;
-	const struct usb_endpoint_descriptor *desc;
 	struct list_head queue;
 	u8 stopped;
 	u8 wedge;
@@ -761,7 +760,7 @@
 	u32 ecr = 0;
 
 	hsep = our_ep(_ep);
-	if (!_ep || !desc || hsep->desc || _ep->name == ep0name
+	if (!_ep || !desc || hsep->ep.desc || _ep->name == ep0name
 		|| desc->bDescriptorType != USB_DT_ENDPOINT
 		|| hsep->bEndpointAddress != desc->bEndpointAddress
 		|| ep_maxpacket(hsep) < usb_endpoint_maxp(desc))
@@ -783,7 +782,7 @@
 	writel(ecr, hsudc->regs + S3C_ECR);
 
 	hsep->stopped = hsep->wedge = 0;
-	hsep->desc = desc;
+	hsep->ep.desc = desc;
 	hsep->ep.maxpacket = usb_endpoint_maxp(desc);
 
 	s3c_hsudc_set_halt(_ep, 0);
@@ -806,7 +805,7 @@
 	struct s3c_hsudc *hsudc = hsep->dev;
 	unsigned long flags;
 
-	if (!_ep || !hsep->desc)
+	if (!_ep || !hsep->ep.desc)
 		return -EINVAL;
 
 	spin_lock_irqsave(&hsudc->lock, flags);
@@ -816,7 +815,6 @@
 
 	s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
 
-	hsep->desc = 0;
 	hsep->ep.desc = NULL;
 	hsep->stopped = 1;
 
@@ -1006,7 +1004,6 @@
 	hsep->ep.maxpacket = epnum ? 512 : 64;
 	hsep->ep.ops = &s3c_hsudc_ep_ops;
 	hsep->fifo = hsudc->regs + S3C_BR(epnum);
-	hsep->desc = 0;
 	hsep->ep.desc = NULL;
 	hsep->stopped = 0;
 	hsep->wedge = 0;
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index 195524c..3de71d3 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1062,7 +1062,7 @@
 
 	ep = to_s3c2410_ep(_ep);
 
-	if (!_ep || !desc || ep->desc
+	if (!_ep || !desc || ep->ep.desc
 			|| _ep->name == ep0name
 			|| desc->bDescriptorType != USB_DT_ENDPOINT)
 		return -EINVAL;
@@ -1075,7 +1075,7 @@
 
 	local_irq_save (flags);
 	_ep->maxpacket = max & 0x7ff;
-	ep->desc = desc;
+	ep->ep.desc = desc;
 	ep->halted = 0;
 	ep->bEndpointAddress = desc->bEndpointAddress;
 
@@ -1136,7 +1136,7 @@
 	unsigned long flags;
 	u32 int_en_reg;
 
-	if (!_ep || !ep->desc) {
+	if (!_ep || !ep->ep.desc) {
 		dprintk(DEBUG_NORMAL, "%s not enabled\n",
 			_ep ? ep->ep.name : NULL);
 		return -EINVAL;
@@ -1146,7 +1146,6 @@
 
 	dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name);
 
-	ep->desc = NULL;
 	ep->ep.desc = NULL;
 	ep->halted = 1;
 
@@ -1195,7 +1194,7 @@
 
 	dprintk(DEBUG_VERBOSE, "%s(%p,%p)\n", __func__, _ep, _req);
 
-	if (!ep || !_req || (!ep->desc && _ep->name != ep0name))
+	if (!ep || !_req || (!ep->ep.desc && _ep->name != ep0name))
 		return;
 
 	WARN_ON (!list_empty (&req->queue));
@@ -1215,7 +1214,7 @@
 	int			fifo_count = 0;
 	unsigned long		flags;
 
-	if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+	if (unlikely(!_ep || (!ep->ep.desc && ep->ep.name != ep0name))) {
 		dprintk(DEBUG_NORMAL, "%s: invalid args\n", __func__);
 		return -EINVAL;
 	}
@@ -1363,7 +1362,7 @@
 	unsigned long		flags;
 	u32			idx;
 
-	if (unlikely (!_ep || (!ep->desc && ep->ep.name != ep0name))) {
+	if (unlikely(!_ep || (!ep->ep.desc && ep->ep.name != ep0name))) {
 		dprintk(DEBUG_NORMAL, "%s: inval 2\n", __func__);
 		return -EINVAL;
 	}
@@ -1629,7 +1628,6 @@
 			list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
 
 		ep->dev = dev;
-		ep->desc = NULL;
 		ep->ep.desc = NULL;
 		ep->halted = 0;
 		INIT_LIST_HEAD (&ep->queue);
diff --git a/drivers/usb/gadget/s3c2410_udc.h b/drivers/usb/gadget/s3c2410_udc.h
index 1653bae..3e80fd5 100644
--- a/drivers/usb/gadget/s3c2410_udc.h
+++ b/drivers/usb/gadget/s3c2410_udc.h
@@ -19,7 +19,6 @@
 	unsigned long			last_io;	/* jiffies timestamp */
 	struct usb_gadget		*gadget;
 	struct s3c2410_udc		*dev;
-	const struct usb_endpoint_descriptor *desc;
 	struct usb_ep			ep;
 	u8				num;
 
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 29c854b..47cf48b 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -744,10 +744,11 @@
 };
 
 /**
- * gether_setup - initialize one ethernet-over-usb link
+ * gether_setup_name - initialize one ethernet-over-usb link
  * @g: gadget to associated with these links
  * @ethaddr: NULL, or a buffer in which the ethernet address of the
  *	host side of the link is recorded
+ * @netname: name for network device (for example, "usb")
  * Context: may sleep
  *
  * This sets up the single network link that may be exported by a
@@ -756,7 +757,8 @@
  *
  * Returns negative errno, or zero on success
  */
-int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
+int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+		const char *netname)
 {
 	struct eth_dev		*dev;
 	struct net_device	*net;
@@ -780,7 +782,7 @@
 
 	/* network device setup */
 	dev->net = net;
-	strcpy(net->name, "usb%d");
+	snprintf(net->name, sizeof(net->name), "%s%%d", netname);
 
 	if (get_ether_addr(dev_addr, net->dev_addr))
 		dev_warn(&g->dev,
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
index 8012357..6f4a1623 100644
--- a/drivers/usb/gadget/u_ether.h
+++ b/drivers/usb/gadget/u_ether.h
@@ -69,9 +69,28 @@
 			|USB_CDC_PACKET_TYPE_PROMISCUOUS \
 			|USB_CDC_PACKET_TYPE_DIRECTED)
 
+/* variant of gether_setup that allows customizing network device name */
+int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN],
+		const char *netname);
 
 /* netdev setup/teardown as directed by the gadget driver */
-int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]);
+/* gether_setup - initialize one ethernet-over-usb link
+ * @g: gadget to associated with these links
+ * @ethaddr: NULL, or a buffer in which the ethernet address of the
+ *	host side of the link is recorded
+ * Context: may sleep
+ *
+ * This sets up the single network link that may be exported by a
+ * gadget driver using this framework.  The link layer addresses are
+ * set up using module parameters.
+ *
+ * Returns negative errno, or zero on success
+ */
+static inline int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
+{
+	return gether_setup_name(g, ethaddr, "usb");
+}
+
 void gether_cleanup(void);
 
 /* connect/disconnect is handled by individual functions */
@@ -99,16 +118,37 @@
 
 #ifdef USB_ETH_RNDIS
 
-int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+int rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				u32 vendorID, const char *manufacturer);
 
 #else
 
 static inline int
-rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN],
+				u32 vendorID, const char *manufacturer)
 {
 	return 0;
 }
 
 #endif
 
+/**
+ * rndis_bind_config - add RNDIS network link to a configuration
+ * @c: the configuration to support the network link
+ * @ethaddr: a buffer in which the ethernet address of the host side
+ *	side of the link was recorded
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gether_setup().  Caller is also responsible
+ * for calling @gether_cleanup() before module unload.
+ */
+static inline int rndis_bind_config(struct usb_configuration *c,
+				    u8 ethaddr[ETH_ALEN])
+{
+	return rndis_bind_config_vendor(c, ethaddr, 0, NULL);
+}
+
+
 #endif /* __U_ETHER_H */
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 6c23938..380a87f 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1025,7 +1025,7 @@
 
 static struct tty_driver *gs_tty_driver;
 
-static int __init
+static int
 gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
 {
 	struct gs_port	*port;
@@ -1071,7 +1071,7 @@
  *
  * Returns negative errno or zero.
  */
-int __init gserial_setup(struct usb_gadget *g, unsigned count)
+int gserial_setup(struct usb_gadget *g, unsigned count)
 {
 	unsigned			i;
 	struct usb_cdc_line_coding	coding;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 31d3483..12ad516 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -72,7 +72,7 @@
 
 static const char longname[] = "Gadget Zero";
 
-unsigned buflen = 4096;
+unsigned buflen = 4096;		/* only used for bulk endpoints */
 module_param(buflen, uint, 0);
 
 /*
@@ -170,14 +170,17 @@
 
 /*-------------------------------------------------------------------------*/
 
-struct usb_request *alloc_ep_req(struct usb_ep *ep)
+struct usb_request *alloc_ep_req(struct usb_ep *ep, int len)
 {
 	struct usb_request	*req;
 
 	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
 	if (req) {
-		req->length = buflen;
-		req->buf = kmalloc(buflen, GFP_ATOMIC);
+		if (len)
+			req->length = len;
+		else
+			req->length = buflen;
+		req->buf = kmalloc(req->length, GFP_ATOMIC);
 		if (!req->buf) {
 			usb_ep_free_request(ep, req);
 			req = NULL;
@@ -206,10 +209,15 @@
 }
 
 void disable_endpoints(struct usb_composite_dev *cdev,
-		struct usb_ep *in, struct usb_ep *out)
+		struct usb_ep *in, struct usb_ep *out,
+		struct usb_ep *iso_in, struct usb_ep *iso_out)
 {
 	disable_ep(cdev, in);
 	disable_ep(cdev, out);
+	if (iso_in)
+		disable_ep(cdev, iso_in);
+	if (iso_out)
+		disable_ep(cdev, iso_out);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -311,7 +319,6 @@
 		device_desc.bcdDevice = cpu_to_le16(0x9999);
 	}
 
-
 	INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
 
 	snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f788eb8..74a14f6 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -65,7 +65,7 @@
 
 config USB_EHCI_ROOT_HUB_TT
 	bool "Root Hub Transaction Translators"
-	depends on USB_EHCI_HCD
+	depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST
 	---help---
 	  Some EHCI chips have vendor-specific extensions to integrate
 	  transaction translators, so that no OHCI or UHCI companion
@@ -77,7 +77,7 @@
 
 config USB_EHCI_TT_NEWSCHED
 	bool "Improved Transaction Translator scheduling"
-	depends on USB_EHCI_HCD
+	depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST
 	default y
 	---help---
 	  This changes the periodic scheduling code to fill more of the low
@@ -110,13 +110,14 @@
 	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
 				    ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
 				    PPC_MPC512x || CPU_CAVIUM_OCTEON || \
-				    PMC_MSP || SPARC_LEON)
+				    PMC_MSP || SPARC_LEON || MIPS_SEAD3)
 	default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
 	bool
 	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
-				    PPC_MPC512x || PMC_MSP || SPARC_LEON)
+				    PPC_MPC512x || PMC_MSP || SPARC_LEON || \
+				    MIPS_SEAD3)
 	default y
 
 config XPS_USB_HCD_XILINX
@@ -291,6 +292,7 @@
 	depends on USB && USB_ARCH_HAS_OHCI
 	select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
 	select USB_OTG_UTILS if ARCH_OMAP
+	select USB_ISP1301 if ARCH_LPC32XX || ARCH_PNX4008
 	---help---
 	  The Open Host Controller Interface (OHCI) is a standard for accessing
 	  USB 1.1 host controller hardware.  It does more in hardware than Intel's
@@ -373,10 +375,15 @@
 	  If unsure, say Y.
 
 config USB_OHCI_HCD_SSB
-	bool "OHCI support for Broadcom SSB OHCI core"
+	bool "OHCI support for Broadcom SSB OHCI core (DEPRECATED)"
 	depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL
+	select USB_HCD_SSB
+	select USB_OHCI_HCD_PLATFORM
 	default n
 	---help---
+	  This option is deprecated now and the driver was removed, use
+	  USB_HCD_SSB and USB_OHCI_HCD_PLATFORM instead.
+
 	  Support for the Sonics Silicon Backplane (SSB) attached
 	  Broadcom USB OHCI core.
 
@@ -638,3 +645,27 @@
 config USB_OCTEON2_COMMON
 	bool
 	default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
+
+config USB_HCD_BCMA
+	tristate "BCMA usb host driver"
+	depends on BCMA && EXPERIMENTAL
+	select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+	select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
+	help
+	  Enbale support for the EHCI and OCHI host controller on an bcma bus.
+	  It converts the bcma driver into two platform device drivers
+	  for ehci and ohci.
+
+	  If unsure, say N.
+
+config USB_HCD_SSB
+	tristate "SSB usb host driver"
+	depends on SSB && EXPERIMENTAL
+	select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+	select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
+	help
+	  Enbale support for the EHCI and OCHI host controller on an bcma bus.
+	  It converts the bcma driver into two platform device drivers
+	  for ehci and ohci.
+
+	  If unsure, say N.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 0982bcc..9e0a89c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -41,3 +41,5 @@
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
 obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
 obj-$(CONFIG_MIPS_ALCHEMY)	+= alchemy-common.o
+obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
+obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
new file mode 100644
index 0000000..443da21
--- /dev/null
+++ b/drivers/usb/host/bcma-hcd.c
@@ -0,0 +1,335 @@
+/*
+ * Broadcom specific Advanced Microcontroller Bus
+ * Broadcom USB-core driver (BCMA bus glue)
+ *
+ * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Based on ssb-ohci driver
+ * Copyright 2007 Michael Buesch <m@bues.ch>
+ *
+ * Derived from the OHCI-PCI driver
+ * Copyright 1999 Roman Weissgaerber
+ * Copyright 2000-2002 David Brownell
+ * Copyright 1999 Linus Torvalds
+ * Copyright 1999 Gregory P. Smith
+ *
+ * Derived from the USBcore related parts of Broadcom-SB
+ * Copyright 2005-2011 Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/bcma/bcma.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
+MODULE_LICENSE("GPL");
+
+struct bcma_hcd_device {
+	struct platform_device *ehci_dev;
+	struct platform_device *ohci_dev;
+};
+
+/* Wait for bitmask in a register to get set or cleared.
+ * timeout is in units of ten-microseconds.
+ */
+static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
+			  int timeout)
+{
+	int i;
+	u32 val;
+
+	for (i = 0; i < timeout; i++) {
+		val = bcma_read32(dev, reg);
+		if ((val & bitmask) == bitmask)
+			return 0;
+		udelay(10);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
+{
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+	/* Work around for 4716 failures. */
+	if (dev->bus->chipinfo.id == 0x4716) {
+		u32 tmp;
+
+		tmp = bcma_cpu_clock(&dev->bus->drv_mips);
+		if (tmp >= 480000000)
+			tmp = 0x1846b; /* set CDR to 0x11(fast) */
+		else if (tmp == 453000000)
+			tmp = 0x1046b; /* set CDR to 0x10(slow) */
+		else
+			tmp = 0;
+
+		/* Change Shim mdio control reg to fix host not acking at
+		 * high frequencies
+		 */
+		if (tmp) {
+			bcma_write32(dev, 0x524, 0x1); /* write sel to enable */
+			udelay(500);
+
+			bcma_write32(dev, 0x524, tmp);
+			udelay(500);
+			bcma_write32(dev, 0x524, 0x4ab);
+			udelay(500);
+			bcma_read32(dev, 0x528);
+			bcma_write32(dev, 0x528, 0x80000000);
+		}
+	}
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
+}
+
+/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
+static void __devinit bcma_hcd_init_chip(struct bcma_device *dev)
+{
+	u32 tmp;
+
+	/*
+	 * USB 2.0 special considerations:
+	 *
+	 * 1. Since the core supports both OHCI and EHCI functions, it must
+	 *    only be reset once.
+	 *
+	 * 2. In addition to the standard SI reset sequence, the Host Control
+	 *    Register must be programmed to bring the USB core and various
+	 *    phy components out of reset.
+	 */
+	if (!bcma_core_is_enabled(dev)) {
+		bcma_core_enable(dev, 0);
+		mdelay(10);
+		if (dev->id.rev >= 5) {
+			/* Enable Misc PLL */
+			tmp = bcma_read32(dev, 0x1e0);
+			tmp |= 0x100;
+			bcma_write32(dev, 0x1e0, tmp);
+			if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100))
+				printk(KERN_EMERG "Failed to enable misc PPL!\n");
+
+			/* Take out of resets */
+			bcma_write32(dev, 0x200, 0x4ff);
+			udelay(25);
+			bcma_write32(dev, 0x200, 0x6ff);
+			udelay(25);
+
+			/* Make sure digital and AFE are locked in USB PHY */
+			bcma_write32(dev, 0x524, 0x6b);
+			udelay(50);
+			tmp = bcma_read32(dev, 0x524);
+			udelay(50);
+			bcma_write32(dev, 0x524, 0xab);
+			udelay(50);
+			tmp = bcma_read32(dev, 0x524);
+			udelay(50);
+			bcma_write32(dev, 0x524, 0x2b);
+			udelay(50);
+			tmp = bcma_read32(dev, 0x524);
+			udelay(50);
+			bcma_write32(dev, 0x524, 0x10ab);
+			udelay(50);
+			tmp = bcma_read32(dev, 0x524);
+
+			if (bcma_wait_bits(dev, 0x528, 0xc000, 10000)) {
+				tmp = bcma_read32(dev, 0x528);
+				printk(KERN_EMERG
+				       "USB20H mdio_rddata 0x%08x\n", tmp);
+			}
+			bcma_write32(dev, 0x528, 0x80000000);
+			tmp = bcma_read32(dev, 0x314);
+			udelay(265);
+			bcma_write32(dev, 0x200, 0x7ff);
+			udelay(10);
+
+			/* Take USB and HSIC out of non-driving modes */
+			bcma_write32(dev, 0x510, 0);
+		} else {
+			bcma_write32(dev, 0x200, 0x7ff);
+
+			udelay(1);
+		}
+
+		bcma_hcd_4716wa(dev);
+	}
+}
+
+static const struct usb_ehci_pdata ehci_pdata = {
+};
+
+static const struct usb_ohci_pdata ohci_pdata = {
+};
+
+static struct platform_device * __devinit
+bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
+{
+	struct platform_device *hci_dev;
+	struct resource hci_res[2];
+	int ret = -ENOMEM;
+
+	memset(hci_res, 0, sizeof(hci_res));
+
+	hci_res[0].start = addr;
+	hci_res[0].end = hci_res[0].start + 0x1000 - 1;
+	hci_res[0].flags = IORESOURCE_MEM;
+
+	hci_res[1].start = dev->irq;
+	hci_res[1].flags = IORESOURCE_IRQ;
+
+	hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
+					"ehci-platform" , 0);
+	if (!hci_dev)
+		return NULL;
+
+	hci_dev->dev.parent = &dev->dev;
+	hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
+
+	ret = platform_device_add_resources(hci_dev, hci_res,
+					    ARRAY_SIZE(hci_res));
+	if (ret)
+		goto err_alloc;
+	if (ohci)
+		ret = platform_device_add_data(hci_dev, &ohci_pdata,
+					       sizeof(ohci_pdata));
+	else
+		ret = platform_device_add_data(hci_dev, &ehci_pdata,
+					       sizeof(ehci_pdata));
+	if (ret)
+		goto err_alloc;
+	ret = platform_device_add(hci_dev);
+	if (ret)
+		goto err_alloc;
+
+	return hci_dev;
+
+err_alloc:
+	platform_device_put(hci_dev);
+	return ERR_PTR(ret);
+}
+
+static int __devinit bcma_hcd_probe(struct bcma_device *dev)
+{
+	int err;
+	u16 chipid_top;
+	u32 ohci_addr;
+	struct bcma_hcd_device *usb_dev;
+	struct bcma_chipinfo *chipinfo;
+
+	chipinfo = &dev->bus->chipinfo;
+	/* USBcores are only connected on embedded devices. */
+	chipid_top = (chipinfo->id & 0xFF00);
+	if (chipid_top != 0x4700 && chipid_top != 0x5300)
+		return -ENODEV;
+
+	/* TODO: Probably need checks here; is the core connected? */
+
+	if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
+	    dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
+		return -EOPNOTSUPP;
+
+	usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL);
+	if (!usb_dev)
+		return -ENOMEM;
+
+	bcma_hcd_init_chip(dev);
+
+	/* In AI chips EHCI is addrspace 0, OHCI is 1 */
+	ohci_addr = dev->addr1;
+	if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
+	    && chipinfo->rev == 0)
+		ohci_addr = 0x18009000;
+
+	usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
+	if (IS_ERR(usb_dev->ohci_dev)) {
+		err = PTR_ERR(usb_dev->ohci_dev);
+		goto err_free_usb_dev;
+	}
+
+	usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
+	if (IS_ERR(usb_dev->ehci_dev)) {
+		err = PTR_ERR(usb_dev->ehci_dev);
+		goto err_unregister_ohci_dev;
+	}
+
+	bcma_set_drvdata(dev, usb_dev);
+	return 0;
+
+err_unregister_ohci_dev:
+	platform_device_unregister(usb_dev->ohci_dev);
+err_free_usb_dev:
+	kfree(usb_dev);
+	return err;
+}
+
+static void __devexit bcma_hcd_remove(struct bcma_device *dev)
+{
+	struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+	struct platform_device *ohci_dev = usb_dev->ohci_dev;
+	struct platform_device *ehci_dev = usb_dev->ehci_dev;
+
+	if (ohci_dev)
+		platform_device_unregister(ohci_dev);
+	if (ehci_dev)
+		platform_device_unregister(ehci_dev);
+
+	bcma_core_disable(dev, 0);
+}
+
+static void bcma_hcd_shutdown(struct bcma_device *dev)
+{
+	bcma_core_disable(dev, 0);
+}
+
+#ifdef CONFIG_PM
+
+static int bcma_hcd_suspend(struct bcma_device *dev)
+{
+	bcma_core_disable(dev, 0);
+
+	return 0;
+}
+
+static int bcma_hcd_resume(struct bcma_device *dev)
+{
+	bcma_core_enable(dev, 0);
+
+	return 0;
+}
+
+#else /* !CONFIG_PM */
+#define bcma_hcd_suspend	NULL
+#define bcma_hcd_resume	NULL
+#endif /* CONFIG_PM */
+
+static const struct bcma_device_id bcma_hcd_table[] __devinitconst = {
+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
+	BCMA_CORETABLE_END
+};
+MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
+
+static struct bcma_driver bcma_hcd_driver = {
+	.name		= KBUILD_MODNAME,
+	.id_table	= bcma_hcd_table,
+	.probe		= bcma_hcd_probe,
+	.remove		= __devexit_p(bcma_hcd_remove),
+	.shutdown	= bcma_hcd_shutdown,
+	.suspend	= bcma_hcd_suspend,
+	.resume		= bcma_hcd_resume,
+};
+
+static int __init bcma_hcd_init(void)
+{
+	return bcma_driver_register(&bcma_hcd_driver);
+}
+module_init(bcma_hcd_init);
+
+static void __exit bcma_hcd_exit(void)
+{
+	bcma_driver_unregister(&bcma_hcd_driver);
+}
+module_exit(bcma_hcd_exit);
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 680e1a3..7561966 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -1025,10 +1025,8 @@
 		if (strict_strtoul(buf + 5, 16, &hird))
 			return -EINVAL;
 		printk(KERN_INFO "setting hird %s %lu\n", buf + 6, hird);
-		temp = ehci_readl(ehci, &ehci->regs->command);
-		temp &= ~CMD_HIRD;
-		temp |= hird << 24;
-		ehci_writel(ehci, temp, &ehci->regs->command);
+		ehci->command = (ehci->command & ~CMD_HIRD) | (hird << 24);
+		ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	} else if (strncmp(buf, "disable", 7) == 0) {
 		if (strict_strtoul(buf + 8, 10, &port))
 			return -EINVAL;
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index d0a84bd..4336257 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -1,6 +1,6 @@
 /*
  * Copyright 2005-2009 MontaVista Software, Inc.
- * Copyright 2008      Freescale Semiconductor, Inc.
+ * Copyright 2008,2012      Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -150,8 +150,7 @@
 			retval = otg_set_host(ehci->transceiver->otg,
 					      &ehci_to_hcd(ehci)->self);
 			if (retval) {
-				if (ehci->transceiver)
-					put_device(ehci->transceiver->dev);
+				usb_put_transceiver(ehci->transceiver);
 				goto err4;
 			}
 		} else {
@@ -195,7 +194,7 @@
 
 	if (ehci->transceiver) {
 		otg_set_host(ehci->transceiver->otg, NULL);
-		put_device(ehci->transceiver->dev);
+		usb_put_transceiver(ehci->transceiver);
 	}
 
 	usb_remove_hcd(hcd);
@@ -211,22 +210,32 @@
 	usb_put_hcd(hcd);
 }
 
-static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
+static void ehci_fsl_setup_phy(struct usb_hcd *hcd,
 			       enum fsl_usb2_phy_modes phy_mode,
 			       unsigned int port_offset)
 {
-	u32 portsc;
-	struct usb_hcd *hcd = ehci_to_hcd(ehci);
+	u32 portsc, temp;
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	void __iomem *non_ehci = hcd->regs;
-	struct fsl_usb2_platform_data *pdata;
+	struct device *dev = hcd->self.controller;
+	struct fsl_usb2_platform_data *pdata = dev->platform_data;
 
-	pdata = hcd->self.controller->platform_data;
+	if (pdata->controller_ver < 0) {
+		dev_warn(hcd->self.controller, "Could not get controller version\n");
+		return;
+	}
 
 	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
 	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
 
 	switch (phy_mode) {
 	case FSL_USB2_PHY_ULPI:
+		if (pdata->controller_ver) {
+			/* controller version 1.6 or above */
+			temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+			out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
+				USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL);
+		}
 		portsc |= PORT_PTS_ULPI;
 		break;
 	case FSL_USB2_PHY_SERIAL:
@@ -236,6 +245,14 @@
 		portsc |= PORT_PTS_PTW;
 		/* fall through */
 	case FSL_USB2_PHY_UTMI:
+		if (pdata->controller_ver) {
+			/* controller version 1.6 or above */
+			temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+			out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
+				UTMI_PHY_EN | USB_CTRL_USB_EN);
+			mdelay(FSL_UTMI_PHY_DLY);  /* Delay for UTMI PHY CLK to
+						become stable - 10ms*/
+		}
 		/* enable UTMI PHY */
 		if (pdata->have_sysif_regs)
 			setbits32(non_ehci + FSL_SOC_USB_CTRL,
@@ -276,7 +293,7 @@
 
 	if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
 			(pdata->operating_mode == FSL_USB2_DR_OTG))
-		ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
+		ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
 
 	if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
 		unsigned int chip, rev, svr;
@@ -290,9 +307,9 @@
 			ehci->has_fsl_port_bug = 1;
 
 		if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
-			ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
+			ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
 		if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
-			ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
+			ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1);
 	}
 
 	if (pdata->have_sysif_regs) {
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index 863fb0c..8840368 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
+/* Copyright (C) 2005-2010,2012 Freescale Semiconductor, Inc.
  * Copyright (c) 2005 MontaVista Software
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -50,4 +50,15 @@
 #define CTRL_UTMI_PHY_EN	(1<<9)
 #define CTRL_PHY_CLK_VALID	(1 << 17)
 #define SNOOP_SIZE_2GB		0x1e
+
+/* control Register Bit Masks */
+#define ULPI_INT_EN             (1<<0)
+#define WU_INT_EN               (1<<1)
+#define USB_CTRL_USB_EN         (1<<2)
+#define LINE_STATE_FILTER__EN   (1<<3)
+#define KEEP_OTG_ON             (1<<4)
+#define OTG_PORT                (1<<5)
+#define PLL_RESET               (1<<8)
+#define UTMI_PHY_EN             (1<<9)
+#define ULPI_PHY_CLK_SEL        (1<<10)
 #endif				/* _EHCI_FSL_H */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4a3bc5b..f644ba9 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -226,8 +226,13 @@
 	if ((temp & STS_HALT) != 0)
 		return 0;
 
+	/*
+	 * This routine gets called during probe before ehci->command
+	 * has been initialized, so we can't rely on its value.
+	 */
+	ehci->command &= ~CMD_RUN;
 	temp = ehci_readl(ehci, &ehci->regs->command);
-	temp &= ~CMD_RUN;
+	temp &= ~(CMD_RUN | CMD_IAAD);
 	ehci_writel(ehci, temp, &ehci->regs->command);
 	return handshake (ehci, &ehci->regs->status,
 			  STS_HALT, STS_HALT, 16 * 125);
@@ -347,6 +352,7 @@
 	if (ehci->debug)
 		dbgp_external_startup();
 
+	ehci->command = ehci_readl(ehci, &ehci->regs->command);
 	ehci->port_c_suspend = ehci->suspended_ports =
 			ehci->resuming_ports = 0;
 	return retval;
@@ -363,16 +369,14 @@
 #endif
 
 	/* wait for any schedule enables/disables to take effect */
-	temp = ehci_readl(ehci, &ehci->regs->command) << 10;
-	temp &= STS_ASS | STS_PSS;
+	temp = (ehci->command << 10) & (STS_ASS | STS_PSS);
 	if (handshake_on_error_set_halt(ehci, &ehci->regs->status,
 					STS_ASS | STS_PSS, temp, 16 * 125))
 		return;
 
 	/* then disable anything that's still active */
-	temp = ehci_readl(ehci, &ehci->regs->command);
-	temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE);
-	ehci_writel(ehci, temp, &ehci->regs->command);
+	ehci->command &= ~(CMD_ASE | CMD_PSE);
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 
 	/* hardware can take 16 microframes to turn off ... */
 	handshake_on_error_set_halt(ehci, &ehci->regs->status,
@@ -417,9 +421,6 @@
 		 * CMD_IAAD when it sets STS_IAA.)
 		 */
 		cmd = ehci_readl(ehci, &ehci->regs->command);
-		if (cmd & CMD_IAAD)
-			ehci_writel(ehci, cmd & ~CMD_IAAD,
-					&ehci->regs->command);
 
 		/* If IAA is set here it either legitimately triggered
 		 * before we cleared IAAD above (but _way_ late, so we'll
@@ -638,7 +639,7 @@
 	INIT_LIST_HEAD(&ehci->cached_itd_list);
 	INIT_LIST_HEAD(&ehci->cached_sitd_list);
 
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
+	if (HCC_PGM_FRAMELISTLEN(hcc_params) && !ehci->sched_size_bug) {
 		/* periodic schedule size can be smaller than default */
 		switch (EHCI_TUNE_FLS) {
 		case 0: ehci->periodic_size = 1024; break;
@@ -894,11 +895,8 @@
 	/* complete the unlinking of some qh [4.15.2.3] */
 	if (status & STS_IAA) {
 		/* guard against (alleged) silicon errata */
-		if (cmd & CMD_IAAD) {
-			ehci_writel(ehci, cmd & ~CMD_IAAD,
-					&ehci->regs->command);
+		if (cmd & CMD_IAAD)
 			ehci_dbg(ehci, "IAA with IAAD still set?\n");
-		}
 		if (ehci->reclaim) {
 			COUNT(ehci->stats.reclaim);
 			end_unlink_async(ehci);
@@ -1248,6 +1246,13 @@
 }
 
 /*-------------------------------------------------------------------------*/
+/*
+ * The EHCI in ChipIdea HDRC cannot be a separate module or device,
+ * because its registers (and irq) are shared between host/gadget/otg
+ * functions  and in order to facilitate role switching we cannot
+ * give the ehci driver exclusive access to those.
+ */
+#ifndef CHIPIDEA_EHCI
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR (DRIVER_AUTHOR);
@@ -1378,6 +1383,11 @@
 #define PLATFORM_DRIVER		ehci_ls1x_driver
 #endif
 
+#ifdef CONFIG_MIPS_SEAD3
+#include "ehci-sead3.c"
+#define	PLATFORM_DRIVER		ehci_hcd_sead3_driver
+#endif
+
 #ifdef CONFIG_USB_EHCI_HCD_PLATFORM
 #include "ehci-platform.c"
 #define PLATFORM_DRIVER		ehci_platform_driver
@@ -1501,3 +1511,4 @@
 }
 module_exit(ehci_hcd_cleanup);
 
+#endif /* CHIPIDEA_EHCI */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 38fe076..fc9e7cc 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -233,7 +233,6 @@
 	/* stop schedules, clean any completed work */
 	if (ehci->rh_state == EHCI_RH_RUNNING)
 		ehci_quiesce (ehci);
-	ehci->command = ehci_readl(ehci, &ehci->regs->command);
 	ehci_work(ehci);
 
 	/* Unlike other USB host controller types, EHCI doesn't have
@@ -374,6 +373,7 @@
 	ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
 
 	/* restore CMD_RUN, framelist size, and irq threshold */
+	ehci->command |= CMD_RUN;
 	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	ehci->rh_state = EHCI_RH_RUNNING;
 
@@ -531,7 +531,8 @@
 		if (ehci->has_amcc_usb23)
 			set_ohci_hcfs(ehci, 1);
 	} else {
-		ehci_dbg (ehci, "port %d high speed\n", index + 1);
+		ehci_dbg(ehci, "port %d reset complete, port enabled\n",
+			index + 1);
 		/* ensure 440EPx ohci controller state is suspended */
 		if (ehci->has_amcc_usb23)
 			set_ohci_hcfs(ehci, 0);
@@ -699,6 +700,7 @@
 			goto error;
 		wIndex--;
 		temp = ehci_readl(ehci, status_reg);
+		temp &= ~PORT_RWC_BITS;
 
 		/*
 		 * Even if OWNER is set, so the port is owned by the
@@ -712,8 +714,7 @@
 			ehci_writel(ehci, temp & ~PORT_PE, status_reg);
 			break;
 		case USB_PORT_FEAT_C_ENABLE:
-			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
-					status_reg);
+			ehci_writel(ehci, temp | PORT_PEC, status_reg);
 			break;
 		case USB_PORT_FEAT_SUSPEND:
 			if (temp & PORT_RESET)
@@ -742,7 +743,7 @@
 				spin_lock_irqsave(&ehci->lock, flags);
 			}
 			/* resume signaling for 20 msec */
-			temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+			temp &= ~PORT_WAKE_BITS;
 			ehci_writel(ehci, temp | PORT_RESUME, status_reg);
 			ehci->reset_done[wIndex] = jiffies
 					+ msecs_to_jiffies(20);
@@ -752,9 +753,8 @@
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
-				ehci_writel(ehci,
-					  temp & ~(PORT_RWC_BITS | PORT_POWER),
-					  status_reg);
+				ehci_writel(ehci, temp & ~PORT_POWER,
+						status_reg);
 			break;
 		case USB_PORT_FEAT_C_CONNECTION:
 			if (ehci->has_lpm) {
@@ -762,12 +762,10 @@
 				temp &= ~PORT_LPM;
 				temp &= ~PORT_DEV_ADDR;
 			}
-			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
-					status_reg);
+			ehci_writel(ehci, temp | PORT_CSC, status_reg);
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
-			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
-					status_reg);
+			ehci_writel(ehci, temp | PORT_OCC, status_reg);
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 5c78f9e..a44294d 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -242,6 +242,19 @@
 
 	ehci_reset(omap_ehci);
 
+	if (pdata->phy_reset) {
+		/* Hold the PHY in RESET for enough time till
+		 * PHY is settled and ready
+		 */
+		udelay(10);
+
+		if (gpio_is_valid(pdata->reset_gpio_port[0]))
+			gpio_set_value_cansleep(pdata->reset_gpio_port[0], 1);
+
+		if (gpio_is_valid(pdata->reset_gpio_port[1]))
+			gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1);
+	}
+
 	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (ret) {
 		dev_err(dev, "failed to add hcd with err %d\n", ret);
@@ -251,19 +264,6 @@
 	/* root ports should always stay powered */
 	ehci_port_power(omap_ehci, 1);
 
-	if (pdata->phy_reset) {
-		/* Hold the PHY in RESET for enough time till
-		 * PHY is settled and ready
-		 */
-		udelay(10);
-
-		if (gpio_is_valid(pdata->reset_gpio_port[0]))
-			gpio_set_value(pdata->reset_gpio_port[0], 1);
-
-		if (gpio_is_valid(pdata->reset_gpio_port[1]))
-			gpio_set_value(pdata->reset_gpio_port[1], 1);
-	}
-
 	return 0;
 
 err_add_hcd:
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index fe8dc06..4baafa3 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -97,6 +97,13 @@
 			break;
 		}
 		break;
+
+	case PCI_VENDOR_ID_PHILIPS:
+		/*
+		 * Philips controllers set HCC_PGM_FRAMELISTLEN, but
+		 * they don't implement schedule sizes shorter than 1024.
+		 */
+		ehci->sched_size_bug = 1;
 	}
 
 	/* cache this readonly data; minimize chip reads */
@@ -368,7 +375,9 @@
 {
 	return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
 		pdev->vendor == PCI_VENDOR_ID_INTEL &&
-		pdev->device == 0x1E26;
+		(pdev->device == 0x1E26 ||
+		 pdev->device == 0x8C2D ||
+		 pdev->device == 0x8C26);
 }
 
 static void ehci_enable_xhci_companion(void)
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index d238b4e2..23c530a 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -94,12 +94,12 @@
 
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
-		pr_err("no irq provieded");
+		pr_err("no irq provided");
 		return irq;
 	}
 	res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	if (!res_mem) {
-		pr_err("no memory recourse provieded");
+		pr_err("no memory recourse provided");
 		return -ENXIO;
 	}
 
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 36ca507..4378bf7 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -943,7 +943,8 @@
 		}
 		break;
 	default:
-		dbg ("bogus dev %p speed %d", urb->dev, urb->dev->speed);
+		ehci_dbg(ehci, "bogus dev %p speed %d\n", urb->dev,
+			urb->dev->speed);
 done:
 		qh_put (qh);
 		return NULL;
@@ -981,14 +982,12 @@
 	head = ehci->async;
 	timer_action_done (ehci, TIMER_ASYNC_OFF);
 	if (!head->qh_next.qh) {
-		u32	cmd = ehci_readl(ehci, &ehci->regs->command);
-
-		if (!(cmd & CMD_ASE)) {
+		if (!(ehci->command & CMD_ASE)) {
 			/* in case a clear of CMD_ASE didn't take yet */
 			(void)handshake(ehci, &ehci->regs->status,
 					STS_ASS, 0, 150);
-			cmd |= CMD_ASE;
-			ehci_writel(ehci, cmd, &ehci->regs->command);
+			ehci->command |= CMD_ASE;
+			ehci_writel(ehci, ehci->command, &ehci->regs->command);
 			/* posted write need not be known to HC yet ... */
 		}
 	}
@@ -1204,7 +1203,6 @@
 
 static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-	int		cmd = ehci_readl(ehci, &ehci->regs->command);
 	struct ehci_qh	*prev;
 
 #ifdef DEBUG
@@ -1222,8 +1220,8 @@
 		if (ehci->rh_state != EHCI_RH_HALTED
 				&& !ehci->reclaim) {
 			/* ... and CMD_IAAD clear */
-			ehci_writel(ehci, cmd & ~CMD_ASE,
-				    &ehci->regs->command);
+			ehci->command &= ~CMD_ASE;
+			ehci_writel(ehci, ehci->command, &ehci->regs->command);
 			wmb ();
 			// handshake later, if we need to
 			timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -1253,8 +1251,7 @@
 		return;
 	}
 
-	cmd |= CMD_IAAD;
-	ehci_writel(ehci, cmd, &ehci->regs->command);
+	ehci_writel(ehci, ehci->command | CMD_IAAD, &ehci->regs->command);
 	(void)ehci_readl(ehci, &ehci->regs->command);
 	iaa_watchdog_start(ehci);
 }
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index f098e2a..c474cec 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -232,6 +232,8 @@
 	if (pdata && pdata->phy_exit)
 		pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
 
+	clk_disable(s5p_ehci->clk);
+
 	return rc;
 }
 
@@ -243,6 +245,8 @@
 	struct platform_device *pdev = to_platform_device(dev);
 	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
 
+	clk_enable(s5p_ehci->clk);
+
 	if (pdata && pdata->phy_init)
 		pdata->phy_init(pdev, S5P_USB_PHY_HOST);
 
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a60679c..33182c6 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -481,7 +481,6 @@
 
 static int enable_periodic (struct ehci_hcd *ehci)
 {
-	u32	cmd;
 	int	status;
 
 	if (ehci->periodic_sched++)
@@ -497,8 +496,8 @@
 		return status;
 	}
 
-	cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
-	ehci_writel(ehci, cmd, &ehci->regs->command);
+	ehci->command |= CMD_PSE;
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	/* posted write ... PSS happens later */
 
 	/* make sure ehci_work scans these */
@@ -511,7 +510,6 @@
 
 static int disable_periodic (struct ehci_hcd *ehci)
 {
-	u32	cmd;
 	int	status;
 
 	if (--ehci->periodic_sched)
@@ -537,8 +535,8 @@
 		return status;
 	}
 
-	cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
-	ehci_writel(ehci, cmd, &ehci->regs->command);
+	ehci->command &= ~CMD_PSE;
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	/* posted write ... */
 
 	free_cached_lists(ehci);
@@ -1333,34 +1331,36 @@
 	if (mask & ~0xffff)
 		return 0;
 
+	/* check bandwidth */
+	uframe %= period_uframes;
+	frame = uframe >> 3;
+
+#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
+	/* The tt's fullspeed bus bandwidth must be available.
+	 * tt_available scheduling guarantees 10+% for control/bulk.
+	 */
+	uf = uframe & 7;
+	if (!tt_available(ehci, period_uframes >> 3,
+			stream->udev, frame, uf, stream->tt_usecs))
+		return 0;
+#else
+	/* tt must be idle for start(s), any gap, and csplit.
+	 * assume scheduling slop leaves 10+% for control/bulk.
+	 */
+	if (!tt_no_collision(ehci, period_uframes >> 3,
+			stream->udev, frame, mask))
+		return 0;
+#endif
+
 	/* this multi-pass logic is simple, but performance may
 	 * suffer when the schedule data isn't cached.
 	 */
-
-	/* check bandwidth */
-	uframe %= period_uframes;
 	do {
 		u32		max_used;
 
 		frame = uframe >> 3;
 		uf = uframe & 7;
 
-#ifdef CONFIG_USB_EHCI_TT_NEWSCHED
-		/* The tt's fullspeed bus bandwidth must be available.
-		 * tt_available scheduling guarantees 10+% for control/bulk.
-		 */
-		if (!tt_available (ehci, period_uframes << 3,
-				stream->udev, frame, uf, stream->tt_usecs))
-			return 0;
-#else
-		/* tt must be idle for start(s), any gap, and csplit.
-		 * assume scheduling slop leaves 10+% for control/bulk.
-		 */
-		if (!tt_no_collision (ehci, period_uframes << 3,
-				stream->udev, frame, mask))
-			return 0;
-#endif
-
 		/* check starts (OUT uses more than one) */
 		max_used = ehci->uframe_periodic_max - stream->usecs;
 		for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) {
@@ -2358,7 +2358,8 @@
 				 * in the previous frame for completions.
 				 */
 				if (q.fstn->hw_prev != EHCI_LIST_END(ehci)) {
-					dbg ("ignoring completions from FSTNs");
+					ehci_dbg(ehci,
+						"ignoring completions from FSTNs\n");
 				}
 				type = Q_NEXT_TYPE(ehci, q.fstn->hw_next);
 				q = q.fstn->fstn_next;
@@ -2441,7 +2442,7 @@
 				q = *q_p;
 				break;
 			default:
-				dbg ("corrupt type %d frame %d shadow %p",
+				ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n",
 					type, frame, q.ptr);
 				// BUG ();
 				q.ptr = NULL;
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c
new file mode 100644
index 0000000..cc199e8
--- /dev/null
+++ b/drivers/usb/host/ehci-sead3.c
@@ -0,0 +1,266 @@
+/*
+ * MIPS CI13320A EHCI Host Controller driver
+ * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+
+static int ehci_sead3_setup(struct usb_hcd *hcd)
+{
+	int ret;
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+	ehci->caps = hcd->regs + 0x100;
+
+#ifdef __BIG_ENDIAN
+	ehci->big_endian_mmio = 1;
+	ehci->big_endian_desc = 1;
+#endif
+
+	ret = ehci_setup(hcd);
+	if (ret)
+		return ret;
+
+	ehci->need_io_watchdog = 0;
+
+	/* Set burst length to 16 words. */
+	ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]);
+
+	return ret;
+}
+
+const struct hc_driver ehci_sead3_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "SEAD-3 EHCI",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 *
+	 */
+	.reset			= ehci_sead3_setup,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int ret;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
+		pr_debug("resource[1] is not IORESOURCE_IRQ");
+		return -ENOMEM;
+	}
+	hcd = usb_create_hcd(&ehci_sead3_hc_driver, &pdev->dev, "SEAD-3");
+	if (!hcd)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		pr_debug("request_mem_region failed");
+		ret = -EBUSY;
+		goto err1;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		pr_debug("ioremap failed");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	/* Root hub has integrated TT. */
+	hcd->has_tt = 1;
+
+	ret = usb_add_hcd(hcd, pdev->resource[1].start,
+			  IRQF_SHARED);
+	if (ret == 0) {
+		platform_set_drvdata(pdev, hcd);
+		return ret;
+	}
+
+	iounmap(hcd->regs);
+err2:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ehci_hcd_sead3_drv_suspend(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	unsigned long flags;
+	int rc = 0;
+
+	if (time_before(jiffies, ehci->next_statechange))
+		msleep(20);
+
+	/* Root hub was already suspended. Disable irq emission and
+	 * mark HW unaccessible.  The PM and USB cores make sure that
+	 * the root hub is either suspended or stopped.
+	 */
+	ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
+	spin_lock_irqsave(&ehci->lock, flags);
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+	(void)ehci_readl(ehci, &ehci->regs->intr_enable);
+
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+	spin_unlock_irqrestore(&ehci->lock, flags);
+
+	/* could save FLADJ in case of Vaux power loss
+	 * ... we'd only use it to handle clock skew
+	 */
+
+	return rc;
+}
+
+static int ehci_hcd_sead3_drv_resume(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+	/* maybe restore FLADJ. */
+
+	if (time_before(jiffies, ehci->next_statechange))
+		msleep(100);
+
+	/* Mark hardware accessible again as we are out of D3 state by now */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+	/* If CF is still set, we maintained PCI Vaux power.
+	 * Just undo the effect of ehci_pci_suspend().
+	 */
+	if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
+		int	mask = INTR_MASK;
+
+		ehci_prepare_ports_for_controller_resume(ehci);
+		if (!hcd->self.root_hub->do_remote_wakeup)
+			mask &= ~STS_PCD;
+		ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+		ehci_readl(ehci, &ehci->regs->intr_enable);
+		return 0;
+	}
+
+	ehci_dbg(ehci, "lost power, restarting\n");
+	usb_root_hub_lost_power(hcd->self.root_hub);
+
+	/* Else reset, to cope with power loss or flush-to-storage
+	 * style "resume" having let BIOS kick in during reboot.
+	 */
+	(void) ehci_halt(ehci);
+	(void) ehci_reset(ehci);
+
+	/* emptying the schedule aborts any urbs */
+	spin_lock_irq(&ehci->lock);
+	if (ehci->reclaim)
+		end_unlink_async(ehci);
+	ehci_work(ehci);
+	spin_unlock_irq(&ehci->lock);
+
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
+	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
+
+	/* here we "know" root ports should always stay powered */
+	ehci_port_power(ehci, 1);
+
+	ehci->rh_state = EHCI_RH_SUSPENDED;
+
+	return 0;
+}
+
+static const struct dev_pm_ops sead3_ehci_pmops = {
+	.suspend	= ehci_hcd_sead3_drv_suspend,
+	.resume		= ehci_hcd_sead3_drv_resume,
+};
+
+#define SEAD3_EHCI_PMOPS (&sead3_ehci_pmops)
+
+#else
+#define SEAD3_EHCI_PMOPS NULL
+#endif
+
+static struct platform_driver ehci_hcd_sead3_driver = {
+	.probe		= ehci_hcd_sead3_drv_probe,
+	.remove		= ehci_hcd_sead3_drv_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver = {
+		.name	= "sead3-ehci",
+		.owner	= THIS_MODULE,
+		.pm	= SEAD3_EHCI_PMOPS,
+	}
+};
+
+MODULE_ALIAS("platform:sead3-ehci");
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
index 9d9cf47..ca819cd 100644
--- a/drivers/usb/host/ehci-sh.c
+++ b/drivers/usb/host/ehci-sh.c
@@ -11,6 +11,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/platform_data/ehci-sh.h>
 
 struct ehci_sh_priv {
 	struct clk *iclk, *fclk;
@@ -100,6 +101,7 @@
 	const struct hc_driver *driver = &ehci_sh_hc_driver;
 	struct resource *res;
 	struct ehci_sh_priv *priv;
+	struct ehci_sh_platdata *pdata;
 	struct usb_hcd *hcd;
 	int irq, ret;
 
@@ -124,6 +126,9 @@
 		goto fail_create_hcd;
 	}
 
+	if (pdev->dev.platform_data != NULL)
+		pdata = pdev->dev.platform_data;
+
 	/* initialize hcd */
 	hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev,
 			     dev_name(&pdev->dev));
@@ -168,6 +173,9 @@
 	clk_enable(priv->fclk);
 	clk_enable(priv->iclk);
 
+	if (pdata && pdata->phy_init)
+		pdata->phy_init();
+
 	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "Failed to add hcd");
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index 6e92855..37ba8c8 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -13,6 +13,7 @@
 
 #include <linux/clk.h>
 #include <linux/jiffies.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 
@@ -25,12 +26,12 @@
 
 static void spear_start_ehci(struct spear_ehci *ehci)
 {
-	clk_enable(ehci->clk);
+	clk_prepare_enable(ehci->clk);
 }
 
 static void spear_stop_ehci(struct spear_ehci *ehci)
 {
-	clk_disable(ehci->clk);
+	clk_disable_unprepare(ehci->clk);
 }
 
 static int ehci_spear_setup(struct usb_hcd *hcd)
@@ -168,6 +169,8 @@
 static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
 		ehci_spear_drv_resume);
 
+static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
+
 static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd ;
@@ -175,12 +178,9 @@
 	struct resource *res;
 	struct clk *usbh_clk;
 	const struct hc_driver *driver = &ehci_spear_hc_driver;
-	int *pdata = pdev->dev.platform_data;
 	int irq, retval;
 	char clk_name[20] = "usbh_clk";
-
-	if (pdata == NULL)
-		return -EFAULT;
+	static int instance = -1;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -191,8 +191,22 @@
 		goto fail_irq_get;
 	}
 
-	if (*pdata >= 0)
-		sprintf(clk_name, "usbh.%01d_clk", *pdata);
+	/*
+	 * Right now device-tree probed devices don't get dma_mask set.
+	 * Since shared usb code relies on it, set it here for now.
+	 * Once we have dma capability bindings this can go away.
+	 */
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &spear_ehci_dma_mask;
+
+	/*
+	 * Increment the device instance, when probing via device-tree
+	 */
+	if (pdev->id < 0)
+		instance++;
+	else
+		instance = pdev->id;
+	sprintf(clk_name, "usbh.%01d_clk", instance);
 
 	usbh_clk = clk_get(NULL, clk_name);
 	if (IS_ERR(usbh_clk)) {
@@ -277,6 +291,11 @@
 	return 0;
 }
 
+static struct of_device_id spear_ehci_id_table[] __devinitdata = {
+	{ .compatible = "st,spear600-ehci", },
+	{ },
+};
+
 static struct platform_driver spear_ehci_hcd_driver = {
 	.probe		= spear_ehci_hcd_drv_probe,
 	.remove		= spear_ehci_hcd_drv_remove,
@@ -285,6 +304,7 @@
 		.name = "spear-ehci",
 		.bus = &platform_bus_type,
 		.pm = &ehci_spear_pm_ops,
+		.of_match_table = of_match_ptr(spear_ehci_id_table),
 	}
 };
 
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index f214a80..e57aba5 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -147,18 +147,7 @@
 
 	spin_lock_irqsave(&ehci->lock, flags);
 
-	/*
-	 * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits
-	 * that are write on clear, by writing back the register read value, so
-	 * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits
-	 */
-	if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) {
-		temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
-		ehci_writel(ehci, temp & ~PORT_PE, status_reg);
-		goto done;
-	}
-
-	else if (typeReq == GetPortStatus) {
+	if (typeReq == GetPortStatus) {
 		temp = ehci_readl(ehci, status_reg);
 		if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
 			/* Resume completed, re-enable disconnect detection */
@@ -174,7 +163,7 @@
 			goto done;
 		}
 
-		temp &= ~PORT_WKCONN_E;
+		temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
 		temp |= PORT_WKDISC_E | PORT_WKOC_E;
 		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
 
@@ -319,26 +308,23 @@
 	return retval;
 }
 
-struct temp_buffer {
+struct dma_aligned_buffer {
 	void *kmalloc_ptr;
 	void *old_xfer_buffer;
 	u8 data[0];
 };
 
-static void free_temp_buffer(struct urb *urb)
+static void free_dma_aligned_buffer(struct urb *urb)
 {
-	enum dma_data_direction dir;
-	struct temp_buffer *temp;
+	struct dma_aligned_buffer *temp;
 
 	if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
 		return;
 
-	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+	temp = container_of(urb->transfer_buffer,
+		struct dma_aligned_buffer, data);
 
-	temp = container_of(urb->transfer_buffer, struct temp_buffer,
-			    data);
-
-	if (dir == DMA_FROM_DEVICE)
+	if (usb_urb_dir_in(urb))
 		memcpy(temp->old_xfer_buffer, temp->data,
 		       urb->transfer_buffer_length);
 	urb->transfer_buffer = temp->old_xfer_buffer;
@@ -347,10 +333,9 @@
 	urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
 }
 
-static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
+static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
 {
-	enum dma_data_direction dir;
-	struct temp_buffer *temp, *kmalloc_ptr;
+	struct dma_aligned_buffer *temp, *kmalloc_ptr;
 	size_t kmalloc_size;
 
 	if (urb->num_sgs || urb->sg ||
@@ -358,22 +343,19 @@
 	    !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
 		return 0;
 
-	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
 	/* Allocate a buffer with enough padding for alignment */
 	kmalloc_size = urb->transfer_buffer_length +
-		sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1;
+		sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1;
 
 	kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
 	if (!kmalloc_ptr)
 		return -ENOMEM;
 
-	/* Position our struct temp_buffer such that data is aligned */
+	/* Position our struct dma_aligned_buffer such that data is aligned */
 	temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;
-
 	temp->kmalloc_ptr = kmalloc_ptr;
 	temp->old_xfer_buffer = urb->transfer_buffer;
-	if (dir == DMA_TO_DEVICE)
+	if (usb_urb_dir_out(urb))
 		memcpy(temp->data, urb->transfer_buffer,
 		       urb->transfer_buffer_length);
 	urb->transfer_buffer = temp->data;
@@ -388,13 +370,13 @@
 {
 	int ret;
 
-	ret = alloc_temp_buffer(urb, mem_flags);
+	ret = alloc_dma_aligned_buffer(urb, mem_flags);
 	if (ret)
 		return ret;
 
 	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
 	if (ret)
-		free_temp_buffer(urb);
+		free_dma_aligned_buffer(urb);
 
 	return ret;
 }
@@ -402,38 +384,39 @@
 static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 {
 	usb_hcd_unmap_urb_for_dma(hcd, urb);
-	free_temp_buffer(urb);
+	free_dma_aligned_buffer(urb);
 }
 
 static const struct hc_driver tegra_ehci_hc_driver = {
 	.description		= hcd_name,
 	.product_desc		= "Tegra EHCI Host Controller",
 	.hcd_priv_size		= sizeof(struct ehci_hcd),
-
 	.flags			= HCD_USB2 | HCD_MEMORY,
 
-	.reset			= tegra_ehci_setup,
+	/* standard ehci functions */
 	.irq			= ehci_irq,
-
 	.start			= ehci_run,
 	.stop			= ehci_stop,
-	.shutdown		= tegra_ehci_shutdown,
 	.urb_enqueue		= ehci_urb_enqueue,
 	.urb_dequeue		= ehci_urb_dequeue,
-	.map_urb_for_dma	= tegra_ehci_map_urb_for_dma,
-	.unmap_urb_for_dma	= tegra_ehci_unmap_urb_for_dma,
 	.endpoint_disable	= ehci_endpoint_disable,
 	.endpoint_reset		= ehci_endpoint_reset,
 	.get_frame_number	= ehci_get_frame,
 	.hub_status_data	= ehci_hub_status_data,
-	.hub_control		= tegra_ehci_hub_control,
 	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	/* modified ehci functions for tegra */
+	.reset			= tegra_ehci_setup,
+	.shutdown		= tegra_ehci_shutdown,
+	.map_urb_for_dma	= tegra_ehci_map_urb_for_dma,
+	.unmap_urb_for_dma	= tegra_ehci_unmap_urb_for_dma,
+	.hub_control		= tegra_ehci_hub_control,
 #ifdef CONFIG_PM
 	.bus_suspend		= ehci_bus_suspend,
 	.bus_resume		= ehci_bus_resume,
 #endif
-	.relinquish_port	= ehci_relinquish_port,
-	.port_handed_over	= ehci_port_handed_over,
 };
 
 static int setup_vbus_gpio(struct platform_device *pdev)
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2694ed6..2a6652f 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -149,6 +149,7 @@
 	unsigned		use_dummy_qh:1;	/* AMD Frame List table quirk*/
 	unsigned		has_synopsys_hc_bug:1; /* Synopsys HC */
 	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */
+	unsigned		sched_size_bug:1; /* Philips */
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
index 0ea577b..c5ed881 100644
--- a/drivers/usb/host/fhci-tds.c
+++ b/drivers/usb/host/fhci-tds.c
@@ -155,7 +155,7 @@
 	struct endpoint *ep;
 	struct usb_td __iomem *td;
 	unsigned long ep_offset;
-	char *err_for = "enpoint PRAM";
+	char *err_for = "endpoint PRAM";
 	int ep_mem_size;
 	u32 i;
 
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index ab333ac..22ff6b3 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -119,6 +119,39 @@
 
 static const struct of_device_id fsl_usb2_mph_dr_of_match[];
 
+static int usb_get_ver_info(struct device_node *np)
+{
+	int ver = -1;
+
+	/*
+	 * returns 1 for usb controller version 1.6
+	 * returns 2 for usb controller version 2.2
+	 * returns 0 otherwise
+	 */
+	if (of_device_is_compatible(np, "fsl-usb2-dr")) {
+		if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6"))
+			ver = FSL_USB_VER_1_6;
+		else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2"))
+			ver = FSL_USB_VER_2_2;
+		else /* for previous controller versions */
+			ver = FSL_USB_VER_OLD;
+
+		if (ver > -1)
+			return ver;
+	}
+
+	if (of_device_is_compatible(np, "fsl-usb2-mph")) {
+		if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
+			ver = FSL_USB_VER_1_6;
+		else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2"))
+			ver = FSL_USB_VER_2_2;
+		else /* for previous controller versions */
+			ver = FSL_USB_VER_OLD;
+	}
+
+	return ver;
+}
+
 static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
 {
 	struct device_node *np = ofdev->dev.of_node;
@@ -166,6 +199,14 @@
 
 	prop = of_get_property(np, "phy_type", NULL);
 	pdata->phy_mode = determine_usb_phy(prop);
+	pdata->controller_ver = usb_get_ver_info(np);
+
+	if (pdata->have_sysif_regs) {
+		if (pdata->controller_ver < 0) {
+			dev_warn(&ofdev->dev, "Could not get controller version\n");
+			return -ENODEV;
+		}
+	}
 
 	for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
 		if (!dev_data->drivers[i])
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index fc72d44..a35bbdd 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -1562,11 +1562,14 @@
 
 	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
 		retval = -ESHUTDOWN;
+		qtd_list_free(&new_qtds);
 		goto out;
 	}
 	retval = usb_hcd_link_urb_to_ep(hcd, urb);
-	if (retval)
+	if (retval) {
+		qtd_list_free(&new_qtds);
 		goto out;
+	}
 
 	qh = urb->ep->hcpriv;
 	if (qh) {
@@ -1584,6 +1587,7 @@
 		if (!qh) {
 			retval = -ENOMEM;
 			usb_hcd_unlink_urb_from_ep(hcd, urb);
+			qtd_list_free(&new_qtds);
 			goto out;
 		}
 		list_add_tail(&qh->qh_list, ep_queue);
@@ -1683,6 +1687,7 @@
 	list_for_each_entry(qtd, &qh->qtd_list, qtd_list)
 		if (qtd->urb == urb) {
 			dequeue_urb_from_qtd(hcd, qh, qtd);
+			list_move(&qtd->qtd_list, &qh->qtd_list);
 			break;
 		}
 
@@ -2176,7 +2181,7 @@
 
 int __init init_kmem_once(void)
 {
-	urb_listitem_cachep = kmem_cache_create("isp1760 urb_listitem",
+	urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem",
 			sizeof(struct urb_listitem), 0, SLAB_TEMPORARY |
 			SLAB_MEM_SPREAD, NULL);
 
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 4592dc1..fff114f 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -398,6 +398,9 @@
 	hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
 			       irqflags, -ENOENT,
 			       &pdev->dev, dev_name(&pdev->dev), devflags);
+
+	dev_set_drvdata(&pdev->dev, hcd);
+
 	if (IS_ERR(hcd)) {
 		pr_warning("isp1760: Failed to register the HCD device\n");
 		ret = -ENODEV;
@@ -417,11 +420,16 @@
 {
 	struct resource *mem_res;
 	resource_size_t mem_size;
+	struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev);
+
+	usb_remove_hcd(hcd);
 
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mem_size = resource_size(mem_res);
 	release_mem_region(mem_res->start, mem_size);
 
+	usb_put_hcd(hcd);
+
 	return 0;
 }
 
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 13ebeca..a665b3e 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -129,7 +129,7 @@
 	if (!hcd)
 		return -ENOMEM;
 	hcd->rsrc_start = pdev->resource[0].start;
-	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+	hcd->rsrc_len = resource_size(&pdev->resource[0]);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		pr_debug("request_mem_region failed\n");
@@ -223,7 +223,7 @@
 /*-------------------------------------------------------------------------*/
 
 static int __devinit
-ohci_at91_start (struct usb_hcd *hcd)
+ohci_at91_reset (struct usb_hcd *hcd)
 {
 	struct at91_usbh_data	*board = hcd->self.controller->platform_data;
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
@@ -233,9 +233,18 @@
 		return ret;
 
 	ohci->num_ports = board->ports;
+	return 0;
+}
+
+static int __devinit
+ohci_at91_start (struct usb_hcd *hcd)
+{
+	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
+	int			ret;
 
 	if ((ret = ohci_run(ohci)) < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
@@ -418,6 +427,7 @@
 	/*
 	 * basic lifecycle operations
 	 */
+	.reset =		ohci_at91_reset,
 	.start =		ohci_at91_start,
 	.stop =			ohci_stop,
 	.shutdown =		ohci_shutdown,
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 4ea63b2..c611699 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -37,7 +37,8 @@
 		return ret;
 
 	if ((ret = ohci_run(ohci)) < 0) {
-		err ("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c
index 5a00a1e..2c9f233 100644
--- a/drivers/usb/host/ohci-cns3xxx.c
+++ b/drivers/usb/host/ohci-cns3xxx.c
@@ -41,7 +41,8 @@
 
 	ret = ohci_run(ohci);
 	if (ret < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 8435097..269b1e0 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -454,3 +454,5 @@
 		.name	= "ohci",
 	},
 };
+
+MODULE_ALIAS("platform:ohci");
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index e4bcb62..31b81f9 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -29,14 +29,14 @@
 	unsigned int pipe= urb->pipe;
 
 	if (!urb->dev || !urb->dev->bus) {
-		dbg("%s URB: no dev", str);
+		printk(KERN_DEBUG "%s URB: no dev\n", str);
 		return;
 	}
 
 #ifndef	OHCI_VERBOSE_DEBUG
 	if (status != 0)
 #endif
-	dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d",
+	printk(KERN_DEBUG "%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d\n",
 		    str,
 		    urb,
 		    usb_pipedevice (pipe),
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index 3d63574..dbfbd1d 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -47,7 +47,7 @@
 	struct usb_hcd *hcd;
 
 	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
-		dbg("resource[1] is not IORESOURCE_IRQ");
+		dev_dbg(&pdev->dev, "resource[1] is not IORESOURCE_IRQ\n");
 		return -ENOMEM;
 	}
 
@@ -65,14 +65,14 @@
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 	if (hcd->regs == NULL) {
-		dbg("ioremap failed");
+		dev_dbg(&pdev->dev, "ioremap failed\n");
 		retval = -ENOMEM;
 		goto err2;
 	}
 
 	usb_host_clock = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(usb_host_clock)) {
-		dbg("clk_get failed");
+		dev_dbg(&pdev->dev, "clk_get failed\n");
 		retval = PTR_ERR(usb_host_clock);
 		goto err3;
 	}
@@ -116,7 +116,8 @@
 		return ret;
 
 	if ((ret = ohci_run(ohci)) < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 37bb20e..2909621 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -35,7 +35,8 @@
 
 	ret = ohci_run(ohci);
 	if (ret < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 235171f..e0adf5c 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1080,11 +1080,6 @@
 #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver
 #endif
 
-#ifdef CONFIG_USB_OHCI_HCD_SSB
-#include "ohci-ssb.c"
-#define SSB_OHCI_DRIVER		ssb_ohci_driver
-#endif
-
 #ifdef CONFIG_MFD_SM501
 #include "ohci-sm501.c"
 #define SM501_OHCI_DRIVER	ohci_hcd_sm501_driver
@@ -1128,8 +1123,7 @@
 	!defined(SA1111_DRIVER) &&	\
 	!defined(PS3_SYSTEM_BUS_DRIVER) && \
 	!defined(SM501_OHCI_DRIVER) && \
-	!defined(TMIO_OHCI_DRIVER) && \
-	!defined(SSB_OHCI_DRIVER)
+	!defined(TMIO_OHCI_DRIVER)
 #error "missing bus glue for ohci-hcd"
 #endif
 
@@ -1195,12 +1189,6 @@
 		goto error_pci;
 #endif
 
-#ifdef SSB_OHCI_DRIVER
-	retval = ssb_driver_register(&SSB_OHCI_DRIVER);
-	if (retval)
-		goto error_ssb;
-#endif
-
 #ifdef SM501_OHCI_DRIVER
 	retval = platform_driver_register(&SM501_OHCI_DRIVER);
 	if (retval < 0)
@@ -1224,10 +1212,6 @@
 	platform_driver_unregister(&SM501_OHCI_DRIVER);
  error_sm501:
 #endif
-#ifdef SSB_OHCI_DRIVER
-	ssb_driver_unregister(&SSB_OHCI_DRIVER);
- error_ssb:
-#endif
 #ifdef PCI_DRIVER
 	pci_unregister_driver(&PCI_DRIVER);
  error_pci:
@@ -1275,9 +1259,6 @@
 #ifdef SM501_OHCI_DRIVER
 	platform_driver_unregister(&SM501_OHCI_DRIVER);
 #endif
-#ifdef SSB_OHCI_DRIVER
-	ssb_driver_unregister(&SSB_OHCI_DRIVER);
-#endif
 #ifdef PCI_DRIVER
 	pci_unregister_driver(&PCI_DRIVER);
 #endif
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index 6618de1..1e364ec 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -22,6 +22,8 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/usb/isp1301.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -29,7 +31,6 @@
 
 #include <mach/platform.h>
 #include <mach/irqs.h>
-#include <asm/gpio.h>
 
 #define USB_CONFIG_BASE		0x31020000
 #define PWRMAN_BASE		0x40004000
@@ -38,7 +39,9 @@
 
 /* USB_CTRL bit defines */
 #define USB_SLAVE_HCLK_EN	(1 << 24)
+#define USB_DEV_NEED_CLK_EN	(1 << 22)
 #define USB_HOST_NEED_CLK_EN	(1 << 21)
+#define PAD_CONTROL_LAST_DRIVEN	(1 << 19)
 
 #define USB_OTG_CLK_CTRL	IO_ADDRESS(USB_CONFIG_BASE + 0xFF4)
 #define USB_OTG_CLK_STAT	IO_ADDRESS(USB_CONFIG_BASE + 0xFF8)
@@ -56,54 +59,6 @@
 #define TRANSPARENT_I2C_EN	(1 << 7)
 #define HOST_EN			(1 << 0)
 
-/* ISP1301 USB transceiver I2C registers */
-#define	ISP1301_MODE_CONTROL_1		0x04	/* u8 read, set, +1 clear */
-
-#define	MC1_SPEED_REG		(1 << 0)
-#define	MC1_SUSPEND_REG		(1 << 1)
-#define	MC1_DAT_SE0		(1 << 2)
-#define	MC1_TRANSPARENT		(1 << 3)
-#define	MC1_BDIS_ACON_EN	(1 << 4)
-#define	MC1_OE_INT_EN		(1 << 5)
-#define	MC1_UART_EN		(1 << 6)
-#define	MC1_MASK		0x7f
-
-#define	ISP1301_MODE_CONTROL_2		0x12	/* u8 read, set, +1 clear */
-
-#define	MC2_GLOBAL_PWR_DN	(1 << 0)
-#define	MC2_SPD_SUSP_CTRL	(1 << 1)
-#define	MC2_BI_DI		(1 << 2)
-#define	MC2_TRANSP_BDIR0	(1 << 3)
-#define	MC2_TRANSP_BDIR1	(1 << 4)
-#define	MC2_AUDIO_EN		(1 << 5)
-#define	MC2_PSW_EN		(1 << 6)
-#define	MC2_EN2V7		(1 << 7)
-
-#define	ISP1301_OTG_CONTROL_1		0x06	/* u8 read, set, +1 clear */
-#	define	OTG1_DP_PULLUP		(1 << 0)
-#	define	OTG1_DM_PULLUP		(1 << 1)
-#	define	OTG1_DP_PULLDOWN	(1 << 2)
-#	define	OTG1_DM_PULLDOWN	(1 << 3)
-#	define	OTG1_ID_PULLDOWN	(1 << 4)
-#	define	OTG1_VBUS_DRV		(1 << 5)
-#	define	OTG1_VBUS_DISCHRG	(1 << 6)
-#	define	OTG1_VBUS_CHRG		(1 << 7)
-#define	ISP1301_OTG_STATUS		0x10	/* u8 readonly */
-#	define	OTG_B_SESS_END		(1 << 6)
-#	define	OTG_B_SESS_VLD		(1 << 7)
-
-#define ISP1301_I2C_ADDR 0x2C
-
-#define ISP1301_I2C_MODE_CONTROL_1 0x4
-#define ISP1301_I2C_MODE_CONTROL_2 0x12
-#define ISP1301_I2C_OTG_CONTROL_1 0x6
-#define ISP1301_I2C_OTG_CONTROL_2 0x10
-#define ISP1301_I2C_INTERRUPT_SOURCE 0x8
-#define ISP1301_I2C_INTERRUPT_LATCH 0xA
-#define ISP1301_I2C_INTERRUPT_FALLING 0xC
-#define ISP1301_I2C_INTERRUPT_RISING 0xE
-#define ISP1301_I2C_REG_CLEAR_ADDR 1
-
 /* On LPC32xx, those are undefined */
 #ifndef start_int_set_falling_edge
 #define start_int_set_falling_edge(irq)
@@ -113,42 +68,12 @@
 #define start_int_umask(irq)
 #endif
 
-static struct i2c_driver isp1301_driver;
 static struct i2c_client *isp1301_i2c_client;
 
 extern int usb_disabled(void);
-extern int ocpi_enable(void);
 
 static struct clk *usb_clk;
 
-static const unsigned short normal_i2c[] =
-    { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END };
-
-static int isp1301_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	return 0;
-}
-
-static int isp1301_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
-static const struct i2c_device_id isp1301_id[] = {
-	{ "isp1301_nxp", 0 },
-	{ }
-};
-
-static struct i2c_driver isp1301_driver = {
-	.driver = {
-		.name = "isp1301_nxp",
-	},
-	.probe = isp1301_probe,
-	.remove = isp1301_remove,
-	.id_table = isp1301_id,
-};
-
 static void isp1301_configure_pnx4008(void)
 {
 	/* PNX4008 only supports DAT_SE0 USB mode */
@@ -220,7 +145,7 @@
 		ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0);
 
 	/* Enable usb_need_clk clock after transceiver is initialized */
-	__raw_writel((__raw_readl(USB_CTRL) | (1 << 22)), USB_CTRL);
+	__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
 
 	printk(KERN_INFO "ISP1301 Vendor ID  : 0x%04x\n",
 	      i2c_smbus_read_word_data(isp1301_i2c_client, 0x00));
@@ -372,65 +297,55 @@
 	struct usb_hcd *hcd = 0;
 	struct ohci_hcd *ohci;
 	const struct hc_driver *driver = &ohci_nxp_hc_driver;
-	struct i2c_adapter *i2c_adap;
-	struct i2c_board_info i2c_info;
-
+	struct resource *res;
 	int ret = 0, irq;
+	struct device_node *isp1301_node;
 
-	dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
-	if (usb_disabled()) {
-		err("USB is disabled");
-		ret = -ENODEV;
+	if (pdev->dev.of_node) {
+		isp1301_node = of_parse_phandle(pdev->dev.of_node,
+						"transceiver", 0);
+	} else {
+		isp1301_node = NULL;
+	}
+
+	isp1301_i2c_client = isp1301_get_client(isp1301_node);
+	if (!isp1301_i2c_client) {
+		ret = -EPROBE_DEFER;
 		goto out;
 	}
 
-	if (pdev->num_resources != 2
-	    || pdev->resource[0].flags != IORESOURCE_MEM
-	    || pdev->resource[1].flags != IORESOURCE_IRQ) {
-		err("Invalid resource configuration");
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+	dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
+	if (usb_disabled()) {
+		dev_err(&pdev->dev, "USB is disabled\n");
 		ret = -ENODEV;
 		goto out;
 	}
 
 	/* Enable AHB slave USB clock, needed for further USB clock control */
-	__raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL);
-
-	ret = i2c_add_driver(&isp1301_driver);
-	if (ret < 0) {
-		err("failed to add ISP1301 driver");
-		goto out;
-	}
-	i2c_adap = i2c_get_adapter(2);
-	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
-	strlcpy(i2c_info.type, "isp1301_nxp", I2C_NAME_SIZE);
-	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
-						   normal_i2c, NULL);
-	i2c_put_adapter(i2c_adap);
-	if (!isp1301_i2c_client) {
-		err("failed to connect I2C to ISP1301 USB Transceiver");
-		ret = -ENODEV;
-		goto out_i2c_driver;
-	}
+	__raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL);
 
 	isp1301_configure();
 
 	/* Enable USB PLL */
 	usb_clk = clk_get(&pdev->dev, "ck_pll5");
 	if (IS_ERR(usb_clk)) {
-		err("failed to acquire USB PLL");
+		dev_err(&pdev->dev, "failed to acquire USB PLL\n");
 		ret = PTR_ERR(usb_clk);
 		goto out1;
 	}
 
 	ret = clk_enable(usb_clk);
 	if (ret < 0) {
-		err("failed to start USB PLL");
+		dev_err(&pdev->dev, "failed to start USB PLL\n");
 		goto out2;
 	}
 
 	ret = clk_set_rate(usb_clk, 48000);
 	if (ret < 0) {
-		err("failed to set USB clock rate");
+		dev_err(&pdev->dev, "failed to set USB clock rate\n");
 		goto out3;
 	}
 
@@ -442,9 +357,9 @@
 	while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
 	       USB_CLOCK_MASK) ;
 
-	hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
+	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd) {
-		err("Failed to allocate HC buffer");
+		dev_err(&pdev->dev, "Failed to allocate HC buffer\n");
 		ret = -ENOMEM;
 		goto out3;
 	}
@@ -452,14 +367,21 @@
 	/* Set all USB bits in the Start Enable register */
 	nxp_set_usb_bits();
 
-	hcd->rsrc_start = pdev->resource[0].start;
-	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
-	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		dev_dbg(&pdev->dev, "request_mem_region failed\n");
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get MEM resource\n");
 		ret =  -ENOMEM;
 		goto out4;
 	}
-	hcd->regs = (void __iomem *)pdev->resource[0].start;
+
+	hcd->regs = devm_request_and_ioremap(&pdev->dev, res);
+	if (!hcd->regs) {
+		dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n");
+		ret =  -ENOMEM;
+		goto out4;
+	}
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -486,10 +408,7 @@
 out2:
 	clk_put(usb_clk);
 out1:
-	i2c_unregister_device(isp1301_i2c_client);
 	isp1301_i2c_client = NULL;
-out_i2c_driver:
-	i2c_del_driver(&isp1301_driver);
 out:
 	return ret;
 }
@@ -507,7 +426,6 @@
 	clk_put(usb_clk);
 	i2c_unregister_device(isp1301_i2c_client);
 	isp1301_i2c_client = NULL;
-	i2c_del_driver(&isp1301_driver);
 
 	platform_set_drvdata(pdev, NULL);
 
@@ -517,10 +435,19 @@
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:usb-ohci");
 
+#ifdef CONFIG_OF
+static const struct of_device_id usb_hcd_nxp_match[] = {
+	{ .compatible = "nxp,ohci-nxp" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match);
+#endif
+
 static struct platform_driver usb_hcd_nxp_driver = {
 	.driver = {
 		.name = "usb-ohci",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(usb_hcd_nxp_match),
 	},
 	.probe = usb_hcd_nxp_probe,
 	.remove = usb_hcd_nxp_remove,
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 96451e4..74b5320 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -217,8 +217,7 @@
 			dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n",
 					ohci->transceiver->label, status);
 			if (status) {
-				if (ohci->transceiver)
-					put_device(ohci->transceiver->dev);
+				usb_put_transceiver(ohci->transceiver);
 				return status;
 			}
 		} else {
@@ -405,7 +404,7 @@
 	usb_remove_hcd(hcd);
 	if (ohci->transceiver) {
 		(void) otg_set_host(ohci->transceiver->otg, 0);
-		put_device(ohci->transceiver->dev);
+		usb_put_transceiver(ohci->transceiver);
 	}
 	if (machine_is_omap_osk())
 		gpio_free(9);
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index ec5c679..670c705 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -93,13 +93,13 @@
 
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
-		pr_err("no irq provieded");
+		pr_err("no irq provided");
 		return irq;
 	}
 
 	res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	if (!res_mem) {
-		pr_err("no memory recourse provieded");
+		pr_err("no memory recourse provided");
 		return -ENXIO;
 	}
 
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
index f13d08f..148d27d 100644
--- a/drivers/usb/host/ohci-pnx8550.c
+++ b/drivers/usb/host/ohci-pnx8550.c
@@ -157,7 +157,8 @@
 		return ret;
 
 	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s",
+			hcd->self.bus_name);
 		ohci_stop (hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index d24cc89d..e27d5ae 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -29,7 +29,8 @@
 		return ret;
 
 	if ((ret = ohci_run(ohci)) < 0) {
-		err("can't start %s", ohci_to_hcd(ohci)->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
@@ -236,7 +237,7 @@
 
 #if	!defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
 	!defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
-#error "No endianess selected for ppc-of-ohci"
+#error "No endianness selected for ppc-of-ohci"
 #endif
 
 
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 1514b70..185c39e 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -130,7 +130,8 @@
 		return ret;
 
 	if ((ret = ohci_run(ohci)) < 0) {
-		err("can't start %s", ohci_to_hcd(ohci)->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 6fd4fa1..2ee1d8d 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -45,7 +45,8 @@
 	result = ohci_run(ohci);
 
 	if (result < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 	}
 
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index c31b281..e1a3cc6 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -419,7 +419,8 @@
 		return ret;
 
 	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s",
+			hcd->self.bus_name);
 		ohci_stop (hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 56dcf06..664c869 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -420,7 +420,8 @@
 
 	ret = ohci_run(ohci);
 	if (ret < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index e1004fb..b6cc925 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -46,7 +46,7 @@
 {
 	unsigned long status = sa1111_readl(hcd->regs + USB_STATUS);
 
-	dbg("%s USB_STATUS = { %s%s%s%s%s}", label,
+	printk(KERN_DEBUG "%s USB_STATUS = { %s%s%s%s%s}\n", label,
 	     ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
 	     ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
 	     ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
@@ -193,7 +193,7 @@
 	hcd->rsrc_len = resource_size(&dev->res);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		dbg("request_mem_region failed");
+		dev_dbg(&dev->dev, "request_mem_region failed\n");
 		ret = -EBUSY;
 		goto err1;
 	}
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c
index 84686d9..76a20c2 100644
--- a/drivers/usb/host/ohci-sh.c
+++ b/drivers/usb/host/ohci-sh.c
@@ -88,20 +88,20 @@
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		err("platform_get_resource error.");
+		dev_err(&pdev->dev, "platform_get_resource error.\n");
 		return -ENODEV;
 	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
-		err("platform_get_irq error.");
+		dev_err(&pdev->dev, "platform_get_irq error.\n");
 		return -ENODEV;
 	}
 
 	/* initialize hcd */
 	hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name);
 	if (!hcd) {
-		err("Failed to create hcd");
+		dev_err(&pdev->dev, "Failed to create hcd\n");
 		return -ENOMEM;
 	}
 
@@ -110,7 +110,7 @@
 	hcd->rsrc_len = resource_size(res);
 	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (ret != 0) {
-		err("Failed to add hcd");
+		dev_err(&pdev->dev, "Failed to add hcd\n");
 		usb_put_hcd(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index 95c1648..fc7305e 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -14,6 +14,7 @@
 #include <linux/signal.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 
 struct spear_ohci {
 	struct ohci_hcd ohci;
@@ -24,12 +25,12 @@
 
 static void spear_start_ohci(struct spear_ohci *ohci)
 {
-	clk_enable(ohci->clk);
+	clk_prepare_enable(ohci->clk);
 }
 
 static void spear_stop_ohci(struct spear_ohci *ohci)
 {
-	clk_disable(ohci->clk);
+	clk_disable_unprepare(ohci->clk);
 }
 
 static int __devinit ohci_spear_start(struct usb_hcd *hcd)
@@ -90,6 +91,8 @@
 	.start_port_reset	= ohci_start_port_reset,
 };
 
+static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
+
 static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
 {
 	const struct hc_driver *driver = &ohci_spear_hc_driver;
@@ -98,11 +101,8 @@
 	struct spear_ohci *ohci_p;
 	struct resource *res;
 	int retval, irq;
-	int *pdata = pdev->dev.platform_data;
 	char clk_name[20] = "usbh_clk";
-
-	if (pdata == NULL)
-		return -EFAULT;
+	static int instance = -1;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -110,8 +110,22 @@
 		goto fail_irq_get;
 	}
 
-	if (*pdata >= 0)
-		sprintf(clk_name, "usbh.%01d_clk", *pdata);
+	/*
+	 * Right now device-tree probed devices don't get dma_mask set.
+	 * Since shared usb code relies on it, set it here for now.
+	 * Once we have dma capability bindings this can go away.
+	 */
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &spear_ohci_dma_mask;
+
+	/*
+	 * Increment the device instance, when probing via device-tree
+	 */
+	if (pdev->id < 0)
+		instance++;
+	else
+		instance = pdev->id;
+	sprintf(clk_name, "usbh.%01d_clk", instance);
 
 	usbh_clk = clk_get(NULL, clk_name);
 	if (IS_ERR(usbh_clk)) {
@@ -222,6 +236,11 @@
 }
 #endif
 
+static struct of_device_id spear_ohci_id_table[] __devinitdata = {
+	{ .compatible = "st,spear600-ohci", },
+	{ },
+};
+
 /* Driver definition to register with the platform bus */
 static struct platform_driver spear_ohci_hcd_driver = {
 	.probe =	spear_ohci_hcd_drv_probe,
@@ -233,6 +252,7 @@
 	.driver = {
 		.owner = THIS_MODULE,
 		.name = "spear-ohci",
+		.of_match_table = of_match_ptr(spear_ohci_id_table),
 	},
 };
 
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c
deleted file mode 100644
index 5ba1859..0000000
--- a/drivers/usb/host/ohci-ssb.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Sonics Silicon Backplane
- * Broadcom USB-core OHCI driver
- *
- * Copyright 2007 Michael Buesch <m@bues.ch>
- *
- * Derived from the OHCI-PCI driver
- * Copyright 1999 Roman Weissgaerber
- * Copyright 2000-2002 David Brownell
- * Copyright 1999 Linus Torvalds
- * Copyright 1999 Gregory P. Smith
- *
- * Derived from the USBcore related parts of Broadcom-SB
- * Copyright 2005 Broadcom Corporation
- *
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-#include <linux/ssb/ssb.h>
-
-
-#define SSB_OHCI_TMSLOW_HOSTMODE	(1 << 29)
-
-struct ssb_ohci_device {
-	struct ohci_hcd ohci; /* _must_ be at the beginning. */
-
-	u32 enable_flags;
-};
-
-static inline
-struct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd)
-{
-	return (struct ssb_ohci_device *)(hcd->hcd_priv);
-}
-
-
-static int ssb_ohci_reset(struct usb_hcd *hcd)
-{
-	struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
-	struct ohci_hcd *ohci = &ohcidev->ohci;
-	int err;
-
-	ohci_hcd_init(ohci);
-	err = ohci_init(ohci);
-
-	return err;
-}
-
-static int ssb_ohci_start(struct usb_hcd *hcd)
-{
-	struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
-	struct ohci_hcd *ohci = &ohcidev->ohci;
-	int err;
-
-	err = ohci_run(ohci);
-	if (err < 0) {
-		ohci_err(ohci, "can't start\n");
-		ohci_stop(hcd);
-	}
-
-	return err;
-}
-
-static const struct hc_driver ssb_ohci_hc_driver = {
-	.description		= "ssb-usb-ohci",
-	.product_desc		= "SSB OHCI Controller",
-	.hcd_priv_size		= sizeof(struct ssb_ohci_device),
-
-	.irq			= ohci_irq,
-	.flags			= HCD_MEMORY | HCD_USB11,
-
-	.reset			= ssb_ohci_reset,
-	.start			= ssb_ohci_start,
-	.stop			= ohci_stop,
-	.shutdown		= ohci_shutdown,
-
-	.urb_enqueue		= ohci_urb_enqueue,
-	.urb_dequeue		= ohci_urb_dequeue,
-	.endpoint_disable	= ohci_endpoint_disable,
-
-	.get_frame_number	= ohci_get_frame,
-
-	.hub_status_data	= ohci_hub_status_data,
-	.hub_control		= ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend		= ohci_bus_suspend,
-	.bus_resume		= ohci_bus_resume,
-#endif
-
-	.start_port_reset	= ohci_start_port_reset,
-};
-
-static void ssb_ohci_detach(struct ssb_device *dev)
-{
-	struct usb_hcd *hcd = ssb_get_drvdata(dev);
-
-	if (hcd->driver->shutdown)
-		hcd->driver->shutdown(hcd);
-	usb_remove_hcd(hcd);
-	iounmap(hcd->regs);
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-	usb_put_hcd(hcd);
-	ssb_device_disable(dev, 0);
-}
-
-static int ssb_ohci_attach(struct ssb_device *dev)
-{
-	struct ssb_ohci_device *ohcidev;
-	struct usb_hcd *hcd;
-	int err = -ENOMEM;
-	u32 tmp, flags = 0;
-
-	if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
-	    dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
-		return -EOPNOTSUPP;
-
-	if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) {
-		/* Put the device into host-mode. */
-		flags |= SSB_OHCI_TMSLOW_HOSTMODE;
-		ssb_device_enable(dev, flags);
-	} else if (dev->id.coreid == SSB_DEV_USB20_HOST) {
-		/*
-		 * USB 2.0 special considerations:
-		 *
-		 * In addition to the standard SSB reset sequence, the Host
-		 * Control Register must be programmed to bring the USB core
-		 * and various phy components out of reset.
-		 */
-		ssb_device_enable(dev, 0);
-		ssb_write32(dev, 0x200, 0x7ff);
-
-		/* Change Flush control reg */
-		tmp = ssb_read32(dev, 0x400);
-		tmp &= ~8;
-		ssb_write32(dev, 0x400, tmp);
-		tmp = ssb_read32(dev, 0x400);
-
-		/* Change Shim control reg */
-		tmp = ssb_read32(dev, 0x304);
-		tmp &= ~0x100;
-		ssb_write32(dev, 0x304, tmp);
-		tmp = ssb_read32(dev, 0x304);
-
-		udelay(1);
-
-		/* Work around for 5354 failures */
-		if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
-			/* Change syn01 reg */
-			tmp = 0x00fe00fe;
-			ssb_write32(dev, 0x894, tmp);
-
-			/* Change syn03 reg */
-			tmp = ssb_read32(dev, 0x89c);
-			tmp |= 0x1;
-			ssb_write32(dev, 0x89c, tmp);
-		}
-	} else
-		ssb_device_enable(dev, 0);
-
-	hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev,
-			dev_name(dev->dev));
-	if (!hcd)
-		goto err_dev_disable;
-	ohcidev = hcd_to_ssb_ohci(hcd);
-	ohcidev->enable_flags = flags;
-
-	tmp = ssb_read32(dev, SSB_ADMATCH0);
-	hcd->rsrc_start = ssb_admatch_base(tmp);
-	hcd->rsrc_len = ssb_admatch_size(tmp);
-	hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
-	if (!hcd->regs)
-		goto err_put_hcd;
-	err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
-	if (err)
-		goto err_iounmap;
-
-	ssb_set_drvdata(dev, hcd);
-
-	return err;
-
-err_iounmap:
-	iounmap(hcd->regs);
-err_put_hcd:
-	usb_put_hcd(hcd);
-err_dev_disable:
-	ssb_device_disable(dev, flags);
-	return err;
-}
-
-static int ssb_ohci_probe(struct ssb_device *dev,
-		const struct ssb_device_id *id)
-{
-	int err;
-	u16 chipid_top;
-
-	/* USBcores are only connected on embedded devices. */
-	chipid_top = (dev->bus->chip_id & 0xFF00);
-	if (chipid_top != 0x4700 && chipid_top != 0x5300)
-		return -ENODEV;
-
-	/* TODO: Probably need checks here; is the core connected? */
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	/* We currently always attach SSB_DEV_USB11_HOSTDEV
-	 * as HOST OHCI. If we want to attach it as Client device,
-	 * we must branch here and call into the (yet to
-	 * be written) Client mode driver. Same for remove(). */
-
-	err = ssb_ohci_attach(dev);
-
-	return err;
-}
-
-static void ssb_ohci_remove(struct ssb_device *dev)
-{
-	ssb_ohci_detach(dev);
-}
-
-#ifdef CONFIG_PM
-
-static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state)
-{
-	ssb_device_disable(dev, 0);
-
-	return 0;
-}
-
-static int ssb_ohci_resume(struct ssb_device *dev)
-{
-	struct usb_hcd *hcd = ssb_get_drvdata(dev);
-	struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
-
-	ssb_device_enable(dev, ohcidev->enable_flags);
-
-	ohci_finish_controller_resume(hcd);
-	return 0;
-}
-
-#else /* !CONFIG_PM */
-#define ssb_ohci_suspend	NULL
-#define ssb_ohci_resume	NULL
-#endif /* CONFIG_PM */
-
-static const struct ssb_device_id ssb_ohci_table[] = {
-	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
-	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
-	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
-	SSB_DEVTABLE_END
-};
-MODULE_DEVICE_TABLE(ssb, ssb_ohci_table);
-
-static struct ssb_driver ssb_ohci_driver = {
-	.name		= KBUILD_MODNAME,
-	.id_table	= ssb_ohci_table,
-	.probe		= ssb_ohci_probe,
-	.remove		= ssb_ohci_remove,
-	.suspend	= ssb_ohci_suspend,
-	.resume		= ssb_ohci_resume,
-};
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 120bfe6..60c2b07 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -140,7 +140,8 @@
 		return ret;
 
 	if ((ret = ohci_run(ohci)) < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c
index a224786..41e378f 100644
--- a/drivers/usb/host/ohci-xls.c
+++ b/drivers/usb/host/ohci-xls.c
@@ -88,7 +88,8 @@
 	ohci = hcd_to_ohci(hcd);
 	ret = ohci_run(ohci);
 	if (ret < 0) {
-		err("can't start %s", hcd->self.bus_name);
+		dev_err(hcd->self.controller, "can't start %s\n",
+			hcd->self.bus_name);
 		ohci_stop(hcd);
 		return ret;
 	}
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 3b38030..4f0f033 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -1399,8 +1399,8 @@
 				 * But interval 1 scheduling is simpler, and
 				 * includes high bandwidth.
 				 */
-				dbg("intr period %d uframes, NYET!",
-						urb->interval);
+				oxu_dbg(oxu, "intr period %d uframes, NYET!\n",
+					urb->interval);
 				goto done;
 			}
 		} else {
@@ -1471,7 +1471,7 @@
 		}
 		break;
 	default:
-		dbg("bogus dev %p speed %d", urb->dev, urb->dev->speed);
+		oxu_dbg(oxu, "bogus dev %p speed %d\n", urb->dev, urb->dev->speed);
 done:
 		qh_put(qh);
 		return NULL;
@@ -2307,7 +2307,7 @@
 				qh_put(temp.qh);
 				break;
 			default:
-				dbg("corrupt type %d frame %d shadow %p",
+				oxu_dbg(oxu, "corrupt type %d frame %d shadow %p\n",
 					type, frame, q.ptr);
 				q.ptr = NULL;
 			}
@@ -2991,8 +2991,9 @@
 				/* shouldn't happen often, but ...
 				 * FIXME kill those tds' urbs
 				 */
-				err("can't reschedule qh %p, err %d",
-					qh, status);
+				dev_err(hcd->self.controller,
+					"can't reschedule qh %p, err %d\n", qh,
+					status);
 			}
 			return status;
 		}
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 32dada8..df0828c 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/kconfig.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -712,12 +713,28 @@
 	return -ETIMEDOUT;
 }
 
-bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
+#define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI	0x8C31
+
+bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
 {
 	return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
 		pdev->vendor == PCI_VENDOR_ID_INTEL &&
 		pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI;
 }
+
+/* The Intel Lynx Point chipset also has switchable ports. */
+bool usb_is_intel_lpt_switchable_xhci(struct pci_dev *pdev)
+{
+	return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
+		pdev->vendor == PCI_VENDOR_ID_INTEL &&
+		pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI;
+}
+
+bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
+{
+	return usb_is_intel_ppt_switchable_xhci(pdev) ||
+		usb_is_intel_lpt_switchable_xhci(pdev);
+}
 EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci);
 
 /*
@@ -742,6 +759,19 @@
 {
 	u32		ports_available;
 
+	/* Don't switchover the ports if the user hasn't compiled the xHCI
+	 * driver.  Otherwise they will see "dead" USB ports that don't power
+	 * the devices.
+	 */
+	if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) {
+		dev_warn(&xhci_pdev->dev,
+				"CONFIG_USB_XHCI_HCD is turned off, "
+				"defaulting to EHCI.\n");
+		dev_warn(&xhci_pdev->dev,
+				"USB 3.0 devices will work at USB 2.0 speeds.\n");
+		return;
+	}
+
 	ports_available = 0xffffffff;
 	/* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable
 	 * Register, to turn on SuperSpeed terminations for all
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 2bf1320..c868be6 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -401,7 +401,7 @@
 		if (r8a66597->address_map & (1 << addr))
 			continue;
 
-		dbg("alloc_address: r8a66597_addr=%d", addr);
+		dev_dbg(&urb->dev->dev, "alloc_address: r8a66597_addr=%d\n", addr);
 		r8a66597->address_map |= 1 << addr;
 
 		if (make_r8a66597_device(r8a66597, urb, addr) < 0)
@@ -426,7 +426,7 @@
 	if (!dev)
 		return;
 
-	dbg("free_addr: addr=%d", dev->address);
+	dev_dbg(&dev->udev->dev, "free_addr: addr=%d\n", dev->address);
 
 	dev->state = USB_STATE_DEFAULT;
 	r8a66597->address_map &= ~(1 << dev->address);
@@ -819,7 +819,7 @@
 	struct r8a66597_device *dev = get_urb_to_r8a66597_dev(r8a66597, urb);
 	struct r8a66597_pipe *pipe = hep->hcpriv;
 
-	dbg("enable_pipe:");
+	dev_dbg(&dev->udev->dev, "enable_pipe:\n");
 
 	pipe->info = *info;
 	set_pipe_reg_addr(pipe, R8A66597_PIPE_NO_DMA);
@@ -898,7 +898,7 @@
 		force_dequeue(r8a66597, pipenum, dev->address);
 	}
 
-	dbg("disable_pipe");
+	dev_dbg(&dev->udev->dev, "disable_pipe\n");
 
 	r8a66597->dma_map &= ~(dev->dma_map);
 	dev->dma_map = 0;
@@ -2264,7 +2264,7 @@
 	struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
 	int port;
 
-	dbg("%s", __func__);
+	dev_dbg(&r8a66597->device0.udev->dev, "%s\n", __func__);
 
 	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
@@ -2273,7 +2273,7 @@
 		if (!(rh->port & USB_PORT_STAT_ENABLE))
 			continue;
 
-		dbg("suspend port = %d", port);
+		dev_dbg(&rh->dev->udev->dev, "suspend port = %d\n", port);
 		r8a66597_bclr(r8a66597, UACT, dvstctr_reg);	/* suspend */
 		rh->port |= USB_PORT_STAT_SUSPEND;
 
@@ -2295,7 +2295,7 @@
 	struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
 	int port;
 
-	dbg("%s", __func__);
+	dev_dbg(&r8a66597->device0.udev->dev, "%s\n", __func__);
 
 	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
@@ -2304,7 +2304,7 @@
 		if (!(rh->port & USB_PORT_STAT_SUSPEND))
 			continue;
 
-		dbg("resume port = %d", port);
+		dev_dbg(&rh->dev->udev->dev, "resume port = %d\n", port);
 		rh->port &= ~USB_PORT_STAT_SUSPEND;
 		rh->port |= USB_PORT_STAT_C_SUSPEND << 16;
 		r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg);
@@ -2360,7 +2360,7 @@
 	struct r8a66597		*r8a66597 = dev_get_drvdata(dev);
 	int port;
 
-	dbg("%s", __func__);
+	dev_dbg(dev, "%s\n", __func__);
 
 	disable_controller(r8a66597);
 
@@ -2378,7 +2378,7 @@
 	struct r8a66597		*r8a66597 = dev_get_drvdata(dev);
 	struct usb_hcd		*hcd = r8a66597_to_hcd(r8a66597);
 
-	dbg("%s", __func__);
+	dev_dbg(dev, "%s\n", __func__);
 
 	enable_controller(r8a66597);
 	usb_root_hub_lost_power(hcd->self.root_hub);
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c
new file mode 100644
index 0000000..c2a29fa
--- /dev/null
+++ b/drivers/usb/host/ssb-hcd.c
@@ -0,0 +1,280 @@
+/*
+ * Sonics Silicon Backplane
+ * Broadcom USB-core driver  (SSB bus glue)
+ *
+ * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Based on ssb-ohci driver
+ * Copyright 2007 Michael Buesch <m@bues.ch>
+ *
+ * Derived from the OHCI-PCI driver
+ * Copyright 1999 Roman Weissgaerber
+ * Copyright 2000-2002 David Brownell
+ * Copyright 1999 Linus Torvalds
+ * Copyright 1999 Gregory P. Smith
+ *
+ * Derived from the USBcore related parts of Broadcom-SB
+ * Copyright 2005-2011 Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/ssb/ssb.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_DESCRIPTION("Common USB driver for SSB Bus");
+MODULE_LICENSE("GPL");
+
+#define SSB_HCD_TMSLOW_HOSTMODE	(1 << 29)
+
+struct ssb_hcd_device {
+	struct platform_device *ehci_dev;
+	struct platform_device *ohci_dev;
+
+	u32 enable_flags;
+};
+
+static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
+{
+#ifdef CONFIG_SSB_DRIVER_MIPS
+	/* Work around for 5354 failures */
+	if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
+		/* Change syn01 reg */
+		ssb_write32(dev, 0x894, 0x00fe00fe);
+
+		/* Change syn03 reg */
+		ssb_write32(dev, 0x89c, ssb_read32(dev, 0x89c) | 0x1);
+	}
+#endif
+}
+
+static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
+{
+	if (dev->id.coreid == SSB_DEV_USB20_HOST) {
+		/*
+		 * USB 2.0 special considerations:
+		 *
+		 * In addition to the standard SSB reset sequence, the Host
+		 * Control Register must be programmed to bring the USB core
+		 * and various phy components out of reset.
+		 */
+		ssb_write32(dev, 0x200, 0x7ff);
+
+		/* Change Flush control reg */
+		ssb_write32(dev, 0x400, ssb_read32(dev, 0x400) & ~8);
+		ssb_read32(dev, 0x400);
+
+		/* Change Shim control reg */
+		ssb_write32(dev, 0x304, ssb_read32(dev, 0x304) & ~0x100);
+		ssb_read32(dev, 0x304);
+
+		udelay(1);
+
+		ssb_hcd_5354wa(dev);
+	}
+}
+
+/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
+static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev)
+{
+	u32 flags = 0;
+
+	if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV)
+		/* Put the device into host-mode. */
+		flags |= SSB_HCD_TMSLOW_HOSTMODE;
+
+	ssb_device_enable(dev, flags);
+
+	ssb_hcd_usb20wa(dev);
+
+	return flags;
+}
+
+static const struct usb_ehci_pdata ehci_pdata = {
+};
+
+static const struct usb_ohci_pdata ohci_pdata = {
+};
+
+static struct platform_device * __devinit
+ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
+{
+	struct platform_device *hci_dev;
+	struct resource hci_res[2];
+	int ret = -ENOMEM;
+
+	memset(hci_res, 0, sizeof(hci_res));
+
+	hci_res[0].start = addr;
+	hci_res[0].end = hci_res[0].start + len - 1;
+	hci_res[0].flags = IORESOURCE_MEM;
+
+	hci_res[1].start = dev->irq;
+	hci_res[1].flags = IORESOURCE_IRQ;
+
+	hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
+					"ehci-platform" , 0);
+	if (!hci_dev)
+		return NULL;
+
+	hci_dev->dev.parent = dev->dev;
+	hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
+
+	ret = platform_device_add_resources(hci_dev, hci_res,
+					    ARRAY_SIZE(hci_res));
+	if (ret)
+		goto err_alloc;
+	if (ohci)
+		ret = platform_device_add_data(hci_dev, &ohci_pdata,
+					       sizeof(ohci_pdata));
+	else
+		ret = platform_device_add_data(hci_dev, &ehci_pdata,
+					       sizeof(ehci_pdata));
+	if (ret)
+		goto err_alloc;
+	ret = platform_device_add(hci_dev);
+	if (ret)
+		goto err_alloc;
+
+	return hci_dev;
+
+err_alloc:
+	platform_device_put(hci_dev);
+	return ERR_PTR(ret);
+}
+
+static int __devinit ssb_hcd_probe(struct ssb_device *dev,
+				   const struct ssb_device_id *id)
+{
+	int err, tmp;
+	int start, len;
+	u16 chipid_top;
+	u16 coreid = dev->id.coreid;
+	struct ssb_hcd_device *usb_dev;
+
+	/* USBcores are only connected on embedded devices. */
+	chipid_top = (dev->bus->chip_id & 0xFF00);
+	if (chipid_top != 0x4700 && chipid_top != 0x5300)
+		return -ENODEV;
+
+	/* TODO: Probably need checks here; is the core connected? */
+
+	if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
+	    dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
+		return -EOPNOTSUPP;
+
+	usb_dev = kzalloc(sizeof(struct ssb_hcd_device), GFP_KERNEL);
+	if (!usb_dev)
+		return -ENOMEM;
+
+	/* We currently always attach SSB_DEV_USB11_HOSTDEV
+	 * as HOST OHCI. If we want to attach it as Client device,
+	 * we must branch here and call into the (yet to
+	 * be written) Client mode driver. Same for remove(). */
+	usb_dev->enable_flags = ssb_hcd_init_chip(dev);
+
+	tmp = ssb_read32(dev, SSB_ADMATCH0);
+
+	start = ssb_admatch_base(tmp);
+	len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp);
+	usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len);
+	if (IS_ERR(usb_dev->ohci_dev)) {
+		err = PTR_ERR(usb_dev->ohci_dev);
+		goto err_free_usb_dev;
+	}
+
+	if (coreid == SSB_DEV_USB20_HOST) {
+		start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */
+		usb_dev->ehci_dev = ssb_hcd_create_pdev(dev, false, start, len);
+		if (IS_ERR(usb_dev->ehci_dev)) {
+			err = PTR_ERR(usb_dev->ehci_dev);
+			goto err_unregister_ohci_dev;
+		}
+	}
+
+	ssb_set_drvdata(dev, usb_dev);
+	return 0;
+
+err_unregister_ohci_dev:
+	platform_device_unregister(usb_dev->ohci_dev);
+err_free_usb_dev:
+	kfree(usb_dev);
+	return err;
+}
+
+static void __devexit ssb_hcd_remove(struct ssb_device *dev)
+{
+	struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
+	struct platform_device *ohci_dev = usb_dev->ohci_dev;
+	struct platform_device *ehci_dev = usb_dev->ehci_dev;
+
+	if (ohci_dev)
+		platform_device_unregister(ohci_dev);
+	if (ehci_dev)
+		platform_device_unregister(ehci_dev);
+
+	ssb_device_disable(dev, 0);
+}
+
+static void __devexit ssb_hcd_shutdown(struct ssb_device *dev)
+{
+	ssb_device_disable(dev, 0);
+}
+
+#ifdef CONFIG_PM
+
+static int ssb_hcd_suspend(struct ssb_device *dev, pm_message_t state)
+{
+	ssb_device_disable(dev, 0);
+
+	return 0;
+}
+
+static int ssb_hcd_resume(struct ssb_device *dev)
+{
+	struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
+
+	ssb_device_enable(dev, usb_dev->enable_flags);
+
+	return 0;
+}
+
+#else /* !CONFIG_PM */
+#define ssb_hcd_suspend	NULL
+#define ssb_hcd_resume	NULL
+#endif /* CONFIG_PM */
+
+static const struct ssb_device_id ssb_hcd_table[] __devinitconst = {
+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
+	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
+	SSB_DEVTABLE_END
+};
+MODULE_DEVICE_TABLE(ssb, ssb_hcd_table);
+
+static struct ssb_driver ssb_hcd_driver = {
+	.name		= KBUILD_MODNAME,
+	.id_table	= ssb_hcd_table,
+	.probe		= ssb_hcd_probe,
+	.remove		= __devexit_p(ssb_hcd_remove),
+	.shutdown	= ssb_hcd_shutdown,
+	.suspend	= ssb_hcd_suspend,
+	.resume		= ssb_hcd_resume,
+};
+
+static int __init ssb_hcd_init(void)
+{
+	return ssb_driver_register(&ssb_hcd_driver);
+}
+module_init(ssb_hcd_init);
+
+static void __exit ssb_hcd_exit(void)
+{
+	ssb_driver_unregister(&ssb_hcd_driver);
+}
+module_exit(ssb_hcd_exit);
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 673ad12..89850a8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -558,6 +558,7 @@
 				xhci_dbg(xhci, "Resume USB2 port %d\n",
 					wIndex + 1);
 				bus_state->resume_done[wIndex] = 0;
+				clear_bit(wIndex, &bus_state->resuming_ports);
 				xhci_set_link_state(xhci, port_array, wIndex,
 							XDEV_U0);
 				xhci_dbg(xhci, "set port %d resume\n",
@@ -845,7 +846,12 @@
 	/* Initial status is no changes */
 	retval = (max_ports + 8) / 8;
 	memset(buf, 0, retval);
-	status = 0;
+
+	/*
+	 * Inform the usbcore about resume-in-progress by returning
+	 * a non-zero value even if there are no status changes.
+	 */
+	status = bus_state->resuming_ports;
 
 	mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC;
 
@@ -885,15 +891,11 @@
 	spin_lock_irqsave(&xhci->lock, flags);
 
 	if (hcd->self.root_hub->do_remote_wakeup) {
-		port_index = max_ports;
-		while (port_index--) {
-			if (bus_state->resume_done[port_index] != 0) {
-				spin_unlock_irqrestore(&xhci->lock, flags);
-				xhci_dbg(xhci, "suspend failed because "
-						"port %d is resuming\n",
-						port_index + 1);
-				return -EBUSY;
-			}
+		if (bus_state->resuming_ports) {
+			spin_unlock_irqrestore(&xhci->lock, flags);
+			xhci_dbg(xhci, "suspend failed because "
+						"a port is resuming\n");
+			return -EBUSY;
 		}
 	}
 
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 3d9422f..329fd2a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1377,6 +1377,7 @@
 			xhci_dbg(xhci, "resume HS port %d\n", port_id);
 			bus_state->resume_done[faked_port_index] = jiffies +
 				msecs_to_jiffies(20);
+			set_bit(faked_port_index, &bus_state->resuming_ports);
 			mod_timer(&hcd->rh_timer,
 				  bus_state->resume_done[faked_port_index]);
 			/* Do the rest in GetPortStatus */
@@ -1803,6 +1804,7 @@
 		break;
 	case COMP_DEV_ERR:
 	case COMP_STALL:
+	case COMP_TX_ERR:
 		frame->status = -EPROTO;
 		skip_td = true;
 		break;
@@ -2270,7 +2272,7 @@
 					(status != 0 &&
 					 !usb_endpoint_xfer_isoc(&urb->ep->desc)))
 				xhci_dbg(xhci, "Giveback URB %p, len = %d, "
-						"expected = %x, status = %d\n",
+						"expected = %d, status = %d\n",
 						urb, urb->actual_length,
 						urb->transfer_buffer_length,
 						status);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 36641a7..16c05c6 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -152,7 +152,7 @@
 {
 	u32 command;
 	u32 state;
-	int ret;
+	int ret, i;
 
 	state = xhci_readl(xhci, &xhci->op_regs->status);
 	if ((state & STS_HALT) == 0) {
@@ -175,7 +175,15 @@
 	 * xHCI cannot write to any doorbells or operational registers other
 	 * than status until the "Controller Not Ready" flag is cleared.
 	 */
-	return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
+	ret = handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
+
+	for (i = 0; i < 2; ++i) {
+		xhci->bus_state[i].port_c_suspend = 0;
+		xhci->bus_state[i].suspended_ports = 0;
+		xhci->bus_state[i].resuming_ports = 0;
+	}
+
+	return ret;
 }
 
 #ifdef CONFIG_PCI
@@ -4090,7 +4098,6 @@
 	BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
 	/* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
 	BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8);
 	return 0;
 unreg_pci:
 	xhci_unregister_pci();
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 3d69c4b..ce1edd7 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1362,6 +1362,8 @@
 	u32			suspended_ports;
 	u32			port_remote_wakeup;
 	unsigned long		resume_done[USB_MAXCHILDREN];
+	/* which ports have started to resume */
+	unsigned long		resuming_ports;
 };
 
 static inline unsigned int hcd_index(struct usb_hcd *hcd)
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 575b56c..7121b50 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -284,18 +284,16 @@
 	int data_received=0, wake_up;
 	unsigned char* b=urb->transfer_buffer;
 	struct mdc800_data* mdc800=urb->context;
+	struct device *dev = &mdc800->dev->dev;
 	int status = urb->status;
 
 	if (status >= 0) {
-
-		//dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]);
-
 		if (mdc800_isBusy (b))
 		{
 			if (!mdc800->camera_busy)
 			{
 				mdc800->camera_busy=1;
-				dbg ("gets busy");
+				dev_dbg(dev, "gets busy\n");
 			}
 		}
 		else
@@ -303,13 +301,13 @@
 			if (mdc800->camera_busy && mdc800_isReady (b))
 			{
 				mdc800->camera_busy=0;
-				dbg ("gets ready");
+				dev_dbg(dev, "gets ready\n");
 			}
 		}
 		if (!(mdc800_isBusy (b) || mdc800_isReady (b)))
 		{
 			/* Store Data in camera_answer field */
-			dbg ("%i %i %i %i %i %i %i %i ",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]);
+			dev_dbg(dev, "%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]);
 
 			memcpy (mdc800->camera_response,b,8);
 			data_received=1;
@@ -441,7 +439,7 @@
 	int irq_interval=0;
 	int retval;
 
-	dbg ("(mdc800_usb_probe) called.");
+	dev_dbg(&intf->dev, "(%s) called.\n", __func__);
 
 
 	if (mdc800->dev != NULL)
@@ -554,7 +552,7 @@
 {
 	struct mdc800_data* mdc800 = usb_get_intfdata(intf);
 
-	dbg ("(mdc800_usb_disconnect) called");
+	dev_dbg(&intf->dev, "(%s) called\n", __func__);
 
 	if (mdc800) {
 		if (mdc800->state == NOT_CONNECTED)
@@ -656,7 +654,7 @@
 	}
 
 	mdc800->open=1;
-	dbg ("Mustek MDC800 device opened.");
+	dev_dbg(&mdc800->dev->dev, "Mustek MDC800 device opened.\n");
 
 error_out:
 	mutex_unlock(&mdc800->io_lock);
@@ -670,7 +668,6 @@
 static int mdc800_device_release (struct inode* inode, struct file *file)
 {
 	int retval=0;
-	dbg ("Mustek MDC800 device closed.");
 
 	mutex_lock(&mdc800->io_lock);
 	if (mdc800->open && (mdc800->state != NOT_CONNECTED))
@@ -927,7 +924,7 @@
 						{
 							mdc800->pic_len=(int) 65536*(unsigned char) mdc800->camera_response[0]+256*(unsigned char) mdc800->camera_response[1]+(unsigned char) mdc800->camera_response[2];
 
-							dbg ("cached imagesize = %i",mdc800->pic_len);
+							dev_dbg(&mdc800->dev->dev, "cached imagesize = %i\n", mdc800->pic_len);
 						}
 
 					}
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index ac0d75a..0fc6e5f 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -88,6 +88,7 @@
 static void appledisplay_complete(struct urb *urb)
 {
 	struct appledisplay *pdata = urb->context;
+	struct device *dev = &pdata->udev->dev;
 	unsigned long flags;
 	int status = urb->status;
 	int retval;
@@ -97,18 +98,18 @@
 		/* success */
 		break;
 	case -EOVERFLOW:
-		printk(KERN_ERR "appletouch: OVERFLOW with data "
-			"length %d, actual length is %d\n",
+		dev_err(dev,
+			"OVERFLOW with data length %d, actual length is %d\n",
 			ACD_URB_BUFFER_LEN, pdata->urb->actual_length);
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* This urb is terminated, clean up */
-		dbg("%s - urb shuttingdown with status: %d",
+		dev_dbg(dev, "%s - urb shuttingdown with status: %d\n",
 			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
+		dev_dbg(dev, "%s - nonzero urb status received: %d/n",
 			__func__, status);
 		goto exit;
 	}
@@ -132,8 +133,7 @@
 exit:
 	retval = usb_submit_urb(pdata->urb, GFP_ATOMIC);
 	if (retval) {
-		dev_err(&pdata->udev->dev,
-			"%s - usb_submit_urb failed with result %d\n",
+		dev_err(dev, "%s - usb_submit_urb failed with result %d\n",
 			__func__, retval);
 	}
 }
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index da97dce..d65984d 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -78,18 +78,14 @@
 	const struct firmware *bitstream_fw = NULL;
 	const struct firmware *firmware_fw = NULL;
 	const struct ihex_binrec *rec;
-	int err;
+	int err = -ENOMEM;
 	int i;
 	__u32 addr;	/* Address to write */
 	__u8 *buf;
 
 	buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
-	if (!buf) {
-		dev_err(&dev->dev, "%s - error loading firmware: error = %d\n",
-			__func__, -ENOMEM);
-		err = -ENOMEM;
+	if (!buf)
 		goto wraperr;
-	}
 
 	err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev);
 	if (err)
@@ -111,11 +107,8 @@
 
 	/* Assert reset (stop the CPU in the EMI) */
 	err = emi26_set_reset(dev,1);
-	if (err < 0) {
-		dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
-			__func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	rec = (const struct ihex_binrec *)loader_fw->data;
 	/* 1. We need to put the loader for the FPGA into the EZ-USB */
@@ -123,19 +116,15 @@
 		err = emi26_writememory(dev, be32_to_cpu(rec->addr),
 					rec->data, be16_to_cpu(rec->len),
 					ANCHOR_LOAD_INTERNAL);
-		if (err < 0) {
-			err("%s - error loading firmware: error = %d", __func__, err);
+		if (err < 0)
 			goto wraperr;
-		}
 		rec = ihex_next_binrec(rec);
 	}
 
 	/* De-assert reset (let the CPU run) */
 	err = emi26_set_reset(dev,0);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 	msleep(250);	/* let device settle */
 
 	/* 2. We upload the FPGA firmware into the EMI
@@ -153,18 +142,14 @@
 			rec = ihex_next_binrec(rec);
 		}
 		err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
-		if (err < 0) {
-			err("%s - error loading firmware: error = %d", __func__, err);
+		if (err < 0)
 			goto wraperr;
-		}
 	} while (rec);
 
 	/* Assert reset (stop the CPU in the EMI) */
 	err = emi26_set_reset(dev,1);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
 	for (rec = (const struct ihex_binrec *)loader_fw->data;
@@ -172,19 +157,15 @@
 		err = emi26_writememory(dev, be32_to_cpu(rec->addr),
 					rec->data, be16_to_cpu(rec->len),
 					ANCHOR_LOAD_INTERNAL);
-		if (err < 0) {
-			err("%s - error loading firmware: error = %d", __func__, err);
+		if (err < 0)
 			goto wraperr;
-		}
 	}
 	msleep(250);	/* let device settle */
 
 	/* De-assert reset (let the CPU run) */
 	err = emi26_set_reset(dev,0);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
 
@@ -194,19 +175,15 @@
 			err = emi26_writememory(dev, be32_to_cpu(rec->addr),
 						rec->data, be16_to_cpu(rec->len),
 						ANCHOR_LOAD_EXTERNAL);
-			if (err < 0) {
-				err("%s - error loading firmware: error = %d", __func__, err);
+			if (err < 0)
 				goto wraperr;
-			}
 		}
 	}
-	
+
 	/* Assert reset (stop the CPU in the EMI) */
 	err = emi26_set_reset(dev,1);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	for (rec = (const struct ihex_binrec *)firmware_fw->data;
 	     rec; rec = ihex_next_binrec(rec)) {
@@ -214,19 +191,15 @@
 			err = emi26_writememory(dev, be32_to_cpu(rec->addr),
 						rec->data, be16_to_cpu(rec->len),
 						ANCHOR_LOAD_INTERNAL);
-			if (err < 0) {
-				err("%s - error loading firmware: error = %d", __func__, err);
+			if (err < 0)
 				goto wraperr;
-			}
 		}
 	}
 
 	/* De-assert reset (let the CPU run) */
 	err = emi26_set_reset(dev,0);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 	msleep(250);	/* let device settle */
 
 	/* return 1 to fail the driver inialization
@@ -234,6 +207,10 @@
 	err = 1;
 
 wraperr:
+	if (err < 0)
+		dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
+			__func__, err);
+
 	release_firmware(loader_fw);
 	release_firmware(bitstream_fw);
 	release_firmware(firmware_fw);
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 4e0f167..ff08015 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -56,7 +56,7 @@
 	unsigned char *buffer =  kmemdup(data, length, GFP_KERNEL);
 
 	if (!buffer) {
-		err("emi62: kmalloc(%d) failed.", length);
+		dev_err(&dev->dev, "kmalloc(%d) failed.\n", length);
 		return -ENOMEM;
 	}
 	/* Note: usb_control_msg returns negative value on error or length of the
@@ -73,9 +73,8 @@
 	dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit);
 	
 	response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
-	if (response < 0) {
-		err("emi62: set_reset (%d) failed", reset_bit);
-	}
+	if (response < 0)
+		dev_err(&dev->dev, "set_reset (%d) failed\n", reset_bit);
 	return response;
 }
 
@@ -87,18 +86,15 @@
 	const struct firmware *bitstream_fw = NULL;
 	const struct firmware *firmware_fw = NULL;
 	const struct ihex_binrec *rec;
-	int err;
+	int err = -ENOMEM;
 	int i;
 	__u32 addr;	/* Address to write */
 	__u8 *buf;
 
 	dev_dbg(&dev->dev, "load_firmware\n");
 	buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
-	if (!buf) {
-		err( "%s - error loading firmware: error = %d", __func__, -ENOMEM);
-		err = -ENOMEM;
+	if (!buf)
 		goto wraperr;
-	}
 
 	err = request_ihex_firmware(&loader_fw, "emi62/loader.fw", &dev->dev);
 	if (err)
@@ -112,16 +108,13 @@
 	err = request_ihex_firmware(&firmware_fw, FIRMWARE_FW, &dev->dev);
 	if (err) {
 	nofw:
-		err( "%s - request_firmware() failed", __func__);
 		goto wraperr;
 	}
 
 	/* Assert reset (stop the CPU in the EMI) */
 	err = emi62_set_reset(dev,1);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	rec = (const struct ihex_binrec *)loader_fw->data;
 
@@ -130,19 +123,15 @@
 		err = emi62_writememory(dev, be32_to_cpu(rec->addr),
 					rec->data, be16_to_cpu(rec->len),
 					ANCHOR_LOAD_INTERNAL);
-		if (err < 0) {
-			err("%s - error loading firmware: error = %d", __func__, err);
+		if (err < 0)
 			goto wraperr;
-		}
 		rec = ihex_next_binrec(rec);
 	}
 
 	/* De-assert reset (let the CPU run) */
 	err = emi62_set_reset(dev,0);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 	msleep(250);	/* let device settle */
 
 	/* 2. We upload the FPGA firmware into the EMI
@@ -160,18 +149,14 @@
 			rec = ihex_next_binrec(rec);
 		}
 		err = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
-		if (err < 0) {
-			err("%s - error loading firmware: error = %d", __func__, err);
+		if (err < 0)
 			goto wraperr;
-		}
 	} while (rec);
 
 	/* Assert reset (stop the CPU in the EMI) */
 	err = emi62_set_reset(dev,1);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	/* 3. We need to put the loader for the firmware into the EZ-USB (again...) */
 	for (rec = (const struct ihex_binrec *)loader_fw->data;
@@ -179,18 +164,14 @@
 		err = emi62_writememory(dev, be32_to_cpu(rec->addr),
 					rec->data, be16_to_cpu(rec->len),
 					ANCHOR_LOAD_INTERNAL);
-		if (err < 0) {
-			err("%s - error loading firmware: error = %d", __func__, err);
+		if (err < 0)
 			goto wraperr;
-		}
 	}
 
 	/* De-assert reset (let the CPU run) */
 	err = emi62_set_reset(dev,0);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 	msleep(250);	/* let device settle */
 
 	/* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */
@@ -201,19 +182,15 @@
 			err = emi62_writememory(dev, be32_to_cpu(rec->addr),
 						rec->data, be16_to_cpu(rec->len),
 						ANCHOR_LOAD_EXTERNAL);
-			if (err < 0) {
-				err("%s - error loading firmware: error = %d", __func__, err);
+			if (err < 0)
 				goto wraperr;
-			}
 		}
 	}
 
 	/* Assert reset (stop the CPU in the EMI) */
 	err = emi62_set_reset(dev,1);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 
 	for (rec = (const struct ihex_binrec *)firmware_fw->data;
 	     rec; rec = ihex_next_binrec(rec)) {
@@ -221,19 +198,15 @@
 			err = emi62_writememory(dev, be32_to_cpu(rec->addr),
 						rec->data, be16_to_cpu(rec->len),
 						ANCHOR_LOAD_EXTERNAL);
-			if (err < 0) {
-				err("%s - error loading firmware: error = %d", __func__, err);
+			if (err < 0)
 				goto wraperr;
-			}
 		}
 	}
 
 	/* De-assert reset (let the CPU run) */
 	err = emi62_set_reset(dev,0);
-	if (err < 0) {
-		err("%s - error loading firmware: error = %d", __func__, err);
+	if (err < 0)
 		goto wraperr;
-	}
 	msleep(250);	/* let device settle */
 
 	release_firmware(loader_fw);
@@ -247,6 +220,9 @@
 	return 1;
 
 wraperr:
+	if (err < 0)
+		dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
+			__func__, err);
 	release_firmware(loader_fw);
 	release_firmware(bitstream_fw);
 	release_firmware(firmware_fw);
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 0dee246..ce97838 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -200,7 +200,8 @@
 			return -EAGAIN;
 
 	/* should be IMGSIZE == 65040 */
-	dbg("read %d bytes fingerprint data", bytes_read);
+	dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n",
+		bytes_read);
 	return result;
 }
 
@@ -366,14 +367,14 @@
 			kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
 
 		if (!dev->bulk_in_buffer) {
-			err("Unable to allocate input buffer.");
+			dev_err(&interface->dev, "Unable to allocate input buffer.\n");
 			idmouse_delete(dev);
 			return -ENOMEM;
 		}
 	}
 
 	if (!(dev->bulk_in_endpointAddr)) {
-		err("Unable to find bulk-in endpoint.");
+		dev_err(&interface->dev, "Unable to find bulk-in endpoint.\n");
 		idmouse_delete(dev);
 		return -ENODEV;
 	}
@@ -385,7 +386,7 @@
 	result = usb_register_dev(interface, &idmouse_class);
 	if (result) {
 		/* something prevented us from registering this device */
-		err("Unble to allocate minor number.");
+		dev_err(&interface->dev, "Unble to allocate minor number.\n");
 		usb_set_intfdata(interface, NULL);
 		idmouse_delete(dev);
 		return result;
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 4fd0dc8..db46143 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -610,8 +610,8 @@
 	interface = usb_find_interface(&iowarrior_driver, subminor);
 	if (!interface) {
 		mutex_unlock(&iowarrior_mutex);
-		err("%s - error, can't find device for minor %d", __func__,
-		    subminor);
+		printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+		       __func__, subminor);
 		return -ENODEV;
 	}
 
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 5db4ab5..ac76229 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -334,8 +334,8 @@
 	interface = usb_find_interface(&ld_usb_driver, subminor);
 
 	if (!interface) {
-		err("%s - error, can't find device for minor %d\n",
-		     __func__, subminor);
+		printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+		       __func__, subminor);
 		return -ENODEV;
 	}
 
@@ -485,7 +485,7 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->intf == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d\n", retval);
+		printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
 		goto unlock_exit;
 	}
 
@@ -565,7 +565,7 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->intf == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d\n", retval);
+		printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval);
 		goto unlock_exit;
 	}
 
@@ -603,7 +603,9 @@
 					 bytes_to_write,
 					 USB_CTRL_SET_TIMEOUT * HZ);
 		if (retval < 0)
-			err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval);
+			dev_err(&dev->intf->dev,
+				"Couldn't submit HID_REQ_SET_REPORT %d\n",
+				retval);
 		goto unlock_exit;
 	}
 
@@ -624,7 +626,8 @@
 	retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
 	if (retval) {
 		dev->interrupt_out_busy = 0;
-		err("Couldn't submit interrupt_out_urb %d\n", retval);
+		dev_err(&dev->intf->dev,
+			"Couldn't submit interrupt_out_urb %d\n", retval);
 		goto unlock_exit;
 	}
 	retval = bytes_to_write;
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 5752220..a2702cb 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -354,8 +354,8 @@
 	interface = usb_find_interface (&tower_driver, subminor);
 
 	if (!interface) {
-		err ("%s - error, can't find device for minor %d",
-		     __func__, subminor);
+		printk(KERN_ERR "%s - error, can't find device for minor %d\n",
+		       __func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
@@ -397,7 +397,8 @@
 				  sizeof(reset_reply),
 				  1000);
 	if (result < 0) {
-		err("LEGO USB Tower reset control request failed");
+		dev_err(&dev->udev->dev,
+			"LEGO USB Tower reset control request failed\n");
 		retval = result;
 		goto unlock_exit;
 	}
@@ -420,7 +421,8 @@
 
 	retval = usb_submit_urb (dev->interrupt_in_urb, GFP_KERNEL);
 	if (retval) {
-		err("Couldn't submit interrupt_in_urb %d", retval);
+		dev_err(&dev->udev->dev,
+			"Couldn't submit interrupt_in_urb %d\n", retval);
 		dev->interrupt_in_running = 0;
 		dev->open_count = 0;
 		goto unlock_exit;
@@ -608,7 +610,7 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->udev == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d", retval);
+		printk(KERN_ERR "legousbtower: No device or device unplugged %d\n", retval);
 		goto unlock_exit;
 	}
 
@@ -697,7 +699,7 @@
 	/* verify that the device wasn't unplugged */
 	if (dev->udev == NULL) {
 		retval = -ENODEV;
-		err("No device or device unplugged %d", retval);
+		printk(KERN_ERR "legousbtower: No device or device unplugged %d\n", retval);
 		goto unlock_exit;
 	}
 
@@ -744,7 +746,8 @@
 	retval = usb_submit_urb (dev->interrupt_out_urb, GFP_KERNEL);
 	if (retval) {
 		dev->interrupt_out_busy = 0;
-		err("Couldn't submit interrupt_out_urb %d", retval);
+		dev_err(&dev->udev->dev,
+			"Couldn't submit interrupt_out_urb %d\n", retval);
 		goto unlock_exit;
 	}
 	retval = bytes_to_write;
@@ -803,9 +806,10 @@
 	/* resubmit if we're still running */
 	if (dev->interrupt_in_running && dev->udev) {
 		retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC);
-		if (retval) {
-			err("%s: usb_submit_urb failed (%d)", __func__, retval);
-		}
+		if (retval)
+			dev_err(&dev->udev->dev,
+				"%s: usb_submit_urb failed (%d)\n",
+				__func__, retval);
 	}
 
 exit:
@@ -852,6 +856,7 @@
  */
 static int tower_probe (struct usb_interface *interface, const struct usb_device_id *id)
 {
+	struct device *idev = &interface->dev;
 	struct usb_device *udev = interface_to_usbdev(interface);
 	struct lego_usb_tower *dev = NULL;
 	struct usb_host_interface *iface_desc;
@@ -871,7 +876,7 @@
 	dev = kmalloc (sizeof(struct lego_usb_tower), GFP_KERNEL);
 
 	if (dev == NULL) {
-		err ("Out of memory");
+		dev_err(idev, "Out of memory\n");
 		goto exit;
 	}
 
@@ -915,37 +920,37 @@
 		}
 	}
 	if(dev->interrupt_in_endpoint == NULL) {
-		err("interrupt in endpoint not found");
+		dev_err(idev, "interrupt in endpoint not found\n");
 		goto error;
 	}
 	if (dev->interrupt_out_endpoint == NULL) {
-		err("interrupt out endpoint not found");
+		dev_err(idev, "interrupt out endpoint not found\n");
 		goto error;
 	}
 
 	dev->read_buffer = kmalloc (read_buffer_size, GFP_KERNEL);
 	if (!dev->read_buffer) {
-		err("Couldn't allocate read_buffer");
+		dev_err(idev, "Couldn't allocate read_buffer\n");
 		goto error;
 	}
 	dev->interrupt_in_buffer = kmalloc (usb_endpoint_maxp(dev->interrupt_in_endpoint), GFP_KERNEL);
 	if (!dev->interrupt_in_buffer) {
-		err("Couldn't allocate interrupt_in_buffer");
+		dev_err(idev, "Couldn't allocate interrupt_in_buffer\n");
 		goto error;
 	}
 	dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->interrupt_in_urb) {
-		err("Couldn't allocate interrupt_in_urb");
+		dev_err(idev, "Couldn't allocate interrupt_in_urb\n");
 		goto error;
 	}
 	dev->interrupt_out_buffer = kmalloc (write_buffer_size, GFP_KERNEL);
 	if (!dev->interrupt_out_buffer) {
-		err("Couldn't allocate interrupt_out_buffer");
+		dev_err(idev, "Couldn't allocate interrupt_out_buffer\n");
 		goto error;
 	}
 	dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->interrupt_out_urb) {
-		err("Couldn't allocate interrupt_out_urb");
+		dev_err(idev, "Couldn't allocate interrupt_out_urb\n");
 		goto error;
 	}
 	dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
@@ -958,7 +963,7 @@
 
 	if (retval) {
 		/* something prevented us from registering this driver */
-		err ("Not able to get a minor for this device.");
+		dev_err(idev, "Not able to get a minor for this device.\n");
 		usb_set_intfdata (interface, NULL);
 		goto error;
 	}
@@ -980,7 +985,7 @@
 				  sizeof(get_version_reply),
 				  1000);
 	if (result < 0) {
-		err("LEGO USB Tower get version control request failed");
+		dev_err(idev, "LEGO USB Tower get version control request failed\n");
 		retval = result;
 		goto error;
 	}
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 487a8ce..1084124 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -153,10 +153,10 @@
 
 		requesttype = rio_cmd.requesttype | USB_DIR_IN |
 		    USB_TYPE_VENDOR | USB_RECIP_DEVICE;
-		dbg
-		    ("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
-		     requesttype, rio_cmd.request, rio_cmd.value,
-		     rio_cmd.index, rio_cmd.length);
+		dev_dbg(&rio->rio_dev->dev,
+			"sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
+			requesttype, rio_cmd.request, rio_cmd.value,
+			rio_cmd.index, rio_cmd.length);
 		/* Send rio control message */
 		retries = 3;
 		while (retries) {
@@ -171,11 +171,14 @@
 			if (result == -ETIMEDOUT)
 				retries--;
 			else if (result < 0) {
-				err("Error executing ioctrl. code = %d", result);
+				dev_err(&rio->rio_dev->dev,
+					"Error executing ioctrl. code = %d\n",
+					result);
 				retries = 0;
 			} else {
-				dbg("Executed ioctl. Result = %d (data=%02x)",
-				     result, buffer[0]);
+				dev_dbg(&rio->rio_dev->dev,
+					"Executed ioctl. Result = %d (data=%02x)\n",
+					result, buffer[0]);
 				if (copy_to_user(rio_cmd.buffer, buffer,
 						 rio_cmd.length)) {
 					free_page((unsigned long) buffer);
@@ -221,9 +224,10 @@
 
 		requesttype = rio_cmd.requesttype | USB_DIR_OUT |
 		    USB_TYPE_VENDOR | USB_RECIP_DEVICE;
-		dbg("sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x",
-		     requesttype, rio_cmd.request, rio_cmd.value,
-		     rio_cmd.index, rio_cmd.length);
+		dev_dbg(&rio->rio_dev->dev,
+			"sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
+			requesttype, rio_cmd.request, rio_cmd.value,
+			rio_cmd.index, rio_cmd.length);
 		/* Send rio control message */
 		retries = 3;
 		while (retries) {
@@ -238,10 +242,13 @@
 			if (result == -ETIMEDOUT)
 				retries--;
 			else if (result < 0) {
-				err("Error executing ioctrl. code = %d", result);
+				dev_err(&rio->rio_dev->dev,
+					"Error executing ioctrl. code = %d\n",
+					result);
 				retries = 0;
 			} else {
-				dbg("Executed ioctl. Result = %d", result);
+				dev_dbg(&rio->rio_dev->dev,
+					"Executed ioctl. Result = %d\n", result);
 				retries = 0;
 
 			}
@@ -313,8 +320,9 @@
 					 usb_sndbulkpipe(rio->rio_dev, 2),
 					 obuf, thistime, &partial, 5000);
 
-			dbg("write stats: result:%d thistime:%lu partial:%u",
-			     result, thistime, partial);
+			dev_dbg(&rio->rio_dev->dev,
+				"write stats: result:%d thistime:%lu partial:%u\n",
+				result, thistime, partial);
 
 			if (result == -ETIMEDOUT) {	/* NAK - so hold for a while */
 				if (!maxretry--) {
@@ -332,7 +340,8 @@
 				break;
 		};
 		if (result) {
-			err("Write Whoops - %x", result);
+			dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n",
+				result);
 			errn = -EIO;
 			goto error;
 		}
@@ -393,15 +402,17 @@
 				      ibuf, this_read, &partial,
 				      8000);
 
-		dbg("read stats: result:%d this_read:%u partial:%u",
-		       result, this_read, partial);
+		dev_dbg(&rio->rio_dev->dev,
+			"read stats: result:%d this_read:%u partial:%u\n",
+			result, this_read, partial);
 
 		if (partial) {
 			count = this_read = partial;
 		} else if (result == -ETIMEDOUT || result == 15) {	/* FIXME: 15 ??? */
 			if (!maxretry--) {
 				mutex_unlock(&(rio->lock));
-				err("read_rio: maxretry timeout");
+				dev_err(&rio->rio_dev->dev,
+					"read_rio: maxretry timeout\n");
 				return -ETIME;
 			}
 			prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
@@ -410,8 +421,9 @@
 			continue;
 		} else if (result != -EREMOTEIO) {
 			mutex_unlock(&(rio->lock));
-			err("Read Whoops - result:%u partial:%u this_read:%u",
-			     result, partial, this_read);
+			dev_err(&rio->rio_dev->dev,
+				"Read Whoops - result:%u partial:%u this_read:%u\n",
+				result, partial, this_read);
 			return -EIO;
 		} else {
 			mutex_unlock(&(rio->lock));
@@ -459,26 +471,29 @@
 
 	retval = usb_register_dev(intf, &usb_rio_class);
 	if (retval) {
-		err("Not able to get a minor for this device.");
+		dev_err(&dev->dev,
+			"Not able to get a minor for this device.\n");
 		return -ENOMEM;
 	}
 
 	rio->rio_dev = dev;
 
 	if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
-		err("probe_rio: Not enough memory for the output buffer");
+		dev_err(&dev->dev,
+			"probe_rio: Not enough memory for the output buffer\n");
 		usb_deregister_dev(intf, &usb_rio_class);
 		return -ENOMEM;
 	}
-	dbg("probe_rio: obuf address:%p", rio->obuf);
+	dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf);
 
 	if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
-		err("probe_rio: Not enough memory for the input buffer");
+		dev_err(&dev->dev,
+			"probe_rio: Not enough memory for the input buffer\n");
 		usb_deregister_dev(intf, &usb_rio_class);
 		kfree(rio->obuf);
 		return -ENOMEM;
 	}
-	dbg("probe_rio: ibuf address:%p", rio->ibuf);
+	dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
 
 	mutex_init(&(rio->lock));
 
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index e2b4bd3..89927bc 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -87,8 +87,8 @@
 	interface = usb_find_interface(&lcd_driver, subminor);
 	if (!interface) {
 		mutex_unlock(&lcd_mutex);
-		err("USBLCD: %s - error, can't find device for minor %d",
-		     __func__, subminor);
+		printk(KERN_ERR "USBLCD: %s - error, can't find device for minor %d\n",
+		       __func__, subminor);
 		return -ENODEV;
 	}
 
@@ -209,8 +209,8 @@
 	    !(status == -ENOENT ||
 	      status == -ECONNRESET ||
 	      status == -ESHUTDOWN)) {
-		dbg("USBLCD: %s - nonzero write bulk status received: %d",
-		    __func__, status);
+		dev_dbg(&dev->interface->dev,
+			"nonzero write bulk status received: %d\n", status);
 	}
 
 	/* free up our allocated buffer */
@@ -268,8 +268,9 @@
 	/* send the data out the bulk port */
 	retval = usb_submit_urb(urb, GFP_KERNEL);
 	if (retval) {
-		err("USBLCD: %s - failed submitting write urb, error %d",
-		    __func__, retval);
+		dev_err(&dev->udev->dev,
+			"%s - failed submitting write urb, error %d\n",
+			__func__, retval);
 		goto error_unanchor;
 	}
 
@@ -322,7 +323,7 @@
 	/* allocate memory for our device state and initialize it */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
-		err("Out of memory");
+		dev_err(&interface->dev, "Out of memory\n");
 		goto error;
 	}
 	kref_init(&dev->kref);
@@ -352,7 +353,8 @@
 			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
 			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
 			if (!dev->bulk_in_buffer) {
-				err("Could not allocate bulk_in_buffer");
+				dev_err(&interface->dev,
+					"Could not allocate bulk_in_buffer\n");
 				goto error;
 			}
 		}
@@ -364,7 +366,8 @@
 		}
 	}
 	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
-		err("Could not find both bulk-in and bulk-out endpoints");
+		dev_err(&interface->dev,
+			"Could not find both bulk-in and bulk-out endpoints\n");
 		goto error;
 	}
 
@@ -375,7 +378,8 @@
 	retval = usb_register_dev(interface, &lcd_class);
 	if (retval) {
 		/* something prevented us from registering this driver */
-		err("Not able to get a minor for this device.");
+		dev_err(&interface->dev,
+			"Not able to get a minor for this device.\n");
 		usb_set_intfdata(interface, NULL);
 		goto error;
 	}
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 9dcb68f..055b84a 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -1028,7 +1028,10 @@
 		case 13:	/* short read, resembling case 10 */
 			req.wValue = cpu_to_le16((USB_DT_CONFIG << 8) | 0);
 			/* last data packet "should" be DATA1, not DATA0 */
-			len = 1024 - udev->descriptor.bMaxPacketSize0;
+			if (udev->speed == USB_SPEED_SUPER)
+				len = 1024 - 512;
+			else
+				len = 1024 - udev->descriptor.bMaxPacketSize0;
 			expected = -EREMOTEIO;
 			break;
 		case 14:	/* short read; try to fill the last packet */
@@ -1387,11 +1390,15 @@
 
 static int halt_simple(struct usbtest_dev *dev)
 {
-	int		ep;
-	int		retval = 0;
-	struct urb	*urb;
+	int			ep;
+	int			retval = 0;
+	struct urb		*urb;
+	struct usb_device	*udev = testdev_to_usbdev(dev);
 
-	urb = simple_alloc_urb(testdev_to_usbdev(dev), 0, 512);
+	if (udev->speed == USB_SPEED_SUPER)
+		urb = simple_alloc_urb(udev, 0, 1024);
+	else
+		urb = simple_alloc_urb(udev, 0, 512);
 	if (urb == NULL)
 		return -ENOMEM;
 
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 8b1d94a..29cad9e 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -85,9 +85,9 @@
 {
 	struct parport_uss720_private *priv = container_of(kref, struct parport_uss720_private, ref_count);
 
+	dev_dbg(&priv->usbdev->dev, "destroying priv datastructure\n");
 	usb_put_dev(priv->usbdev);
 	kfree(priv);
-	dbg("destroying priv datastructure");
 }
 
 static void destroy_async(struct kref *kref)
@@ -118,14 +118,17 @@
 	priv = rq->priv;
 	pp = priv->pp;
 	if (status) {
-		err("async_complete: urb error %d", status);
+		dev_err(&urb->dev->dev, "async_complete: urb error %d\n",
+			status);
 	} else if (rq->dr.bRequest == 3) {
 		memcpy(priv->reg, rq->reg, sizeof(priv->reg));
 #if 0
-		dbg("async_complete regs %02x %02x %02x %02x %02x %02x %02x",
-		    (unsigned int)priv->reg[0], (unsigned int)priv->reg[1], (unsigned int)priv->reg[2],
-		    (unsigned int)priv->reg[3], (unsigned int)priv->reg[4], (unsigned int)priv->reg[5],
-		    (unsigned int)priv->reg[6]);
+		dev_dbg(&priv->usbdev->dev,
+			"async_complete regs %02x %02x %02x %02x %02x %02x %02x\n",
+			(unsigned int)priv->reg[0], (unsigned int)priv->reg[1],
+			(unsigned int)priv->reg[2], (unsigned int)priv->reg[3],
+			(unsigned int)priv->reg[4], (unsigned int)priv->reg[5],
+			(unsigned int)priv->reg[6]);
 #endif
 		/* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
 		if (rq->reg[2] & rq->reg[1] & 0x10 && pp)
@@ -151,7 +154,7 @@
 		return NULL;
 	rq = kmalloc(sizeof(struct uss720_async_request), mem_flags);
 	if (!rq) {
-		err("submit_async_request out of memory");
+		dev_err(&usbdev->dev, "submit_async_request out of memory\n");
 		return NULL;
 	}
 	kref_init(&rq->ref_count);
@@ -162,7 +165,7 @@
 	rq->urb = usb_alloc_urb(0, mem_flags);
 	if (!rq->urb) {
 		kref_put(&rq->ref_count, destroy_async);
-		err("submit_async_request out of memory");
+		dev_err(&usbdev->dev, "submit_async_request out of memory\n");
 		return NULL;
 	}
 	rq->dr.bRequestType = requesttype;
@@ -182,7 +185,7 @@
 	if (!ret)
 		return rq;
 	destroy_async(&rq->ref_count);
-	err("submit_async_request submit_urb failed with %d", ret);
+	dev_err(&usbdev->dev, "submit_async_request submit_urb failed with %d\n", ret);
 	return NULL;
 }
 
@@ -217,7 +220,8 @@
 	priv = pp->private_data;
 	rq = submit_async_request(priv, 3, 0xc0, ((unsigned int)reg) << 8, 0, mem_flags);
 	if (!rq) {
-		err("get_1284_register(%u) failed", (unsigned int)reg);
+		dev_err(&priv->usbdev->dev, "get_1284_register(%u) failed",
+			(unsigned int)reg);
 		return -EIO;
 	}
 	if (!val) {
@@ -248,7 +252,8 @@
 	priv = pp->private_data;
 	rq = submit_async_request(priv, 4, 0x40, (((unsigned int)reg) << 8) | val, 0, mem_flags);
 	if (!rq) {
-		err("set_1284_register(%u,%u) failed", (unsigned int)reg, (unsigned int)val);
+		dev_err(&priv->usbdev->dev, "set_1284_register(%u,%u) failed",
+			(unsigned int)reg, (unsigned int)val);
 		return -EIO;
 	}
 	kref_put(&rq->ref_count, destroy_async);
@@ -690,9 +695,9 @@
 	unsigned char reg;
 	int i;
 
-	dbg("probe: vendor id 0x%x, device id 0x%x\n",
-	    le16_to_cpu(usbdev->descriptor.idVendor),
-	    le16_to_cpu(usbdev->descriptor.idProduct));
+	dev_dbg(&intf->dev, "probe: vendor id 0x%x, device id 0x%x\n",
+		le16_to_cpu(usbdev->descriptor.idVendor),
+		le16_to_cpu(usbdev->descriptor.idProduct));
 
 	/* our known interfaces have 3 alternate settings */
 	if (intf->num_altsetting != 3) {
@@ -700,7 +705,7 @@
 		return -ENODEV;
 	}
 	i = usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 2);
-	dbg("set inteface result %d", i);
+	dev_dbg(&intf->dev, "set inteface result %d\n", i);
 
 	interface = intf->cur_altsetting;
 
@@ -731,11 +736,13 @@
 	set_1284_register(pp, 2, 0x0c, GFP_KERNEL);
 	/* debugging */
 	get_1284_register(pp, 0, &reg, GFP_KERNEL);
-	dbg("reg: %02x %02x %02x %02x %02x %02x %02x",
-	    priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3], priv->reg[4], priv->reg[5], priv->reg[6]);
+	dev_dbg(&intf->dev, "reg: %02x %02x %02x %02x %02x %02x %02x\n",
+		priv->reg[0], priv->reg[1], priv->reg[2], priv->reg[3],
+		priv->reg[4], priv->reg[5], priv->reg[6]);
 
 	endpoint = &interface->endpoint[2];
-	dbg("epaddr %d interval %d", endpoint->desc.bEndpointAddress, endpoint->desc.bInterval);
+	dev_dbg(&intf->dev, "epaddr %d interval %d\n",
+		endpoint->desc.bEndpointAddress, endpoint->desc.bInterval);
 	parport_announce_port(pp);
 
 	usb_set_intfdata(intf, pp);
@@ -753,20 +760,20 @@
 	struct parport_uss720_private *priv;
 	struct usb_device *usbdev;
 
-	dbg("disconnect");
+	dev_dbg(&intf->dev, "disconnect\n");
 	usb_set_intfdata(intf, NULL);
 	if (pp) {
 		priv = pp->private_data;
 		usbdev = priv->usbdev;
 		priv->usbdev = NULL;
 		priv->pp = NULL;
-		dbg("parport_remove_port");
+		dev_dbg(&intf->dev, "parport_remove_port\n");
 		parport_remove_port(pp);
 		parport_put_port(pp);
 		kill_all_async_requests_priv(priv);
 		kref_put(&priv->ref_count, destroy_priv);
 	}
-	dbg("disconnect done");
+	dev_dbg(&intf->dev, "disconnect done\n");
 }
 
 /* table of cables that work through this driver */
diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 7020146..42ad2e6 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -83,7 +83,8 @@
 	int status = urb->status;
 
 	if (status) {
-		err("%s - control failed: %d\n", __func__, status);
+		dev_err(&urb->dev->dev, "%s - control failed: %d\n",
+			__func__, status);
 		wake_up_interruptible(&dev->waitq);
 		return;
 	}
@@ -94,7 +95,7 @@
 {
 	struct usb_yurex *dev = to_yurex_dev(kref);
 
-	dbg("yurex_delete");
+	dev_dbg(&dev->interface->dev, "%s\n", __func__);
 
 	usb_put_dev(dev->udev);
 	if (dev->cntl_urb) {
@@ -137,8 +138,9 @@
 	case 0: /*success*/
 		break;
 	case -EOVERFLOW:
-		err("%s - overflow with length %d, actual length is %d",
-		    __func__, YUREX_BUF_SIZE, dev->urb->actual_length);
+		dev_err(&dev->interface->dev,
+			"%s - overflow with length %d, actual length is %d\n",
+			__func__, YUREX_BUF_SIZE, dev->urb->actual_length);
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
@@ -146,7 +148,8 @@
 		/* The device is terminated, clean up */
 		return;
 	default:
-		err("%s - unknown status received: %d", __func__, status);
+		dev_err(&dev->interface->dev,
+			"%s - unknown status received: %d\n", __func__, status);
 		goto exit;
 	}
 
@@ -162,16 +165,19 @@
 				if (i != 5)
 					dev->bbu <<= 8;
 			}
-			dbg("%s count: %lld", __func__, dev->bbu);
+			dev_dbg(&dev->interface->dev, "%s count: %lld\n",
+				__func__, dev->bbu);
 			spin_unlock_irqrestore(&dev->lock, flags);
 
 			kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
 		}
 		else
-			dbg("data format error - no EOF");
+			dev_dbg(&dev->interface->dev,
+				"data format error - no EOF\n");
 		break;
 	case CMD_ACK:
-		dbg("%s ack: %c", __func__, buf[1]);
+		dev_dbg(&dev->interface->dev, "%s ack: %c\n",
+			__func__, buf[1]);
 		wake_up_interruptible(&dev->waitq);
 		break;
 	}
@@ -179,7 +185,7 @@
 exit:
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
 	if (retval) {
-		err("%s - usb_submit_urb failed: %d",
+		dev_err(&dev->interface->dev, "%s - usb_submit_urb failed: %d\n",
 			__func__, retval);
 	}
 }
@@ -196,7 +202,7 @@
 	/* allocate memory for our device state and initialize it */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		err("Out of memory");
+		dev_err(&interface->dev, "Out of memory\n");
 		goto error;
 	}
 	kref_init(&dev->kref);
@@ -219,7 +225,7 @@
 	}
 	if (!dev->int_in_endpointAddr) {
 		retval = -ENODEV;
-		err("Could not find endpoints");
+		dev_err(&interface->dev, "Could not find endpoints\n");
 		goto error;
 	}
 
@@ -227,14 +233,14 @@
 	/* allocate control URB */
 	dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->cntl_urb) {
-		err("Could not allocate control URB");
+		dev_err(&interface->dev, "Could not allocate control URB\n");
 		goto error;
 	}
 
 	/* allocate buffer for control req */
 	dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
 	if (!dev->cntl_req) {
-		err("Could not allocate cntl_req");
+		dev_err(&interface->dev, "Could not allocate cntl_req\n");
 		goto error;
 	}
 
@@ -243,7 +249,7 @@
 					      GFP_KERNEL,
 					      &dev->cntl_urb->transfer_dma);
 	if (!dev->cntl_buffer) {
-		err("Could not allocate cntl_buffer");
+		dev_err(&interface->dev, "Could not allocate cntl_buffer\n");
 		goto error;
 	}
 
@@ -265,7 +271,7 @@
 	/* allocate interrupt URB */
 	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->urb) {
-		err("Could not allocate URB");
+		dev_err(&interface->dev, "Could not allocate URB\n");
 		goto error;
 	}
 
@@ -273,7 +279,7 @@
 	dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
 					GFP_KERNEL, &dev->urb->transfer_dma);
 	if (!dev->int_buffer) {
-		err("Could not allocate int_buffer");
+		dev_err(&interface->dev, "Could not allocate int_buffer\n");
 		goto error;
 	}
 
@@ -285,7 +291,7 @@
 	dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
 		retval = -EIO;
-		err("Could not submitting URB");
+		dev_err(&interface->dev, "Could not submitting URB\n");
 		goto error;
 	}
 
@@ -295,7 +301,8 @@
 	/* we can register the device now, as it is ready */
 	retval = usb_register_dev(interface, &yurex_class);
 	if (retval) {
-		err("Not able to get a minor for this device.");
+		dev_err(&interface->dev,
+			"Not able to get a minor for this device.\n");
 		usb_set_intfdata(interface, NULL);
 		goto error;
 	}
@@ -368,8 +375,8 @@
 
 	interface = usb_find_interface(&yurex_driver, subminor);
 	if (!interface) {
-		err("%s - error, can't find device for minor %d",
-		    __func__, subminor);
+		printk(KERN_ERR "%s - error, can't find device for minor %d",
+		       __func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
@@ -505,7 +512,8 @@
 
 	/* send the data as the control msg */
 	prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE);
-	dbg("%s - submit %c", __func__, dev->cntl_buffer[0]);
+	dev_dbg(&dev->interface->dev, "%s - submit %c\n", __func__,
+		dev->cntl_buffer[0]);
 	retval = usb_submit_urb(dev->cntl_urb, GFP_KERNEL);
 	if (retval >= 0)
 		timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
@@ -514,7 +522,9 @@
 	mutex_unlock(&dev->io_mutex);
 
 	if (retval < 0) {
-		err("%s - failed to send bulk msg, error %d", __func__, retval);
+		dev_err(&dev->interface->dev,
+			"%s - failed to send bulk msg, error %d\n",
+			__func__, retval);
 		goto error;
 	}
 	if (set && timeout)
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index f70cab3..ef0c3f9 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -8,6 +8,7 @@
 	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
 	depends on USB && USB_GADGET
 	select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
+	select NOP_USB_XCEIV if (SOC_OMAPTI81XX || SOC_OMAPAM33XX)
 	select TWL4030_USB if MACH_OMAP_3430SDP
 	select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
 	select USB_OTG_UTILS
@@ -54,6 +55,10 @@
 	tristate "AM35x"
 	depends on ARCH_OMAP
 
+config USB_MUSB_DSPS
+	tristate "TI DSPS platforms"
+	depends on SOC_OMAPTI81XX || SOC_OMAPAM33XX
+
 config USB_MUSB_BLACKFIN
 	tristate "Blackfin"
 	depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523)
@@ -70,7 +75,8 @@
 	default USB_INVENTRA_DMA if USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN
 	default USB_TI_CPPI_DMA if USB_MUSB_DAVINCI
 	default USB_TUSB_OMAP_DMA if USB_MUSB_TUSB6010
-	default MUSB_PIO_ONLY if USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X
+	default MUSB_PIO_ONLY if USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X \
+				|| USB_MUSB_DSPS
 	help
 	  Unfortunately, only one option can be enabled here. Ideally one
 	  should be able to build all these drivers into one kernel to
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 88bfb9d..3b85871 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -13,6 +13,7 @@
 # Hardware Glue Layer
 obj-$(CONFIG_USB_MUSB_OMAP2PLUS)		+= omap2430.o
 obj-$(CONFIG_USB_MUSB_AM35X)			+= am35x.o
+obj-$(CONFIG_USB_MUSB_DSPS)			+= musb_dsps.o
 obj-$(CONFIG_USB_MUSB_TUSB6010)			+= tusb6010.o
 obj-$(CONFIG_USB_MUSB_DAVINCI)			+= davinci.o
 obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 66bc376..8637c1f 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -6,6 +6,7 @@
  * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci.
  */
 
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 66aaccf..db3dff8 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1034,7 +1034,9 @@
 	|| defined(CONFIG_USB_MUSB_OMAP2PLUS)		\
 	|| defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE)	\
 	|| defined(CONFIG_USB_MUSB_AM35X)		\
-	|| defined(CONFIG_USB_MUSB_AM35X_MODULE)
+	|| defined(CONFIG_USB_MUSB_AM35X_MODULE)	\
+	|| defined(CONFIG_USB_MUSB_DSPS)		\
+	|| defined(CONFIG_USB_MUSB_DSPS_MODULE)
 static ushort __devinitdata fifo_mode = 4;
 #elif defined(CONFIG_USB_MUSB_UX500)			\
 	|| defined(CONFIG_USB_MUSB_UX500_MODULE)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
new file mode 100644
index 0000000..23db42d
--- /dev/null
+++ b/drivers/usb/musb/musb_dsps.c
@@ -0,0 +1,711 @@
+/*
+ * Texas Instruments DSPS platforms "glue layer"
+ *
+ * Copyright (C) 2012, by Texas Instruments
+ *
+ * Based on the am35x "glue layer" code.
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 2 as published by the Free Software
+ * Foundation.
+ *
+ * The Inventra Controller Driver for Linux 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 The Inventra Controller Driver for Linux ; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA  02111-1307  USA
+ *
+ * musb_dsps.c will be a common file for all the TI DSPS platforms
+ * such as dm64x, dm36x, dm35x, da8x, am35x and ti81x.
+ * For now only ti81x is using this and in future davinci.c, am35x.c
+ * da8xx.c would be merged to this file after testing.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm_runtime.h>
+#include <linux/module.h>
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+
+#include <plat/usb.h>
+
+#include "musb_core.h"
+
+/**
+ * avoid using musb_readx()/musb_writex() as glue layer should not be
+ * dependent on musb core layer symbols.
+ */
+static inline u8 dsps_readb(const void __iomem *addr, unsigned offset)
+	{ return __raw_readb(addr + offset); }
+
+static inline u32 dsps_readl(const void __iomem *addr, unsigned offset)
+	{ return __raw_readl(addr + offset); }
+
+static inline void dsps_writeb(void __iomem *addr, unsigned offset, u8 data)
+	{ __raw_writeb(data, addr + offset); }
+
+static inline void dsps_writel(void __iomem *addr, unsigned offset, u32 data)
+	{ __raw_writel(data, addr + offset); }
+
+/**
+ * DSPS musb wrapper register offset.
+ * FIXME: This should be expanded to have all the wrapper registers from TI DSPS
+ * musb ips.
+ */
+struct dsps_musb_wrapper {
+	u16	revision;
+	u16	control;
+	u16	status;
+	u16	eoi;
+	u16	epintr_set;
+	u16	epintr_clear;
+	u16	epintr_status;
+	u16	coreintr_set;
+	u16	coreintr_clear;
+	u16	coreintr_status;
+	u16	phy_utmi;
+	u16	mode;
+
+	/* bit positions for control */
+	unsigned	reset:5;
+
+	/* bit positions for interrupt */
+	unsigned	usb_shift:5;
+	u32		usb_mask;
+	u32		usb_bitmap;
+	unsigned	drvvbus:5;
+
+	unsigned	txep_shift:5;
+	u32		txep_mask;
+	u32		txep_bitmap;
+
+	unsigned	rxep_shift:5;
+	u32		rxep_mask;
+	u32		rxep_bitmap;
+
+	/* bit positions for phy_utmi */
+	unsigned	otg_disable:5;
+
+	/* bit positions for mode */
+	unsigned	iddig:5;
+	/* miscellaneous stuff */
+	u32		musb_core_offset;
+	u8		poll_seconds;
+};
+
+/**
+ * DSPS glue structure.
+ */
+struct dsps_glue {
+	struct device *dev;
+	struct platform_device *musb;	/* child musb pdev */
+	const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
+	struct timer_list timer;	/* otg_workaround timer */
+};
+
+/**
+ * dsps_musb_enable - enable interrupts
+ */
+static void dsps_musb_enable(struct musb *musb)
+{
+	struct device *dev = musb->controller;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+	const struct dsps_musb_wrapper *wrp = glue->wrp;
+	void __iomem *reg_base = musb->ctrl_base;
+	u32 epmask, coremask;
+
+	/* Workaround: setup IRQs through both register sets. */
+	epmask = ((musb->epmask & wrp->txep_mask) << wrp->txep_shift) |
+	       ((musb->epmask & wrp->rxep_mask) << wrp->rxep_shift);
+	coremask = (wrp->usb_bitmap & ~MUSB_INTR_SOF);
+
+	dsps_writel(reg_base, wrp->epintr_set, epmask);
+	dsps_writel(reg_base, wrp->coreintr_set, coremask);
+	/* Force the DRVVBUS IRQ so we can start polling for ID change. */
+	if (is_otg_enabled(musb))
+		dsps_writel(reg_base, wrp->coreintr_set,
+			    (1 << wrp->drvvbus) << wrp->usb_shift);
+}
+
+/**
+ * dsps_musb_disable - disable HDRC and flush interrupts
+ */
+static void dsps_musb_disable(struct musb *musb)
+{
+	struct device *dev = musb->controller;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+	const struct dsps_musb_wrapper *wrp = glue->wrp;
+	void __iomem *reg_base = musb->ctrl_base;
+
+	dsps_writel(reg_base, wrp->coreintr_clear, wrp->usb_bitmap);
+	dsps_writel(reg_base, wrp->epintr_clear,
+			 wrp->txep_bitmap | wrp->rxep_bitmap);
+	dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
+	dsps_writel(reg_base, wrp->eoi, 0);
+}
+
+static void otg_timer(unsigned long _musb)
+{
+	struct musb *musb = (void *)_musb;
+	void __iomem *mregs = musb->mregs;
+	struct device *dev = musb->controller;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+	const struct dsps_musb_wrapper *wrp = glue->wrp;
+	u8 devctl;
+	unsigned long flags;
+
+	/*
+	 * We poll because DSPS IP's won't expose several OTG-critical
+	 * status change events (from the transceiver) otherwise.
+	 */
+	devctl = dsps_readb(mregs, MUSB_DEVCTL);
+	dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
+				otg_state_string(musb->xceiv->state));
+
+	spin_lock_irqsave(&musb->lock, flags);
+	switch (musb->xceiv->state) {
+	case OTG_STATE_A_WAIT_BCON:
+		devctl &= ~MUSB_DEVCTL_SESSION;
+		dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+		devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
+		if (devctl & MUSB_DEVCTL_BDEVICE) {
+			musb->xceiv->state = OTG_STATE_B_IDLE;
+			MUSB_DEV_MODE(musb);
+		} else {
+			musb->xceiv->state = OTG_STATE_A_IDLE;
+			MUSB_HST_MODE(musb);
+		}
+		break;
+	case OTG_STATE_A_WAIT_VFALL:
+		musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+		dsps_writel(musb->ctrl_base, wrp->coreintr_set,
+			    MUSB_INTR_VBUSERROR << wrp->usb_shift);
+		break;
+	case OTG_STATE_B_IDLE:
+		if (!is_peripheral_enabled(musb))
+			break;
+
+		devctl = dsps_readb(mregs, MUSB_DEVCTL);
+		if (devctl & MUSB_DEVCTL_BDEVICE)
+			mod_timer(&glue->timer,
+					jiffies + wrp->poll_seconds * HZ);
+		else
+			musb->xceiv->state = OTG_STATE_A_IDLE;
+		break;
+	default:
+		break;
+	}
+	spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
+{
+	struct device *dev = musb->controller;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+	static unsigned long last_timer;
+
+	if (!is_otg_enabled(musb))
+		return;
+
+	if (timeout == 0)
+		timeout = jiffies + msecs_to_jiffies(3);
+
+	/* Never idle if active, or when VBUS timeout is not set as host */
+	if (musb->is_active || (musb->a_wait_bcon == 0 &&
+				musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
+		dev_dbg(musb->controller, "%s active, deleting timer\n",
+				otg_state_string(musb->xceiv->state));
+		del_timer(&glue->timer);
+		last_timer = jiffies;
+		return;
+	}
+
+	if (time_after(last_timer, timeout) && timer_pending(&glue->timer)) {
+		dev_dbg(musb->controller,
+			"Longer idle timer already pending, ignoring...\n");
+		return;
+	}
+	last_timer = timeout;
+
+	dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
+		otg_state_string(musb->xceiv->state),
+			jiffies_to_msecs(timeout - jiffies));
+	mod_timer(&glue->timer, timeout);
+}
+
+static irqreturn_t dsps_interrupt(int irq, void *hci)
+{
+	struct musb  *musb = hci;
+	void __iomem *reg_base = musb->ctrl_base;
+	struct device *dev = musb->controller;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+	const struct dsps_musb_wrapper *wrp = glue->wrp;
+	unsigned long flags;
+	irqreturn_t ret = IRQ_NONE;
+	u32 epintr, usbintr;
+
+	spin_lock_irqsave(&musb->lock, flags);
+
+	/* Get endpoint interrupts */
+	epintr = dsps_readl(reg_base, wrp->epintr_status);
+	musb->int_rx = (epintr & wrp->rxep_bitmap) >> wrp->rxep_shift;
+	musb->int_tx = (epintr & wrp->txep_bitmap) >> wrp->txep_shift;
+
+	if (epintr)
+		dsps_writel(reg_base, wrp->epintr_status, epintr);
+
+	/* Get usb core interrupts */
+	usbintr = dsps_readl(reg_base, wrp->coreintr_status);
+	if (!usbintr && !epintr)
+		goto eoi;
+
+	musb->int_usb =	(usbintr & wrp->usb_bitmap) >> wrp->usb_shift;
+	if (usbintr)
+		dsps_writel(reg_base, wrp->coreintr_status, usbintr);
+
+	dev_dbg(musb->controller, "usbintr (%x) epintr(%x)\n",
+			usbintr, epintr);
+	/*
+	 * DRVVBUS IRQs are the only proxy we have (a very poor one!) for
+	 * DSPS IP's missing ID change IRQ.  We need an ID change IRQ to
+	 * switch appropriately between halves of the OTG state machine.
+	 * Managing DEVCTL.SESSION per Mentor docs requires that we know its
+	 * value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
+	 * Also, DRVVBUS pulses for SRP (but not at 5V) ...
+	 */
+	if ((usbintr & MUSB_INTR_BABBLE) && is_host_enabled(musb))
+		pr_info("CAUTION: musb: Babble Interrupt Occured\n");
+
+	if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
+		int drvvbus = dsps_readl(reg_base, wrp->status);
+		void __iomem *mregs = musb->mregs;
+		u8 devctl = dsps_readb(mregs, MUSB_DEVCTL);
+		int err;
+
+		err = is_host_enabled(musb) && (musb->int_usb &
+						MUSB_INTR_VBUSERROR);
+		if (err) {
+			/*
+			 * The Mentor core doesn't debounce VBUS as needed
+			 * to cope with device connect current spikes. This
+			 * means it's not uncommon for bus-powered devices
+			 * to get VBUS errors during enumeration.
+			 *
+			 * This is a workaround, but newer RTL from Mentor
+			 * seems to allow a better one: "re"-starting sessions
+			 * without waiting for VBUS to stop registering in
+			 * devctl.
+			 */
+			musb->int_usb &= ~MUSB_INTR_VBUSERROR;
+			musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
+			mod_timer(&glue->timer,
+					jiffies + wrp->poll_seconds * HZ);
+			WARNING("VBUS error workaround (delay coming)\n");
+		} else if (is_host_enabled(musb) && drvvbus) {
+			musb->is_active = 1;
+			MUSB_HST_MODE(musb);
+			musb->xceiv->otg->default_a = 1;
+			musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+			del_timer(&glue->timer);
+		} else {
+			musb->is_active = 0;
+			MUSB_DEV_MODE(musb);
+			musb->xceiv->otg->default_a = 0;
+			musb->xceiv->state = OTG_STATE_B_IDLE;
+		}
+
+		/* NOTE: this must complete power-on within 100 ms. */
+		dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
+				drvvbus ? "on" : "off",
+				otg_state_string(musb->xceiv->state),
+				err ? " ERROR" : "",
+				devctl);
+		ret = IRQ_HANDLED;
+	}
+
+	if (musb->int_tx || musb->int_rx || musb->int_usb)
+		ret |= musb_interrupt(musb);
+
+ eoi:
+	/* EOI needs to be written for the IRQ to be re-asserted. */
+	if (ret == IRQ_HANDLED || epintr || usbintr)
+		dsps_writel(reg_base, wrp->eoi, 1);
+
+	/* Poll for ID change */
+	if (is_otg_enabled(musb) && musb->xceiv->state == OTG_STATE_B_IDLE)
+		mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+
+	spin_unlock_irqrestore(&musb->lock, flags);
+
+	return ret;
+}
+
+static int dsps_musb_init(struct musb *musb)
+{
+	struct device *dev = musb->controller;
+	struct musb_hdrc_platform_data *plat = dev->platform_data;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+	const struct dsps_musb_wrapper *wrp = glue->wrp;
+	struct omap_musb_board_data *data = plat->board_data;
+	void __iomem *reg_base = musb->ctrl_base;
+	u32 rev, val;
+	int status;
+
+	/* mentor core register starts at offset of 0x400 from musb base */
+	musb->mregs += wrp->musb_core_offset;
+
+	/* NOP driver needs change if supporting dual instance */
+	usb_nop_xceiv_register();
+	musb->xceiv = usb_get_transceiver();
+	if (!musb->xceiv)
+		return -ENODEV;
+
+	/* Returns zero if e.g. not clocked */
+	rev = dsps_readl(reg_base, wrp->revision);
+	if (!rev) {
+		status = -ENODEV;
+		goto err0;
+	}
+
+	if (is_host_enabled(musb))
+		setup_timer(&glue->timer, otg_timer, (unsigned long) musb);
+
+	/* Reset the musb */
+	dsps_writel(reg_base, wrp->control, (1 << wrp->reset));
+
+	/* Start the on-chip PHY and its PLL. */
+	if (data->set_phy_power)
+		data->set_phy_power(1);
+
+	musb->isr = dsps_interrupt;
+
+	/* reset the otgdisable bit, needed for host mode to work */
+	val = dsps_readl(reg_base, wrp->phy_utmi);
+	val &= ~(1 << wrp->otg_disable);
+	dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
+
+	/* clear level interrupt */
+	dsps_writel(reg_base, wrp->eoi, 0);
+
+	return 0;
+err0:
+	usb_put_transceiver(musb->xceiv);
+	usb_nop_xceiv_unregister();
+	return status;
+}
+
+static int dsps_musb_exit(struct musb *musb)
+{
+	struct device *dev = musb->controller;
+	struct musb_hdrc_platform_data *plat = dev->platform_data;
+	struct omap_musb_board_data *data = plat->board_data;
+	struct platform_device *pdev = to_platform_device(dev->parent);
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+
+	if (is_host_enabled(musb))
+		del_timer_sync(&glue->timer);
+
+	/* Shutdown the on-chip PHY and its PLL. */
+	if (data->set_phy_power)
+		data->set_phy_power(0);
+
+	/* NOP driver needs change if supporting dual instance */
+	usb_put_transceiver(musb->xceiv);
+	usb_nop_xceiv_unregister();
+
+	return 0;
+}
+
+static struct musb_platform_ops dsps_ops = {
+	.init		= dsps_musb_init,
+	.exit		= dsps_musb_exit,
+
+	.enable		= dsps_musb_enable,
+	.disable	= dsps_musb_disable,
+
+	.try_idle	= dsps_musb_try_idle,
+};
+
+static u64 musb_dmamask = DMA_BIT_MASK(32);
+
+static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
+{
+	struct device *dev = glue->dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct musb_hdrc_platform_data  *pdata = dev->platform_data;
+	struct platform_device	*musb;
+	struct resource *res;
+	struct resource	resources[2];
+	char res_name[10];
+	int ret;
+
+	/* get memory resource */
+	sprintf(res_name, "musb%d", id);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
+	if (!res) {
+		dev_err(dev, "%s get mem resource failed\n", res_name);
+		ret = -ENODEV;
+		goto err0;
+	}
+	res->parent = NULL;
+	resources[0] = *res;
+
+	/* get irq resource */
+	sprintf(res_name, "musb%d-irq", id);
+	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
+	if (!res) {
+		dev_err(dev, "%s get irq resource failed\n", res_name);
+		ret = -ENODEV;
+		goto err0;
+	}
+	strcpy((u8 *)res->name, "mc");
+	res->parent = NULL;
+	resources[1] = *res;
+
+	/* allocate the child platform device */
+	musb = platform_device_alloc("musb-hdrc", -1);
+	if (!musb) {
+		dev_err(dev, "failed to allocate musb device\n");
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	musb->dev.parent		= dev;
+	musb->dev.dma_mask		= &musb_dmamask;
+	musb->dev.coherent_dma_mask	= musb_dmamask;
+
+	glue->musb			= musb;
+
+	pdata->platform_ops		= &dsps_ops;
+
+	ret = platform_device_add_resources(musb, resources, 2);
+	if (ret) {
+		dev_err(dev, "failed to add resources\n");
+		goto err1;
+	}
+
+	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+	if (ret) {
+		dev_err(dev, "failed to add platform_data\n");
+		goto err1;
+	}
+
+	ret = platform_device_add(musb);
+	if (ret) {
+		dev_err(dev, "failed to register musb device\n");
+		goto err1;
+	}
+
+	return 0;
+
+err1:
+	platform_device_put(musb);
+err0:
+	return ret;
+}
+
+static void __devexit dsps_delete_musb_pdev(struct dsps_glue *glue)
+{
+	platform_device_del(glue->musb);
+	platform_device_put(glue->musb);
+}
+
+static int __devinit dsps_probe(struct platform_device *pdev)
+{
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	const struct dsps_musb_wrapper *wrp =
+				(struct dsps_musb_wrapper *)id->driver_data;
+	struct dsps_glue *glue;
+	struct resource *iomem;
+	int ret;
+
+	/* allocate glue */
+	glue = kzalloc(sizeof(*glue), GFP_KERNEL);
+	if (!glue) {
+		dev_err(&pdev->dev, "unable to allocate glue memory\n");
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	/* get memory resource */
+	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!iomem) {
+		dev_err(&pdev->dev, "failed to get usbss mem resourse\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	glue->dev = &pdev->dev;
+
+	glue->wrp = kmemdup(wrp, sizeof(*wrp), GFP_KERNEL);
+	if (!glue->wrp) {
+		dev_err(&pdev->dev, "failed to duplicate wrapper struct memory\n");
+		ret = -ENOMEM;
+		goto err1;
+	}
+	platform_set_drvdata(pdev, glue);
+
+	/* create the child platform device for first instances of musb */
+	ret = dsps_create_musb_pdev(glue, 0);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "failed to create child pdev\n");
+		goto err2;
+	}
+
+	/* enable the usbss clocks */
+	pm_runtime_enable(&pdev->dev);
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pm_runtime_get_sync FAILED");
+		goto err3;
+	}
+
+	return 0;
+
+err3:
+	pm_runtime_disable(&pdev->dev);
+err2:
+	kfree(glue->wrp);
+err1:
+	kfree(glue);
+err0:
+	return ret;
+}
+static int __devexit dsps_remove(struct platform_device *pdev)
+{
+	struct dsps_glue *glue = platform_get_drvdata(pdev);
+
+	/* delete the child platform device */
+	dsps_delete_musb_pdev(glue);
+
+	/* disable usbss clocks */
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	kfree(glue->wrp);
+	kfree(glue);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dsps_suspend(struct device *dev)
+{
+	struct musb_hdrc_platform_data *plat = dev->platform_data;
+	struct omap_musb_board_data *data = plat->board_data;
+
+	/* Shutdown the on-chip PHY and its PLL. */
+	if (data->set_phy_power)
+		data->set_phy_power(0);
+
+	return 0;
+}
+
+static int dsps_resume(struct device *dev)
+{
+	struct musb_hdrc_platform_data *plat = dev->platform_data;
+	struct omap_musb_board_data *data = plat->board_data;
+
+	/* Start the on-chip PHY and its PLL. */
+	if (data->set_phy_power)
+		data->set_phy_power(1);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
+
+static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = {
+	.revision		= 0x00,
+	.control		= 0x14,
+	.status			= 0x18,
+	.eoi			= 0x24,
+	.epintr_set		= 0x38,
+	.epintr_clear		= 0x40,
+	.epintr_status		= 0x30,
+	.coreintr_set		= 0x3c,
+	.coreintr_clear		= 0x44,
+	.coreintr_status	= 0x34,
+	.phy_utmi		= 0xe0,
+	.mode			= 0xe8,
+	.reset			= 0,
+	.otg_disable		= 21,
+	.iddig			= 8,
+	.usb_shift		= 0,
+	.usb_mask		= 0x1ff,
+	.usb_bitmap		= (0x1ff << 0),
+	.drvvbus		= 8,
+	.txep_shift		= 0,
+	.txep_mask		= 0xffff,
+	.txep_bitmap		= (0xffff << 0),
+	.rxep_shift		= 16,
+	.rxep_mask		= 0xfffe,
+	.rxep_bitmap		= (0xfffe << 16),
+	.musb_core_offset	= 0x400,
+	.poll_seconds		= 2,
+};
+
+static const struct platform_device_id musb_dsps_id_table[] __devinitconst = {
+	{
+		.name	= "musb-ti81xx",
+		.driver_data	= (kernel_ulong_t) &ti81xx_driver_data,
+	},
+	{  },	/* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(platform, musb_dsps_id_table);
+
+static const struct of_device_id musb_dsps_of_match[] __devinitconst = {
+	{ .compatible = "musb-ti81xx", },
+	{ .compatible = "ti,ti81xx-musb", },
+	{ .compatible = "ti,am335x-musb", },
+	{  },
+};
+MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
+
+static struct platform_driver dsps_usbss_driver = {
+	.probe		= dsps_probe,
+	.remove         = __devexit_p(dsps_remove),
+	.driver         = {
+		.name   = "musb-dsps",
+		.pm	= &dsps_pm_ops,
+		.of_match_table	= musb_dsps_of_match,
+	},
+	.id_table	= musb_dsps_id_table,
+};
+
+MODULE_DESCRIPTION("TI DSPS MUSB Glue Layer");
+MODULE_AUTHOR("Ravi B <ravibabu@ti.com>");
+MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>");
+MODULE_LICENSE("GPL v2");
+
+static int __init dsps_init(void)
+{
+	return platform_driver_register(&dsps_usbss_driver);
+}
+subsys_initcall(dsps_init);
+
+static void __exit dsps_exit(void)
+{
+	platform_driver_unregister(&dsps_usbss_driver);
+}
+module_exit(dsps_exit);
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index a0a2178..bd6e755 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -37,7 +37,8 @@
 	struct regulator       *vbus_draw;
 	int			vbus_draw_enabled;
 	unsigned		mA;
-	struct work_struct	work;
+	struct delayed_work	work;
+	int			vbus;
 };
 
 
@@ -94,20 +95,26 @@
 static void gpio_vbus_work(struct work_struct *work)
 {
 	struct gpio_vbus_data *gpio_vbus =
-		container_of(work, struct gpio_vbus_data, work);
+		container_of(work, struct gpio_vbus_data, work.work);
 	struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
-	int gpio, status;
+	int gpio, status, vbus;
 
 	if (!gpio_vbus->phy.otg->gadget)
 		return;
 
+	vbus = is_vbus_powered(pdata);
+	if ((vbus ^ gpio_vbus->vbus) == 0)
+		return;
+	gpio_vbus->vbus = vbus;
+
 	/* Peripheral controllers which manage the pullup themselves won't have
 	 * gpio_pullup configured here.  If it's configured here, we'll do what
 	 * isp1301_omap::b_peripheral() does and enable the pullup here... although
 	 * that may complicate usb_gadget_{,dis}connect() support.
 	 */
 	gpio = pdata->gpio_pullup;
-	if (is_vbus_powered(pdata)) {
+
+	if (vbus) {
 		status = USB_EVENT_VBUS;
 		gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL;
 		gpio_vbus->phy.last_event = status;
@@ -152,7 +159,7 @@
 		otg->gadget ? otg->gadget->name : "none");
 
 	if (otg->gadget)
-		schedule_work(&gpio_vbus->work);
+		schedule_delayed_work(&gpio_vbus->work, msecs_to_jiffies(100));
 
 	return IRQ_HANDLED;
 }
@@ -195,6 +202,7 @@
 	dev_dbg(&pdev->dev, "registered gadget '%s'\n", gadget->name);
 
 	/* initialize connection state */
+	gpio_vbus->vbus = 0; /* start with disconnected */
 	gpio_vbus_irq(irq, pdev);
 	return 0;
 }
@@ -300,7 +308,7 @@
 
 	ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier);
 
-	INIT_WORK(&gpio_vbus->work, gpio_vbus_work);
+	INIT_DELAYED_WORK(&gpio_vbus->work, gpio_vbus_work);
 
 	gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw");
 	if (IS_ERR(gpio_vbus->vbus_draw)) {
@@ -319,7 +327,8 @@
 
 	return 0;
 err_otg:
-	free_irq(irq, &pdev->dev);
+	regulator_put(gpio_vbus->vbus_draw);
+	free_irq(irq, pdev);
 err_irq:
 	if (gpio_is_valid(pdata->gpio_pullup))
 		gpio_free(pdata->gpio_pullup);
@@ -341,7 +350,7 @@
 
 	usb_set_transceiver(NULL);
 
-	free_irq(gpio_to_irq(gpio), &pdev->dev);
+	free_irq(gpio_to_irq(gpio), pdev);
 	if (gpio_is_valid(pdata->gpio_pullup))
 		gpio_free(pdata->gpio_pullup);
 	gpio_free(gpio);
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
new file mode 100644
index 0000000..3cfabcb
--- /dev/null
+++ b/drivers/usb/phy/Kconfig
@@ -0,0 +1,17 @@
+#
+# Physical Layer USB driver configuration
+#
+comment "USB Physical Layer drivers"
+	depends on USB
+
+config USB_ISP1301
+	tristate "NXP ISP1301 USB transceiver support"
+	depends on USB
+	depends on I2C
+	help
+	  Say Y here to add support for the NXP ISP1301 USB transceiver driver.
+	  This chip is typically used as USB transceiver for USB host, gadget
+	  and OTG drivers (to be selected separately).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called isp1301.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
new file mode 100644
index 0000000..eca095b
--- /dev/null
+++ b/drivers/usb/phy/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for physical layer USB drivers
+#
+
+ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
+
+obj-$(CONFIG_USB_ISP1301)		+= isp1301.o
diff --git a/drivers/usb/phy/isp1301.c b/drivers/usb/phy/isp1301.c
new file mode 100644
index 0000000..b19f493
--- /dev/null
+++ b/drivers/usb/phy/isp1301.c
@@ -0,0 +1,77 @@
+/*
+ * NXP ISP1301 USB transceiver driver
+ *
+ * Copyright (C) 2012 Roland Stigge
+ *
+ * Author: Roland Stigge <stigge@antcom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+
+#define DRV_NAME		"isp1301"
+
+#define ISP1301_I2C_ADDR	0x2C
+
+static const unsigned short normal_i2c[] = {
+	ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END
+};
+
+static const struct i2c_device_id isp1301_id[] = {
+	{ "isp1301", 0 },
+	{ }
+};
+
+static struct i2c_client *isp1301_i2c_client;
+
+static int isp1301_probe(struct i2c_client *client,
+			 const struct i2c_device_id *i2c_id)
+{
+	isp1301_i2c_client = client;
+	return 0;
+}
+
+static int isp1301_remove(struct i2c_client *client)
+{
+	return 0;
+}
+
+static struct i2c_driver isp1301_driver = {
+	.driver = {
+		.name = DRV_NAME,
+	},
+	.probe = isp1301_probe,
+	.remove = isp1301_remove,
+	.id_table = isp1301_id,
+};
+
+module_i2c_driver(isp1301_driver);
+
+static int match(struct device *dev, void *data)
+{
+	struct device_node *node = (struct device_node *)data;
+	return (dev->of_node == node) &&
+		(dev->driver == &isp1301_driver.driver);
+}
+
+struct i2c_client *isp1301_get_client(struct device_node *node)
+{
+	if (node) { /* reference of ISP1301 I2C node via DT */
+		struct device *dev = bus_find_device(&i2c_bus_type, NULL,
+						     node, match);
+		if (!dev)
+			return NULL;
+		return to_i2c_client(dev);
+	} else { /* non-DT: only one ISP1301 chip supported */
+		return isp1301_i2c_client;
+	}
+}
+EXPORT_SYMBOL_GPL(isp1301_get_client);
+
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("NXP ISP1301 USB transceiver driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 00bd2a5..28478ce 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -55,6 +55,7 @@
 #define USBHSG_STATUS_STARTED		(1 << 0)
 #define USBHSG_STATUS_REGISTERD		(1 << 1)
 #define USBHSG_STATUS_WEDGE		(1 << 2)
+#define USBHSG_STATUS_SELF_POWERED	(1 << 3)
 };
 
 struct usbhsg_recip_handle {
@@ -333,7 +334,10 @@
 					       struct usb_ctrlrequest *ctrl)
 {
 	struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
-	unsigned short status = 1 << USB_DEVICE_SELF_POWERED;
+	unsigned short status = 0;
+
+	if (usbhsg_status_has(gpriv, USBHSG_STATUS_SELF_POWERED))
+		status = 1 << USB_DEVICE_SELF_POWERED;
 
 	__usbhsg_recip_send_status(gpriv, status);
 
@@ -879,8 +883,21 @@
 	return usbhs_frame_get_num(priv);
 }
 
+static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self)
+{
+	struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
+
+	if (is_self)
+		usbhsg_status_set(gpriv, USBHSG_STATUS_SELF_POWERED);
+	else
+		usbhsg_status_clr(gpriv, USBHSG_STATUS_SELF_POWERED);
+
+	return 0;
+}
+
 static struct usb_gadget_ops usbhsg_gadget_ops = {
 	.get_frame		= usbhsg_get_frame,
+	.set_selfpowered	= usbhsg_set_selfpowered,
 	.udc_start		= usbhsg_gadget_start,
 	.udc_stop		= usbhsg_gadget_stop,
 };
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 7141d65..325d291 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -669,6 +669,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ssu100.
 
+config USB_SERIAL_QT2
+	tristate "USB Quatech Serial Driver for USB 2 devices"
+	help
+	  Say Y here if you want to use the Quatech USB 2
+	  serial adapters.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called quatech-serial.
+
 config USB_SERIAL_DEBUG
 	tristate "USB Debugging Device"
 	help
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 07f198e..1dc483a 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -49,6 +49,7 @@
 obj-$(CONFIG_USB_SERIAL_PL2303)			+= pl2303.o
 obj-$(CONFIG_USB_SERIAL_QCAUX)			+= qcaux.o
 obj-$(CONFIG_USB_SERIAL_QUALCOMM)		+= qcserial.o
+obj-$(CONFIG_USB_SERIAL_QT2)			+= quatech2.o
 obj-$(CONFIG_USB_SERIAL_SAFE)			+= safe_serial.o
 obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI)		+= siemens_mpi.o
 obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS)		+= sierra.o
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index eec4fb9..d634e66 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -111,13 +111,14 @@
 	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
 		endpoint = &iface_desc->endpoint[i].desc;
 		if (usb_endpoint_is_bulk_out(endpoint)) {
-			dbg("found bulk out on endpoint %d", i);
+			dev_dbg(&serial->dev->dev,
+				"found bulk out on endpoint %d\n", i);
 			++num_bulk_out;
 		}
 	}
 
 	if (num_bulk_out == 0) {
-		dbg("Invalid interface, discarding");
+		dev_dbg(&serial->dev->dev, "Invalid interface, discarding\n");
 		return -ENODEV;
 	}
 
@@ -133,7 +134,7 @@
 		packet += HCI_HEADER_LENGTH;
 	}
 	if (len <= 0) {
-		dbg("%s - malformed packet", __func__);
+		dev_dbg(&port->dev, "%s - malformed packet\n", __func__);
 		return 0;
 	}
 
@@ -170,13 +171,6 @@
 	tty_kref_put(tty);
 }
 
-static struct usb_driver aircable_driver = {
-	.name =		"aircable",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver aircable_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -196,7 +190,7 @@
 	&aircable_device, NULL
 };
 
-module_usb_serial_driver(aircable_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index f99f4710..f8ce97d 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -265,7 +265,7 @@
 	hcr = (cflag & CRTSCTS) ? 0x03 : 0x00;
 
 	/* calc baudrate */
-	dbg("%s - setting bps to %d", __func__, bps);
+	dev_dbg(&port->dev, "%s - setting bps to %d\n", __func__, bps);
 	eval = 0;
 	switch (bps) {
 	case 0:
@@ -292,8 +292,8 @@
 	/* keep old LCR_SBC bit */
 	lcr |= (priv->lcr & UART_LCR_SBC);
 
-	dbg("%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d",
-	    __func__, hcr, lcr, quot);
+	dev_dbg(&port->dev, "%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d\n",
+		__func__, hcr, lcr, quot);
 
 	/* handshake control */
 	if (priv->hcr != hcr) {
@@ -375,8 +375,9 @@
 
 	result = usb_serial_generic_open(tty, port);
 	if (result) {
-		dbg("%s - usb_serial_generic_open failed: %d",
-		    __func__, result);
+		dev_dbg(&port->dev,
+			"%s - usb_serial_generic_open failed: %d\n",
+			__func__, result);
 		goto err_out;
 	}
 
@@ -622,24 +623,26 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		break;
 	case 0: /* success */
 		/* discovered this by trail and error... */
 		if ((urb->actual_length == 4) && (data[0] == 0xe8)) {
 			const __u8 id = data[1]&UART_IIR_ID;
-			dbg("%s: iir=%02x", __func__, data[1]);
+			dev_dbg(&port->dev, "%s: iir=%02x\n", __func__, data[1]);
 			if (id == UART_IIR_MSI) {
-				dbg("%s: msr=%02x", __func__, data[3]);
+				dev_dbg(&port->dev, "%s: msr=%02x\n",
+					__func__, data[3]);
 				ark3116_update_msr(port, data[3]);
 				break;
 			} else if (id == UART_IIR_RLSI) {
-				dbg("%s: lsr=%02x", __func__, data[2]);
+				dev_dbg(&port->dev, "%s: lsr=%02x\n",
+					__func__, data[2]);
 				ark3116_update_lsr(port, data[2]);
 				break;
 			}
@@ -714,13 +717,6 @@
 	tty_kref_put(tty);
 }
 
-static struct usb_driver ark3116_driver = {
-	.name =		"ark3116",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver ark3116_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -747,7 +743,7 @@
 	&ark3116_device, NULL
 };
 
-module_usb_serial_driver(ark3116_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index a52e0d2..6b73656 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -2,17 +2,17 @@
  * Belkin USB Serial Adapter Driver
  *
  *  Copyright (C) 2000		William Greathouse (wgreathouse@smva.com)
- *  Copyright (C) 2000-2001 	Greg Kroah-Hartman (greg@kroah.com)
+ *  Copyright (C) 2000-2001	Greg Kroah-Hartman (greg@kroah.com)
  *  Copyright (C) 2010		Johan Hovold (jhovold@gmail.com)
  *
  *  This program is largely derived from work by the linux-usb group
  *  and associated source files.  Please see the usb/serial files for
  *  individual credits and copyrights.
  *
- * 	This program is free software; you can redistribute it and/or modify
- * 	it under the terms of the GNU General Public License as published by
- * 	the Free Software Foundation; either version 2 of the License, or
- * 	(at your option) any later version.
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this
  * driver
@@ -62,7 +62,7 @@
 					unsigned int set, unsigned int clear);
 
 
-static const struct usb_device_id id_table_combined[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
 	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
 	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
@@ -71,14 +71,7 @@
 	{ USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
 	{ }	/* Terminating entry */
 };
-MODULE_DEVICE_TABLE(usb, id_table_combined);
-
-static struct usb_driver belkin_driver = {
-	.name =		"belkin",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
+MODULE_DEVICE_TABLE(usb, id_table);
 
 /* All of the device info needed for the serial converters */
 static struct usb_serial_driver belkin_device = {
@@ -87,7 +80,7 @@
 		.name =		"belkin",
 	},
 	.description =		"Belkin / Peracom / GoHubs USB Serial Adapter",
-	.id_table =		id_table_combined,
+	.id_table =		id_table,
 	.num_ports =		1,
 	.open =			belkin_sa_open,
 	.close =		belkin_sa_close,
@@ -159,8 +152,6 @@
 {
 	int i;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i)
 		kfree(usb_get_serial_port_data(serial->port[i]));
 }
@@ -170,8 +161,6 @@
 {
 	int retval;
 
-	dbg("%s port %d", __func__, port->number);
-
 	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 	if (retval) {
 		dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
@@ -187,8 +176,6 @@
 
 static void belkin_sa_close(struct usb_serial_port *port)
 {
-	dbg("%s port %d", __func__, port->number);
-
 	usb_serial_generic_close(port);
 	usb_kill_urb(port->interrupt_in_urb);
 }
@@ -210,12 +197,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
@@ -403,7 +390,9 @@
 		case CS8:
 			urb_value = BELKIN_SA_DATA_BITS(8);
 			break;
-		default: dbg("CSIZE was not CS5-CS8, using default of 8");
+		default:
+			dev_dbg(&port->dev,
+				"CSIZE was not CS5-CS8, using default of 8\n");
 			urb_value = BELKIN_SA_DATA_BITS(8);
 			break;
 		}
@@ -463,8 +452,6 @@
 	unsigned long control_state;
 	unsigned long flags;
 
-	dbg("%s", __func__);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	control_state = priv->control_state;
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -484,8 +471,6 @@
 	int rts = 0;
 	int dtr = 0;
 
-	dbg("%s", __func__);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	control_state = priv->control_state;
 
@@ -524,7 +509,7 @@
 	return retval;
 }
 
-module_usb_serial_driver(belkin_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index ed8adb0..f398d1e 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -124,8 +124,15 @@
 	return retval;
 }
 
+static ssize_t show_dynids(struct device_driver *driver, char *buf)
+{
+	struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
+
+	return usb_show_dynids(&usb_drv->dynids, buf);
+}
+
 static struct driver_attribute drv_attrs[] = {
-	__ATTR(new_id, S_IWUSR, NULL, store_new_id),
+	__ATTR(new_id, S_IRUGO | S_IWUSR, show_dynids, store_new_id),
 	__ATTR_NULL,
 };
 
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index aaab32d..cabd1b1 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -125,8 +125,6 @@
 	unsigned long factor;
 	short divisor;
 
-	dbg("ch341_set_baudrate(%d)", priv->baud_rate);
-
 	if (!priv->baud_rate)
 		return -EINVAL;
 	factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate);
@@ -153,7 +151,6 @@
 
 static int ch341_set_handshake(struct usb_device *dev, u8 control)
 {
-	dbg("ch341_set_handshake(0x%02x)", control);
 	return ch341_control_out(dev, 0xa4, ~control, 0);
 }
 
@@ -164,8 +161,6 @@
 	const unsigned size = 8;
 	unsigned long flags;
 
-	dbg("ch341_get_status()");
-
 	buffer = kmalloc(size, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
@@ -196,8 +191,6 @@
 	int r;
 	const unsigned size = 8;
 
-	dbg("ch341_configure()");
-
 	buffer = kmalloc(size, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
@@ -254,8 +247,6 @@
 	struct ch341_private *priv;
 	int r;
 
-	dbg("ch341_attach()");
-
 	/* private data */
 	priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);
 	if (!priv)
@@ -290,7 +281,6 @@
 	struct ch341_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
 	/* drop DTR and RTS */
 	spin_lock_irqsave(&priv->lock, flags);
 	if (on)
@@ -304,8 +294,6 @@
 
 static void ch341_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	usb_serial_generic_close(port);
 	usb_kill_urb(port->interrupt_in_urb);
 }
@@ -318,8 +306,6 @@
 	struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
 	int r;
 
-	dbg("ch341_open()");
-
 	priv->baud_rate = DEFAULT_BAUD_RATE;
 
 	r = ch341_configure(serial->dev, priv);
@@ -358,8 +344,6 @@
 	unsigned baud_rate;
 	unsigned long flags;
 
-	dbg("ch341_set_termios()");
-
 	baud_rate = tty_get_baud_rate(tty);
 
 	priv->baud_rate = baud_rate;
@@ -393,8 +377,6 @@
 	uint16_t reg_contents;
 	uint8_t *break_reg;
 
-	dbg("%s()", __func__);
-
 	break_reg = kmalloc(2, GFP_KERNEL);
 	if (!break_reg) {
 		dev_err(&port->dev, "%s - kmalloc failed\n", __func__);
@@ -461,8 +443,6 @@
 	unsigned int actual_length = urb->actual_length;
 	int status;
 
-	dbg("%s (%d)", __func__, port->number);
-
 	switch (urb->status) {
 	case 0:
 		/* success */
@@ -580,8 +560,6 @@
 	u8 status;
 	unsigned int result;
 
-	dbg("%s (%d)", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	mcr = priv->line_control;
 	status = priv->line_status;
@@ -599,35 +577,18 @@
 	return result;
 }
 
-
-static int ch341_reset_resume(struct usb_interface *intf)
+static int ch341_reset_resume(struct usb_serial *serial)
 {
-	struct usb_device *dev = interface_to_usbdev(intf);
-	struct usb_serial *serial = NULL;
 	struct ch341_private *priv;
 
-	serial = usb_get_intfdata(intf);
 	priv = usb_get_serial_port_data(serial->port[0]);
 
-	/*reconfigure ch341 serial port after bus-reset*/
-	ch341_configure(dev, priv);
-
-	usb_serial_resume(intf);
+	/* reconfigure ch341 serial port after bus-reset */
+	ch341_configure(serial->dev, priv);
 
 	return 0;
 }
 
-static struct usb_driver ch341_driver = {
-	.name		= "ch341",
-	.probe		= usb_serial_probe,
-	.disconnect	= usb_serial_disconnect,
-	.suspend	= usb_serial_suspend,
-	.resume		= usb_serial_resume,
-	.reset_resume	= ch341_reset_resume,
-	.id_table	= id_table,
-	.supports_autosuspend =	1,
-};
-
 static struct usb_serial_driver ch341_device = {
 	.driver = {
 		.owner	= THIS_MODULE,
@@ -646,13 +607,14 @@
 	.tiocmset          = ch341_tiocmset,
 	.read_int_callback = ch341_read_int_callback,
 	.attach            = ch341_attach,
+	.reset_resume      = ch341_reset_resume,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
 	&ch341_device, NULL
 };
 
-module_usb_serial_driver(ch341_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 1ee6b2a..b9cca6d 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -113,7 +113,8 @@
 	serial = usb_serial_get_by_index(co->index);
 	if (serial == NULL) {
 		/* no device is connected yet, sorry :( */
-		err("No USB device connected to ttyUSB%i", co->index);
+		printk(KERN_ERR "No USB device connected to ttyUSB%i\n",
+		       co->index);
 		return -ENODEV;
 	}
 
@@ -137,7 +138,7 @@
 			tty = kzalloc(sizeof(*tty), GFP_KERNEL);
 			if (!tty) {
 				retval = -ENOMEM;
-				err("no more memory");
+				dev_err(&port->dev, "no more memory\n");
 				goto reset_open_count;
 			}
 			kref_init(&tty->kref);
@@ -146,7 +147,7 @@
 			tty->index = co->index;
 			if (tty_init_termios(tty)) {
 				retval = -ENOMEM;
-				err("no more memory");
+				dev_err(&port->dev, "no more memory\n");
 				goto free_tty;
 			}
 		}
@@ -159,7 +160,7 @@
 			retval = usb_serial_generic_open(NULL, port);
 
 		if (retval) {
-			err("could not open USB console port");
+			dev_err(&port->dev, "could not open USB console port\n");
 			goto fail;
 		}
 
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index ec30f95..1b19262 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -156,13 +156,6 @@
 	__u8			bInterfaceNumber;
 };
 
-static struct usb_driver cp210x_driver = {
-	.name		= "cp210x",
-	.probe		= usb_serial_probe,
-	.disconnect	= usb_serial_disconnect,
-	.id_table	= id_table,
-};
-
 static struct usb_serial_driver cp210x_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -188,8 +181,10 @@
 };
 
 /* Config request types */
-#define REQTYPE_HOST_TO_DEVICE	0x41
-#define REQTYPE_DEVICE_TO_HOST	0xc1
+#define REQTYPE_HOST_TO_INTERFACE	0x41
+#define REQTYPE_INTERFACE_TO_HOST	0xc1
+#define REQTYPE_HOST_TO_DEVICE	0x40
+#define REQTYPE_DEVICE_TO_HOST	0xc0
 
 /* Config request codes */
 #define CP210X_IFC_ENABLE	0x00
@@ -286,7 +281,7 @@
 
 	/* Issue the request, attempting to read 'size' bytes */
 	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-				request, REQTYPE_DEVICE_TO_HOST, 0x0000,
+				request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
 				port_priv->bInterfaceNumber, buf, size,
 				USB_CTRL_GET_TIMEOUT);
 
@@ -340,13 +335,13 @@
 	if (size > 2) {
 		result = usb_control_msg(serial->dev,
 				usb_sndctrlpipe(serial->dev, 0),
-				request, REQTYPE_HOST_TO_DEVICE, 0x0000,
+				request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
 				port_priv->bInterfaceNumber, buf, size,
 				USB_CTRL_SET_TIMEOUT);
 	} else {
 		result = usb_control_msg(serial->dev,
 				usb_sndctrlpipe(serial->dev, 0),
-				request, REQTYPE_HOST_TO_DEVICE, data[0],
+				request, REQTYPE_HOST_TO_INTERFACE, data[0],
 				port_priv->bInterfaceNumber, NULL, 0,
 				USB_CTRL_SET_TIMEOUT);
 	}
@@ -422,8 +417,6 @@
 {
 	int result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	result = cp210x_set_config_single(port, CP210X_IFC_ENABLE,
 								UART_ENABLE);
 	if (result) {
@@ -443,8 +436,6 @@
 
 static void cp210x_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	usb_serial_generic_close(port);
 
 	mutex_lock(&port->serial->disc_mutex);
@@ -488,8 +479,6 @@
 	unsigned int baud;
 	unsigned int bits;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4);
 
 	dbg("%s - baud rate = %d", __func__, baud);
@@ -787,8 +776,6 @@
 {
 	unsigned int control = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (set & TIOCM_RTS) {
 		control |= CONTROL_RTS;
 		control |= CONTROL_WRITE_RTS;
@@ -825,8 +812,6 @@
 	unsigned int control;
 	int result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	cp210x_get_config(port, CP210X_GET_MDMSTS, &control, 1);
 
 	result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
@@ -846,7 +831,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	unsigned int state;
 
-	dbg("%s - port %d", __func__, port->number);
 	if (break_state == 0)
 		state = BREAK_OFF;
 	else
@@ -891,7 +875,7 @@
 	}
 }
 
-module_usb_serial_driver(cp210x_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index d39b941..3aa0b53 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -77,13 +77,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver cyberjack_driver = {
-	.name =		"cyberjack",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver cyberjack_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -122,8 +115,6 @@
 	struct cyberjack_private *priv;
 	int i;
 
-	dbg("%s", __func__);
-
 	/* allocate the private data structure */
 	priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
 	if (!priv)
@@ -155,8 +146,6 @@
 {
 	int i;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i)
 		usb_kill_urb(serial->port[i]->interrupt_in_urb);
 }
@@ -165,8 +154,6 @@
 {
 	int i;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		/* My special items, the standard routines free my urbs */
 		kfree(usb_get_serial_port_data(serial->port[i]));
@@ -180,8 +167,6 @@
 	unsigned long flags;
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	dbg("%s - usb_clear_halt", __func__);
 	usb_clear_halt(port->serial->dev, port->write_urb->pipe);
 
@@ -197,8 +182,6 @@
 
 static void cyberjack_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	if (port->serial->dev) {
 		/* shutdown any bulk reads that might be going on */
 		usb_kill_urb(port->write_urb);
@@ -214,8 +197,6 @@
 	int result;
 	int wrexpected;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (count == 0) {
 		dbg("%s - write request of 0 bytes", __func__);
 		return 0;
@@ -307,8 +288,6 @@
 	int status = urb->status;
 	int result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* the urb might have been killed. */
 	if (status)
 		return;
@@ -367,8 +346,6 @@
 	int result;
 	int status = urb->status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	usb_serial_debug_data(debug, &port->dev, __func__,
 						urb->actual_length, data);
 	if (status) {
@@ -417,8 +394,6 @@
 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
 	int status = urb->status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	set_bit(0, &port->write_urbs_free);
 	if (status) {
 		dbg("%s - nonzero write bulk status received: %d",
@@ -475,7 +450,7 @@
 	usb_serial_port_softint(port);
 }
 
-module_usb_serial_driver(cyberjack_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index afc886c..b78c34e 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -89,13 +89,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver cypress_driver = {
-	.name =		"cypress",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
 enum packet_format {
 	packet_format_1,  /* b0:status, b1:payload count */
 	packet_format_2   /* b0[7:3]:status, b0[2:0]:payload count */
@@ -305,8 +298,6 @@
 	const unsigned int feature_len = 5;
 	unsigned long flags;
 
-	dbg("%s", __func__);
-
 	priv = usb_get_serial_port_data(port);
 
 	if (!priv->comm_is_ok)
@@ -451,8 +442,6 @@
 	struct cypress_private *priv;
 	struct usb_serial_port *port = serial->port[0];
 
-	dbg("%s - port %d", __func__, port->number);
-
 	priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -505,8 +494,6 @@
 	struct cypress_private *priv;
 	struct usb_serial_port *port = serial->port[0];
 
-	dbg("%s", __func__);
-
 	if (generic_startup(serial)) {
 		dbg("%s - Failed setting up port %d", __func__,
 				port->number);
@@ -537,8 +524,6 @@
 {
 	struct cypress_private *priv;
 
-	dbg("%s", __func__);
-
 	if (generic_startup(serial)) {
 		dbg("%s - Failed setting up port %d", __func__,
 				serial->port[0]->number);
@@ -556,8 +541,6 @@
 {
 	struct cypress_private *priv;
 
-	dbg("%s", __func__);
-
 	if (generic_startup(serial)) {
 		dbg("%s - Failed setting up port %d", __func__,
 				serial->port[0]->number);
@@ -575,10 +558,7 @@
 {
 	struct cypress_private *priv;
 
-	dbg("%s - port %d", __func__, serial->port[0]->number);
-
 	/* all open ports are closed at this point */
-
 	priv = usb_get_serial_port_data(serial->port[0]);
 
 	if (priv) {
@@ -595,8 +575,6 @@
 	unsigned long flags;
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (!priv->comm_is_ok)
 		return -EIO;
 
@@ -661,8 +639,6 @@
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* writing is potentially harmful, lock must be taken */
 	mutex_lock(&port->serial->disc_mutex);
 	if (port->serial->disconnected) {
@@ -720,7 +696,6 @@
 	if (!priv->comm_is_ok)
 		return;
 
-	dbg("%s - port %d", __func__, port->number);
 	dbg("%s - interrupt out size is %d", __func__,
 						port->interrupt_out_size);
 
@@ -828,8 +803,6 @@
 	int room = 0;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	room = kfifo_avail(&priv->write_fifo);
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -847,8 +820,6 @@
 	unsigned int result = 0;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	control = priv->line_control;
 	status = priv->current_status;
@@ -874,8 +845,6 @@
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	if (set & TIOCM_RTS)
 		priv->line_control |= CONTROL_RTS;
@@ -948,8 +917,6 @@
 	__u8 oldlines;
 	int linechange = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	/* We can't clean this one up as we don't know the device type
 	   early enough */
@@ -1096,8 +1063,6 @@
 	int chars = 0;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	chars = kfifo_len(&priv->write_fifo);
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -1112,8 +1077,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irq(&priv->lock);
 	priv->rx_flags = THROTTLED;
 	spin_unlock_irq(&priv->lock);
@@ -1126,8 +1089,6 @@
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	int actually_throttled, result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irq(&priv->lock);
 	actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
 	priv->rx_flags = 0;
@@ -1161,8 +1122,6 @@
 	int i = 0;
 	int status = urb->status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	switch (status) {
 	case 0: /* success */
 		break;
@@ -1303,8 +1262,6 @@
 	int result;
 	int status = urb->status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -1346,7 +1303,7 @@
 	cypress_send(port);
 }
 
-module_usb_serial_driver(cypress_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 999f91b..b5cd838 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -271,14 +271,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver digi_driver = {
-	.name =		"digi_acceleport",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
-
 /* device info needed for the Digi serial converter */
 
 static struct usb_serial_driver digi_acceleport_2_device = {
@@ -657,9 +649,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct digi_port *priv = usb_get_serial_port_data(port);
 
-
-	dbg("digi_rx_throttle: TOP: port=%d", priv->dp_port_num);
-
 	/* stop receiving characters by not resubmitting the read urb */
 	spin_lock_irqsave(&priv->dp_port_lock, flags);
 	priv->dp_throttled = 1;
@@ -675,8 +664,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct digi_port *priv = usb_get_serial_port_data(port);
 
-	dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num);
-
 	spin_lock_irqsave(&priv->dp_port_lock, flags);
 
 	/* restart read chain */
@@ -904,8 +891,6 @@
 	unsigned int val;
 	unsigned long flags;
 
-	dbg("%s: TOP: port=%d", __func__, priv->dp_port_num);
-
 	spin_lock_irqsave(&priv->dp_port_lock, flags);
 	val = priv->dp_modem_signals;
 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
@@ -921,8 +906,6 @@
 	unsigned int val;
 	unsigned long flags;
 
-	dbg("%s: TOP: port=%d", __func__, priv->dp_port_num);
-
 	spin_lock_irqsave(&priv->dp_port_lock, flags);
 	val = (priv->dp_modem_signals & ~clear) | set;
 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
@@ -1013,8 +996,6 @@
 	int ret = 0;
 	int status = urb->status;
 
-	dbg("digi_write_bulk_callback: TOP, status=%d", status);
-
 	/* port and serial sanity check */
 	if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
 		pr_err("%s: port or port->private is NULL, status=%d\n",
@@ -1121,8 +1102,6 @@
 	struct digi_port *priv = usb_get_serial_port_data(port);
 	struct ktermios not_termios;
 
-	dbg("digi_open: TOP: port=%d", priv->dp_port_num);
-
 	/* be sure the device is started up */
 	if (digi_startup_device(port->serial) != 0)
 		return -ENXIO;
@@ -1160,8 +1139,6 @@
 	unsigned char buf[32];
 	struct digi_port *priv = usb_get_serial_port_data(port);
 
-	dbg("digi_close: TOP: port=%d", priv->dp_port_num);
-
 	mutex_lock(&port->serial->disc_mutex);
 	/* if disconnected, just clear flags */
 	if (port->serial->disconnected)
@@ -1220,7 +1197,6 @@
 	wake_up_interruptible(&priv->dp_close_wait);
 	spin_unlock_irq(&priv->dp_port_lock);
 	mutex_unlock(&port->serial->disc_mutex);
-	dbg("digi_close: done");
 }
 
 
@@ -1269,8 +1245,6 @@
 	struct digi_port *priv;
 	struct digi_serial *serial_priv;
 
-	dbg("digi_startup: TOP");
-
 	/* allocate the private data structures for all ports */
 	/* number of regular ports + 1 for the out-of-band port */
 	for (i = 0; i < serial->type->num_ports + 1; i++) {
@@ -1325,7 +1299,6 @@
 static void digi_disconnect(struct usb_serial *serial)
 {
 	int i;
-	dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt());
 
 	/* stop reads and writes on all ports */
 	for (i = 0; i < serial->type->num_ports + 1; i++) {
@@ -1338,7 +1311,6 @@
 static void digi_release(struct usb_serial *serial)
 {
 	int i;
-	dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt());
 
 	/* free the private data structures for all ports */
 	/* number of regular ports + 1 for the out-of-band port */
@@ -1356,8 +1328,6 @@
 	int ret;
 	int status = urb->status;
 
-	dbg("digi_read_bulk_callback: TOP");
-
 	/* port sanity check, do not resubmit if port is not valid */
 	if (port == NULL)
 		return;
@@ -1507,9 +1477,6 @@
 	int i;
 	unsigned int rts;
 
-	dbg("digi_read_oob_callback: port=%d, len=%d",
-			priv->dp_port_num, urb->actual_length);
-
 	/* handle each oob command */
 	for (i = 0; i < urb->actual_length - 3;) {
 		opcode = ((unsigned char *)urb->transfer_buffer)[i++];
@@ -1580,7 +1547,7 @@
 
 }
 
-module_usb_serial_driver(digi_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 5b99fc0..cdf61dd 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -51,13 +51,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver empeg_driver = {
-	.name =		"empeg",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver empeg_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -80,14 +73,12 @@
 {
 	int r;
 
-	dbg("%s", __func__);
-
 	if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
 		dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
 			serial->dev->actconfig->desc.bConfigurationValue);
 		return -ENODEV;
 	}
-	dbg("%s - reset config", __func__);
+
 	r = usb_reset_configuration(serial->dev);
 
 	/* continue on with initialization */
@@ -138,7 +129,7 @@
 	tty_encode_baud_rate(tty, 115200, 115200);
 }
 
-module_usb_serial_driver(empeg_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c
index 3cfc762..800e8eb 100644
--- a/drivers/usb/serial/ezusb.c
+++ b/drivers/usb/serial/ezusb.c
@@ -26,7 +26,6 @@
 	int result;
 	unsigned char *transfer_buffer;
 
-	/* dbg("ezusb_writememory %x, %d", address, length); */
 	if (!serial->dev) {
 		printk(KERN_ERR "ezusb: %s - no physical device present, "
 		       "failing.\n", __func__);
@@ -50,7 +49,6 @@
 {
 	int response;
 
-	/* dbg("%s - %d", __func__, reset_bit); */
 	response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0);
 	if (response < 0)
 		dev_err(&serial->dev->dev, "%s- %d failed\n",
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
index 88c0b19..499b15f 100644
--- a/drivers/usb/serial/f81232.c
+++ b/drivers/usb/serial/f81232.c
@@ -68,8 +68,6 @@
 	int status = urb->status;
 	int retval;
 
-	dbg("%s (%d)", __func__, port->number);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -78,12 +76,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__,
-		    status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__,
-		    status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
@@ -133,7 +131,7 @@
 		tty_flag = TTY_PARITY;
 	else if (line_status & UART_FRAME_ERROR)
 		tty_flag = TTY_FRAME;
-	dbg("%s - tty_flag = %d", __func__, tty_flag);
+	dev_dbg(&port->dev, "%s - tty_flag = %d\n", __func__, tty_flag);
 
 	/* overrun is special, not associated with a char */
 	if (line_status & UART_OVERRUN_ERROR)
@@ -203,7 +201,6 @@
 	if (tty)
 		f81232_set_termios(tty, port, &tmp_termios);
 
-	dbg("%s - submitting interrupt urb", __func__);
 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 	if (result) {
 		dev_err(&port->dev, "%s - failed submitting interrupt urb,"
@@ -293,7 +290,9 @@
 {
 	struct serial_struct ser;
 	struct usb_serial_port *port = tty->driver_data;
-	dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
+
+	dev_dbg(&port->dev, "%s (%d) cmd = 0x%04x\n", __func__,
+		port->number, cmd);
 
 	switch (cmd) {
 	case TIOCGSERIAL:
@@ -309,10 +308,12 @@
 		return 0;
 
 	case TIOCMIWAIT:
-		dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+		dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__,
+			port->number);
 		return wait_modem_info(port, arg);
 	default:
-		dbg("%s not supported = 0x%04x", __func__, cmd);
+		dev_dbg(&port->dev, "%s not supported = 0x%04x\n",
+			__func__, cmd);
 		break;
 	}
 	return -ENOIOCTLCMD;
@@ -353,24 +354,12 @@
 	}
 }
 
-static struct usb_driver f81232_driver = {
-	.name =		"f81232",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-	.suspend =      usb_serial_suspend,
-	.resume =       usb_serial_resume,
-	.no_dynamic_id = 	1,
-	.supports_autosuspend =	1,
-};
-
 static struct usb_serial_driver f81232_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
 		.name =		"f81232",
 	},
 	.id_table =		id_table,
-	.usb_driver = 		&f81232_driver,
 	.num_ports =		1,
 	.bulk_in_size =		256,
 	.bulk_out_size =	256,
@@ -394,7 +383,7 @@
 	NULL,
 };
 
-module_usb_serial_driver(f81232_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION("Fintek F81232 USB to serial adaptor driver");
 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@linuxfoundation.org");
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 02e7f2d..8c084ea 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -809,6 +809,7 @@
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
 	{ USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
+	{ USB_DEVICE(PI_VID, PI_E861_PID) },
 	{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
 	{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
@@ -861,13 +862,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver ftdi_driver = {
-	.name =		"ftdi_sio",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
 static const char *ftdi_chip_name[] = {
 	[SIO] = "SIO",	/* the serial part of FT8U100AX */
 	[FT8U232AM] = "FT8U232AM",
@@ -1285,8 +1279,6 @@
 	unsigned char *buf;
 	int rv;
 
-	dbg("%s", __func__);
-
 	buf = kmalloc(1, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -1593,8 +1585,6 @@
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	int retval = 0;
 
-	dbg("%s", __func__);
-
 	/* XXX I've no idea if the original SIO supports the event_char
 	 * sysfs parameter, so I'm playing it safe.  */
 	if (priv->chip_type != SIO) {
@@ -1619,8 +1609,6 @@
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 
-	dbg("%s", __func__);
-
 	/* XXX see create_sysfs_attrs */
 	if (priv->chip_type != SIO) {
 		device_remove_file(&port->dev, &dev_attr_event_char);
@@ -1667,8 +1655,6 @@
 	struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
 
 
-	dbg("%s", __func__);
-
 	priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL);
 	if (!priv) {
 		dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
@@ -1704,8 +1690,6 @@
 /* Called from usbserial:serial_probe */
 static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
 {
-	dbg("%s", __func__);
-
 	priv->flags |= ASYNC_SPD_CUST;
 	priv->custom_divisor = 77;
 	priv->force_baud = 38400;
@@ -1716,8 +1700,6 @@
 
 static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
 {
-	dbg("%s", __func__);
-
 	priv->flags |= ASYNC_SPD_CUST;
 	priv->custom_divisor = 240;
 	priv->force_baud = 38400;
@@ -1767,8 +1749,6 @@
 	struct usb_device *udev = serial->dev;
 	struct usb_interface *interface = serial->interface;
 
-	dbg("%s", __func__);
-
 	if (interface == udev->actconfig->interface[0]) {
 		dev_info(&udev->dev,
 			 "Ignoring serial port reserved for JTAG\n");
@@ -1782,8 +1762,6 @@
 {
 	struct usb_device *udev = serial->dev;
 
-	dbg("%s", __func__);
-
 	if ((udev->manufacturer && !strcmp(udev->manufacturer, "CALAO Systems")) ||
 	    (udev->product && !strcmp(udev->product, "BeagleBone/XDS100")))
 		return ftdi_jtag_probe(serial);
@@ -1800,8 +1778,6 @@
 	struct usb_device *udev = serial->dev;
 	struct usb_interface *interface = serial->interface;
 
-	dbg("%s", __func__);
-
 	if (interface == udev->actconfig->interface[2])
 		return 0;
 
@@ -1839,8 +1815,6 @@
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 
-	dbg("%s", __func__);
-
 	priv->dev_gone = true;
 	wake_up_interruptible_all(&priv->delta_msr_wait);
 
@@ -1858,8 +1832,6 @@
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	int result;
 
-	dbg("%s", __func__);
-
 	/* No error checking for this (will get errors later anyway) */
 	/* See ftdi_sio.h for description of what is reset */
 	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -1918,8 +1890,6 @@
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 
-	dbg("%s", __func__);
-
 	usb_serial_generic_close(port);
 	kref_put(&priv->kref, ftdi_sio_priv_release);
 }
@@ -1976,8 +1946,6 @@
 	char flag;
 	char *ch;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (len < 2) {
 		dbg("malformed packet");
 		return 0;
@@ -2121,8 +2089,6 @@
 	unsigned char vstop;
 	unsigned char vstart;
 
-	dbg("%s", __func__);
-
 	/* Force baud rate if this device requires it, unless it is set to
 	   B0. */
 	if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) {
@@ -2295,8 +2261,6 @@
 	int len;
 	int ret;
 
-	dbg("%s TIOCMGET", __func__);
-
 	buf = kmalloc(2, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
@@ -2346,7 +2310,7 @@
 			unsigned int set, unsigned int clear)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	dbg("%s TIOCMSET", __func__);
+
 	return update_mctrl(port, set, clear);
 }
 
@@ -2435,7 +2399,6 @@
 {
 	int retval;
 
-	dbg("%s", __func__);
 	if (vendor > 0 && product > 0) {
 		/* Add user specified VID/PID to reserved element of table. */
 		int i;
@@ -2445,7 +2408,7 @@
 		id_table_combined[i].idVendor = vendor;
 		id_table_combined[i].idProduct = product;
 	}
-	retval = usb_serial_register_drivers(&ftdi_driver, serial_drivers);
+	retval = usb_serial_register_drivers(serial_drivers, KBUILD_MODNAME, id_table_combined);
 	if (retval == 0)
 		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
 			       DRIVER_DESC "\n");
@@ -2454,9 +2417,7 @@
 
 static void __exit ftdi_exit(void)
 {
-	dbg("%s", __func__);
-
-	usb_serial_deregister_drivers(&ftdi_driver, serial_drivers);
+	usb_serial_deregister_drivers(serial_drivers);
 }
 
 
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 0838baf8..f3c7c78 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -785,6 +785,14 @@
 #define RTSYSTEMS_SERIAL_VX7_PID	0x9e52	/* Serial converter for VX-7 Radios using FT232RL */
 #define RTSYSTEMS_CT29B_PID		0x9e54	/* CT29B Radio Cable */
 
+
+/*
+ * Physik Instrumente
+ * http://www.physikinstrumente.com/en/products/
+ */
+#define PI_VID              0x1a72  /* Vendor ID */
+#define PI_E861_PID         0x1008  /* E-861 piezo controller USB connection */
+
 /*
  * Bayer Ascensia Contour blood glucose meter USB-converter cable.
  * http://winglucofacts.com/cables/
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c
index 4577b36..2357079 100644
--- a/drivers/usb/serial/funsoft.c
+++ b/drivers/usb/serial/funsoft.c
@@ -24,13 +24,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver funsoft_driver = {
-	.name =		"funsoft",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver funsoft_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -44,7 +37,7 @@
 	&funsoft_device, NULL
 };
 
-module_usb_serial_driver(funsoft_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index e8eb634..346c15a 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -216,16 +216,8 @@
 	{ USB_DEVICE(GARMIN_VENDOR_ID, 3) },
 	{ }					/* Terminating entry */
 };
-
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver garmin_driver = {
-	.name =		"garmin_gps",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 
 static inline int getLayerId(const __u8 *usbPacket)
 {
@@ -345,8 +337,6 @@
 	unsigned long flags;
 	struct garmin_packet *result = NULL;
 
-	dbg("%s", __func__);
-
 	spin_lock_irqsave(&garmin_data_p->lock, flags);
 	while (!list_empty(&garmin_data_p->pktlist)) {
 		result = (struct garmin_packet *)garmin_data_p->pktlist.next;
@@ -939,8 +929,6 @@
 	int status = 0;
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&garmin_data_p->lock, flags);
 	garmin_data_p->mode  = initial_mode;
 	garmin_data_p->count = 0;
@@ -996,8 +984,6 @@
 		struct garmin_data *garmin_data_p =
 					usb_get_serial_port_data(port);
 
-		dbg("%s - port %d", __func__, port->number);
-
 		if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)) {
 
 			if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
@@ -1027,9 +1013,6 @@
 	unsigned char *buffer;
 	int status;
 
-	dbg("%s - port %d, state %d", __func__, port->number,
-		garmin_data_p->state);
-
 	spin_lock_irqsave(&garmin_data_p->lock, flags);
 	garmin_data_p->flags &= ~FLAGS_DROP_DATA;
 	spin_unlock_irqrestore(&garmin_data_p->lock, flags);
@@ -1224,8 +1207,6 @@
 	int status = urb->status;
 	int retval;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (!serial) {
 		dbg("%s - bad serial pointer, exiting", __func__);
 		return;
@@ -1384,7 +1365,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
-	dbg("%s - port %d", __func__, port->number);
 	/* set flag, data received will be put into a queue
 	   for later processing */
 	spin_lock_irq(&garmin_data_p->lock);
@@ -1399,7 +1379,6 @@
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 	int status;
 
-	dbg("%s - port %d", __func__, port->number);
 	spin_lock_irq(&garmin_data_p->lock);
 	garmin_data_p->flags &= ~FLAGS_THROTTLED;
 	spin_unlock_irq(&garmin_data_p->lock);
@@ -1441,8 +1420,6 @@
 	struct usb_serial_port *port = serial->port[0];
 	struct garmin_data *garmin_data_p = NULL;
 
-	dbg("%s", __func__);
-
 	garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);
 	if (garmin_data_p == NULL) {
 		dev_err(&port->dev, "%s - Out of memory\n", __func__);
@@ -1471,8 +1448,6 @@
 	struct usb_serial_port *port = serial->port[0];
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
-	dbg("%s", __func__);
-
 	usb_kill_urb(port->interrupt_in_urb);
 	del_timer_sync(&garmin_data_p->timer);
 }
@@ -1483,8 +1458,6 @@
 	struct usb_serial_port *port = serial->port[0];
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
-	dbg("%s", __func__);
-
 	kfree(garmin_data_p);
 }
 
@@ -1516,7 +1489,7 @@
 	&garmin_device, NULL
 };
 
-module_usb_serial_driver(garmin_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 664deb6..105a6d8 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -28,9 +28,6 @@
 
 #ifdef CONFIG_USB_SERIAL_GENERIC
 
-static int generic_probe(struct usb_interface *interface,
-			 const struct usb_device_id *id);
-
 static __u16 vendor  = 0x05f9;
 static __u16 product = 0xffff;
 
@@ -49,13 +46,6 @@
 	{}
 };
 
-static struct usb_driver generic_driver = {
-	.name =		"usbserial_generic",
-	.probe =	generic_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	generic_serial_ids,
-};
-
 /* All of the device info needed for the Generic Serial Converter */
 struct usb_serial_driver usb_serial_generic_device = {
 	.driver = {
@@ -75,16 +65,6 @@
 	&usb_serial_generic_device, NULL
 };
 
-static int generic_probe(struct usb_interface *interface,
-			       const struct usb_device_id *id)
-{
-	const struct usb_device_id *id_pattern;
-
-	id_pattern = usb_match_id(interface, generic_device_ids);
-	if (id_pattern != NULL)
-		return usb_serial_probe(interface, id);
-	return -ENODEV;
-}
 #endif
 
 int usb_serial_generic_register(int _debug)
@@ -99,7 +79,7 @@
 		USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
 
 	/* register our generic driver with ourselves */
-	retval = usb_serial_register_drivers(&generic_driver, serial_drivers);
+	retval = usb_serial_register_drivers(serial_drivers, "usbserial_generic", generic_serial_ids);
 #endif
 	return retval;
 }
@@ -108,7 +88,7 @@
 {
 #ifdef CONFIG_USB_SERIAL_GENERIC
 	/* remove our generic driver */
-	usb_serial_deregister_drivers(&generic_driver, serial_drivers);
+	usb_serial_deregister_drivers(serial_drivers);
 #endif
 }
 
@@ -117,8 +97,6 @@
 	int result = 0;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* clear the throttle flags */
 	spin_lock_irqsave(&port->lock, flags);
 	port->throttled = 0;
@@ -139,12 +117,9 @@
 	unsigned long flags;
 	int i;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (serial->dev) {
 		/* shutdown any bulk transfers that might be going on */
 		if (port->bulk_out_size) {
-			usb_kill_urb(port->write_urb);
 			for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
 				usb_kill_urb(port->write_urbs[i]);
 
@@ -161,7 +136,6 @@
 
 void usb_serial_generic_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
 	generic_cleanup(port);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_close);
@@ -249,8 +223,6 @@
 {
 	int result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* only do something if we have a bulk out endpoint */
 	if (!port->bulk_out_size)
 		return -ENODEV;
@@ -273,8 +245,6 @@
 	unsigned long flags;
 	int room;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (!port->bulk_out_size)
 		return 0;
 
@@ -282,7 +252,7 @@
 	room = kfifo_avail(&port->write_fifo);
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	dbg("%s - returns %d", __func__, room);
+	dev_dbg(&port->dev, "%s - returns %d\n", __func__, room);
 	return room;
 }
 
@@ -292,8 +262,6 @@
 	unsigned long flags;
 	int chars;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (!port->bulk_out_size)
 		return 0;
 
@@ -301,7 +269,7 @@
 	chars = kfifo_len(&port->write_fifo) + port->tx_bytes;
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	dbg("%s - returns %d", __func__, chars);
+	dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
 	return chars;
 }
 
@@ -313,7 +281,8 @@
 	if (!test_and_clear_bit(index, &port->read_urbs_free))
 		return 0;
 
-	dbg("%s - port %d, urb %d\n", __func__, port->number, index);
+	dev_dbg(&port->dev, "%s - port %d, urb %d\n", __func__,
+		port->number, index);
 
 	res = usb_submit_urb(port->read_urbs[index], mem_flags);
 	if (res) {
@@ -335,8 +304,6 @@
 	int res;
 	int i;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) {
 		res = usb_serial_generic_submit_read_urb(port, i, mem_flags);
 		if (res)
@@ -395,10 +362,12 @@
 	}
 	set_bit(i, &port->read_urbs_free);
 
-	dbg("%s - port %d, urb %d, len %d\n", __func__, port->number, i,
-							urb->actual_length);
+	dev_dbg(&port->dev, "%s - port %d, urb %d, len %d\n",
+		__func__, port->number, i, urb->actual_length);
+
 	if (urb->status) {
-		dbg("%s - non-zero urb status: %d\n", __func__, urb->status);
+		dev_dbg(&port->dev, "%s - non-zero urb status: %d\n",
+			__func__, urb->status);
 		return;
 	}
 
@@ -424,8 +393,6 @@
 	int status = urb->status;
 	int i;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
 		if (port->write_urbs[i] == urb)
 			break;
@@ -436,7 +403,8 @@
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	if (status) {
-		dbg("%s - non-zero urb status: %d", __func__, status);
+		dev_dbg(&port->dev, "%s - non-zero urb status: %d\n",
+			__func__, status);
 
 		spin_lock_irqsave(&port->lock, flags);
 		kfifo_reset_out(&port->write_fifo);
@@ -454,8 +422,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* Set the throttle request flag. It will be picked up
 	 * by usb_serial_generic_read_bulk_callback(). */
 	spin_lock_irqsave(&port->lock, flags);
@@ -469,8 +435,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int was_throttled;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* Clear the throttle flags */
 	spin_lock_irq(&port->lock);
 	was_throttled = port->throttled;
@@ -525,7 +489,8 @@
 {
 	struct tty_port *port = &usb_port->port;
 
-	dbg("%s - port %d, status %d", __func__, usb_port->number, status);
+	dev_dbg(&usb_port->dev, "%s - port %d, status %d\n", __func__,
+		usb_port->number, status);
 
 	if (status)
 		wake_up_interruptible(&port->open_wait);
@@ -566,8 +531,6 @@
 {
 	int i;
 
-	dbg("%s", __func__);
-
 	/* stop reads and writes on all ports */
 	for (i = 0; i < serial->num_ports; ++i)
 		generic_cleanup(serial->port[i]);
@@ -576,5 +539,4 @@
 
 void usb_serial_generic_release(struct usb_serial *serial)
 {
-	dbg("%s", __func__);
 }
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index 2563e78..0bbaf21 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -36,13 +36,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver hp49gp_driver = {
-	.name =		"hp4X",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver hp49gp_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -56,7 +49,7 @@
 	&hp49gp_device, NULL
 };
 
-module_usb_serial_driver(hp49gp_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 323e872..e1f5ccd 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -3181,7 +3181,7 @@
 	kfree(edge_serial);
 }
 
-module_usb_serial_driver(io_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h
index d0e7c9a..350afdd 100644
--- a/drivers/usb/serial/io_tables.h
+++ b/drivers/usb/serial/io_tables.h
@@ -95,13 +95,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver io_driver = {
-	.name =		"io_edgeport",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
 static struct usb_serial_driver edgeport_2port_device = {
 	.driver = {
 		.owner		= THIS_MODULE,
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 40a95a7..3936904 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -197,14 +197,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver io_driver = {
-	.name =		"io_ti",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
-
 static unsigned char OperationalMajorVersion;
 static unsigned char OperationalMinorVersion;
 static unsigned short OperationalBuildNumber;
@@ -547,6 +539,7 @@
 {
 	int baud_rate;
 	struct tty_struct *tty = tty_port_tty_get(&port->port->port);
+	struct usb_serial *serial = port->port->serial;
 	wait_queue_t wait;
 	unsigned long flags;
 
@@ -561,7 +554,7 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (kfifo_len(&port->write_fifo) == 0
 		|| timeout == 0 || signal_pending(current)
-		|| !usb_get_intfdata(port->port->serial->interface))
+		|| serial->disconnected)
 			/* disconnect */
 			break;
 		spin_unlock_irqrestore(&port->ep_lock, flags);
@@ -578,7 +571,7 @@
 	/* wait for data to drain from the device */
 	timeout += jiffies;
 	while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
-	&& usb_get_intfdata(port->port->serial->interface)) {
+						&& !serial->disconnected) {
 		/* not disconnected */
 		if (!tx_active(port))
 			break;
@@ -586,7 +579,7 @@
 	}
 
 	/* disconnected */
-	if (!usb_get_intfdata(port->port->serial->interface))
+	if (serial->disconnected)
 		return;
 
 	/* wait one more character time, based on baud rate */
@@ -2003,8 +1996,8 @@
 {
 	struct edgeport_serial *edge_serial;
 	struct edgeport_port *edge_port;
+	struct usb_serial *serial = port->serial;
 	int port_number;
-	int status;
 
 	dbg("%s - port %d", __func__, port->number);
 
@@ -2028,12 +2021,18 @@
 	 * send a close port command to it */
 	dbg("%s - send umpc_close_port", __func__);
 	port_number = port->number - port->serial->minor;
-	status = send_cmd(port->serial->dev,
+
+	mutex_lock(&serial->disc_mutex);
+	if (!serial->disconnected) {
+		send_cmd(serial->dev,
 				     UMPC_CLOSE_PORT,
 				     (__u8)(UMPM_UART1_PORT + port_number),
 				     0,
 				     NULL,
 				     0);
+	}
+	mutex_unlock(&serial->disc_mutex);
+
 	mutex_lock(&edge_serial->es_lock);
 	--edge_port->edge_serial->num_ports_open;
 	if (edge_port->edge_serial->num_ports_open <= 0) {
@@ -2783,7 +2782,7 @@
 	&edgeport_1port_device, &edgeport_2port_device, NULL
 };
 
-module_usb_serial_driver(io_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 10c02b8..c85a7eb 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -33,7 +33,6 @@
 #define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
 #define DRIVER_DESC "USB PocketPC PDA driver"
 
-static __u16 product, vendor;
 static bool debug;
 static int connect_retries = KP_RETRIES;
 static int initial_wait;
@@ -45,8 +44,6 @@
 static int  ipaq_startup(struct usb_serial *serial);
 
 static struct usb_device_id ipaq_id_table [] = {
-	/* The first entry is a placeholder for the insmod-specified device */
-	{ USB_DEVICE(0x049F, 0x0003) },
 	{ USB_DEVICE(0x0104, 0x00BE) }, /* Socket USB Sync */
 	{ USB_DEVICE(0x03F0, 0x1016) }, /* HP USB Sync */
 	{ USB_DEVICE(0x03F0, 0x1116) }, /* HP USB Sync 1611 */
@@ -505,13 +502,6 @@
 
 MODULE_DEVICE_TABLE(usb, ipaq_id_table);
 
-static struct usb_driver ipaq_driver = {
-	.name =		"ipaq",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	ipaq_id_table,
-};
-
 
 /* All of the device info needed for the Compaq iPAQ */
 static struct usb_serial_driver ipaq_device = {
@@ -539,8 +529,6 @@
 	int			result = 0;
 	int			retries = connect_retries;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	msleep(1000*initial_wait);
 
 	/*
@@ -577,7 +565,7 @@
 	 */
 	int ipaq_num_ports = 1;
 
-	dbg("%s - numberofendpoints: %d", __FUNCTION__,
+	dev_dbg(&serial->dev->dev, "%s - numberofendpoints: %d\n", __func__,
 		(int)serial->interface->cur_altsetting->desc.bNumEndpoints);
 
 	/*
@@ -596,8 +584,6 @@
 
 static int ipaq_startup(struct usb_serial *serial)
 {
-	dbg("%s", __func__);
-
 	/* Some of the devices in ipaq_id_table[] are composite, and we
 	 * shouldn't bind to all the interfaces.  This test will rule out
 	 * some obviously invalid possibilities.
@@ -617,36 +603,14 @@
 		return -ENODEV;
 	}
 
-	dbg("%s - iPAQ module configured for %d ports",
-		__FUNCTION__, serial->num_ports);
+	dev_dbg(&serial->dev->dev,
+		"%s - iPAQ module configured for %d ports\n", __func__,
+		serial->num_ports);
 
 	return usb_reset_configuration(serial->dev);
 }
 
-static int __init ipaq_init(void)
-{
-	int retval;
-
-	if (vendor) {
-		ipaq_id_table[0].idVendor = vendor;
-		ipaq_id_table[0].idProduct = product;
-	}
-
-	retval = usb_serial_register_drivers(&ipaq_driver, serial_drivers);
-	if (retval == 0)
-		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-			       DRIVER_DESC "\n");
-	return retval;
-}
-
-static void __exit ipaq_exit(void)
-{
-	usb_serial_deregister_drivers(&ipaq_driver, serial_drivers);
-}
-
-
-module_init(ipaq_init);
-module_exit(ipaq_exit);
+module_usb_serial_driver(serial_drivers, ipaq_id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -655,12 +619,6 @@
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
-module_param(vendor, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified USB idVendor");
-
-module_param(product, ushort, 0);
-MODULE_PARM_DESC(product, "User specified USB idProduct");
-
 module_param(connect_retries, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(connect_retries,
 		"Maximum number of connect retries (one second each)");
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 76a0640..5811d34 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -132,19 +132,11 @@
 
 #define IPW_WANTS_TO_SEND	0x30
 
-static const struct usb_device_id usb_ipw_ids[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(IPW_VID, IPW_PID) },
 	{ },
 };
-
-MODULE_DEVICE_TABLE(usb, usb_ipw_ids);
-
-static struct usb_driver usb_ipw_driver = {
-	.name =		"ipwtty",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	usb_ipw_ids,
-};
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static bool debug;
 
@@ -155,8 +147,6 @@
 	u8 *buf_flow_init;
 	int result;
 
-	dbg("%s", __func__);
-
 	buf_flow_init = kmemdup(buf_flow_static, 16, GFP_KERNEL);
 	if (!buf_flow_init)
 		return -ENOMEM;
@@ -317,7 +307,7 @@
 		.name =		"ipw",
 	},
 	.description =		"IPWireless converter",
-	.id_table =		usb_ipw_ids,
+	.id_table =		id_table,
 	.num_ports =		1,
 	.disconnect =		usb_wwan_disconnect,
 	.open =			ipw_open,
@@ -333,7 +323,7 @@
 	&ipw_device, NULL
 };
 
-module_usb_serial_driver(usb_ipw_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 /* Module information */
 MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 84965cd..fc09414 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -77,13 +77,6 @@
 
 MODULE_DEVICE_TABLE(usb, ir_id_table);
 
-static struct usb_driver ir_driver = {
-	.name		= "ir-usb",
-	.probe		= usb_serial_probe,
-	.disconnect	= usb_serial_disconnect,
-	.id_table	= ir_id_table,
-};
-
 static struct usb_serial_driver ir_device = {
 	.driver	= {
 		.owner	= THIS_MODULE,
@@ -103,18 +96,21 @@
 	&ir_device, NULL
 };
 
-static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc)
+static inline void irda_usb_dump_class_desc(struct usb_serial *serial,
+					    struct usb_irda_cs_descriptor *desc)
 {
-	dbg("bLength=%x", desc->bLength);
-	dbg("bDescriptorType=%x", desc->bDescriptorType);
-	dbg("bcdSpecRevision=%x", __le16_to_cpu(desc->bcdSpecRevision));
-	dbg("bmDataSize=%x", desc->bmDataSize);
-	dbg("bmWindowSize=%x", desc->bmWindowSize);
-	dbg("bmMinTurnaroundTime=%d", desc->bmMinTurnaroundTime);
-	dbg("wBaudRate=%x", __le16_to_cpu(desc->wBaudRate));
-	dbg("bmAdditionalBOFs=%x", desc->bmAdditionalBOFs);
-	dbg("bIrdaRateSniff=%x", desc->bIrdaRateSniff);
-	dbg("bMaxUnicastList=%x", desc->bMaxUnicastList);
+	struct device *dev = &serial->dev->dev;
+
+	dev_dbg(dev, "bLength=%x\n", desc->bLength);
+	dev_dbg(dev, "bDescriptorType=%x\n", desc->bDescriptorType);
+	dev_dbg(dev, "bcdSpecRevision=%x\n", __le16_to_cpu(desc->bcdSpecRevision));
+	dev_dbg(dev, "bmDataSize=%x\n", desc->bmDataSize);
+	dev_dbg(dev, "bmWindowSize=%x\n", desc->bmWindowSize);
+	dev_dbg(dev, "bmMinTurnaroundTime=%d\n", desc->bmMinTurnaroundTime);
+	dev_dbg(dev, "wBaudRate=%x\n", __le16_to_cpu(desc->wBaudRate));
+	dev_dbg(dev, "bmAdditionalBOFs=%x\n", desc->bmAdditionalBOFs);
+	dev_dbg(dev, "bIrdaRateSniff=%x\n", desc->bIrdaRateSniff);
+	dev_dbg(dev, "bMaxUnicastList=%x\n", desc->bMaxUnicastList);
 }
 
 /*------------------------------------------------------------------*/
@@ -130,8 +126,9 @@
  * Based on the same function in drivers/net/irda/irda-usb.c
  */
 static struct usb_irda_cs_descriptor *
-irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
+irda_usb_find_class_desc(struct usb_serial *serial, unsigned int ifnum)
 {
+	struct usb_device *dev = serial->dev;
 	struct usb_irda_cs_descriptor *desc;
 	int ret;
 
@@ -144,20 +141,20 @@
 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 			0, ifnum, desc, sizeof(*desc), 1000);
 
-	dbg("%s -  ret=%d", __func__, ret);
+	dev_dbg(&serial->dev->dev, "%s -  ret=%d\n", __func__, ret);
 	if (ret < sizeof(*desc)) {
-		dbg("%s - class descriptor read %s (%d)",
-				__func__,
-				(ret < 0) ? "failed" : "too short",
-				ret);
+		dev_dbg(&serial->dev->dev,
+			"%s - class descriptor read %s (%d)\n", __func__,
+			(ret < 0) ? "failed" : "too short", ret);
 		goto error;
 	}
 	if (desc->bDescriptorType != USB_DT_CS_IRDA) {
-		dbg("%s - bad class descriptor type", __func__);
+		dev_dbg(&serial->dev->dev, "%s - bad class descriptor type\n",
+			__func__);
 		goto error;
 	}
 
-	irda_usb_dump_class_desc(desc);
+	irda_usb_dump_class_desc(serial, desc);
 	return desc;
 
 error:
@@ -207,14 +204,15 @@
 {
 	struct usb_irda_cs_descriptor *irda_desc;
 
-	irda_desc = irda_usb_find_class_desc(serial->dev, 0);
+	irda_desc = irda_usb_find_class_desc(serial, 0);
 	if (!irda_desc) {
 		dev_err(&serial->dev->dev,
 			"IRDA class descriptor not found, device not bound\n");
 		return -ENODEV;
 	}
 
-	dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
+	dev_dbg(&serial->dev->dev,
+		"%s - Baud rates supported:%s%s%s%s%s%s%s%s%s\n",
 		__func__,
 		(irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "",
 		(irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "",
@@ -264,8 +262,6 @@
 {
 	int i;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
 		port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET;
 
@@ -322,15 +318,11 @@
 
 static void ir_set_termios_callback(struct urb *urb)
 {
-	struct usb_serial_port *port = urb->context;
-	int status = urb->status;
-
-	dbg("%s - port %d", __func__, port->number);
-
 	kfree(urb->transfer_buffer);
 
-	if (status)
-		dbg("%s - non-zero urb status: %d", __func__, status);
+	if (urb->status)
+		dev_dbg(&urb->dev->dev, "%s - non-zero urb status: %d\n",
+			__func__, urb->status);
 }
 
 static void ir_set_termios(struct tty_struct *tty,
@@ -342,8 +334,6 @@
 	speed_t baud;
 	int ir_baud;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	baud = tty_get_baud_rate(tty);
 
 	/*
@@ -447,7 +437,7 @@
 		ir_device.bulk_out_size = buffer_size;
 	}
 
-	retval = usb_serial_register_drivers(&ir_driver, serial_drivers);
+	retval = usb_serial_register_drivers(serial_drivers, KBUILD_MODNAME, ir_id_table);
 	if (retval == 0)
 		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
 			       DRIVER_DESC "\n");
@@ -456,7 +446,7 @@
 
 static void __exit ir_exit(void)
 {
-	usb_serial_deregister_drivers(&ir_driver, serial_drivers);
+	usb_serial_deregister_drivers(serial_drivers);
 }
 
 
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index f2192d5..22b1eb5 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -51,13 +51,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver iuu_driver = {
-	.name = "iuu_phoenix",
-	.probe = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-	.id_table = id_table,
-};
-
 /* turbo parameter */
 static int boost = 100;
 static int clockmode = 1;
@@ -135,8 +128,6 @@
 	if (!port)
 		return;
 
-	dbg("%s", __func__);
-
 	if (priv) {
 		iuu_free_buf(priv);
 		dbg("%s - I will free all", __func__);
@@ -198,8 +189,6 @@
 	int result;
 	int status = urb->status;
 
-	dbg("%s - enter", __func__);
-
 	if (status) {
 		dbg("%s - status = %d", __func__, status);
 		/* error stop all */
@@ -221,7 +210,6 @@
 	struct iuu_private *priv = usb_get_serial_port_data(port);
 	int result;
 	char *buf_ptr = port->write_urb->transfer_buffer;
-	dbg("%s - enter", __func__);
 
 	/* Prepare the reset sequence */
 
@@ -255,8 +243,6 @@
 	u8 *st;
 	int status = urb->status;
 
-	dbg("%s - enter", __func__);
-
 	if (status) {
 		dbg("%s - status = %d", __func__, status);
 		/* error stop all */
@@ -299,8 +285,6 @@
 {
 	int result;
 
-	dbg("%s - enter", __func__);
-
 	memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1);
 	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
 			  usb_sndbulkpipe(port->serial->dev,
@@ -318,8 +302,6 @@
 	struct usb_serial *serial = port->serial;
 	int actual = 0;
 
-	dbg("%s - enter", __func__);
-
 	/* send the data out the bulk port */
 
 	status =
@@ -341,10 +323,7 @@
 	struct usb_serial *serial = port->serial;
 	int actual = 0;
 
-	dbg("%s - enter", __func__);
-
 	/* send the data out the bulk port */
-
 	status =
 	    usb_bulk_msg(serial->dev,
 			 usb_rcvbulkpipe(serial->dev,
@@ -367,8 +346,6 @@
 	if (!buf)
 		return -ENOMEM;
 
-	dbg("%s - enter", __func__);
-
 	buf[0] = IUU_SET_LED;
 	buf[1] = R & 0xFF;
 	buf[2] = (R >> 8) & 0xFF;
@@ -460,8 +437,6 @@
 	unsigned int P2 = 0;
 	int frq = (int)dwFrq;
 
-	dbg("%s - enter", __func__);
-
 	if (frq == 0) {
 		priv->buf[Count++] = IUU_UART_WRITE_I2C;
 		priv->buf[Count++] = FrqGenAdr << 1;
@@ -590,8 +565,6 @@
 	u8 rxcmd = IUU_UART_RX;
 	struct iuu_private *priv = usb_get_serial_port_data(port);
 
-	dbg("%s - enter", __func__);
-
 	if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
 		return -EIO;
 
@@ -630,8 +603,6 @@
 	struct tty_struct *tty;
 	int status = urb->status;
 
-	dbg("%s - status = %d", __func__, status);
-
 	if (status) {
 		if (status == -EPROTO) {
 			/* reschedule needed */
@@ -659,7 +630,6 @@
 	int i;
 	int buf_len;
 	char *buf_ptr = port->write_urb->transfer_buffer;
-	dbg("%s - enter", __func__);
 
 	spin_lock_irqsave(&priv->lock, flags);
 	*buf_ptr++ = IUU_UART_ESC;
@@ -691,7 +661,6 @@
 static int iuu_read_buf(struct usb_serial_port *port, int len)
 {
 	int result;
-	dbg("%s - enter", __func__);
 
 	usb_fill_bulk_urb(port->read_urb, port->serial->dev,
 			  usb_rcvbulkpipe(port->serial->dev,
@@ -713,8 +682,6 @@
 	unsigned char *data = urb->transfer_buffer;
 	priv->poll++;
 
-	dbg("%s - enter", __func__);
-
 	if (status) {
 		dbg("%s - status = %d", __func__, status);
 		/* error stop all */
@@ -771,7 +738,6 @@
 {
 	struct iuu_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
-	dbg("%s - enter", __func__);
 
 	if (count > 256)
 		return -ENOMEM;
@@ -792,8 +758,6 @@
 	int result;
 	int status = urb->status;
 
-	dbg("%s - status = %d", __func__, status);
-
 	if (status) {
 		/* error stop all */
 		return;
@@ -1015,8 +979,6 @@
 	if (!serial)
 		return;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	iuu_uart_off(port);
 	if (serial->dev) {
 		/* free writebuf */
@@ -1031,7 +993,6 @@
 
 static void iuu_init_termios(struct tty_struct *tty)
 {
-	dbg("%s - enter", __func__);
 	*(tty->termios) = tty_std_termios;
 	tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
 				| TIOCM_CTS | CSTOPB | PARENB;
@@ -1188,8 +1149,6 @@
 	if (!buf)
 		return -ENOMEM;
 
-	dbg("%s - enter", __func__);
-
 	buf[0] = IUU_SET_VCC;
 	buf[1] = vcc & 0xFF;
 	buf[2] = (vcc >> 8) & 0xFF;
@@ -1250,15 +1209,11 @@
 
 static int iuu_create_sysfs_attrs(struct usb_serial_port *port)
 {
-	dbg("%s", __func__);
-
 	return device_create_file(&port->dev, &dev_attr_vcc_mode);
 }
 
 static int iuu_remove_sysfs_attrs(struct usb_serial_port *port)
 {
-	dbg("%s", __func__);
-
 	device_remove_file(&port->dev, &dev_attr_vcc_mode);
 	return 0;
 }
@@ -1294,7 +1249,7 @@
 	&iuu_device, NULL
 };
 
-module_usb_serial_driver(iuu_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR("Alain Degreffe eczema@ecze.com");
 
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index a39ddd1..a1b9924 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -130,15 +130,13 @@
 #include "keyspan_usa67msg.h"
 
 
-module_usb_serial_driver(keyspan_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, keyspan_ids_combined);
 
 static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
 {
 	struct usb_serial_port *port = tty->driver_data;
 	struct keyspan_port_private 	*p_priv;
 
-	dbg("%s", __func__);
-
 	p_priv = usb_get_serial_port_data(port);
 
 	if (break_state == -1)
@@ -158,8 +156,6 @@
 	const struct keyspan_device_details	*d_details;
 	unsigned int 			cflag;
 
-	dbg("%s", __func__);
-
 	p_priv = usb_get_serial_port_data(port);
 	d_details = p_priv->device_details;
 	cflag = tty->termios->c_cflag;
@@ -306,8 +302,6 @@
 	unsigned char 		*data = urb->transfer_buffer;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (status) {
@@ -369,8 +363,6 @@
 
 static void	usa26_inack_callback(struct urb *urb)
 {
-	dbg("%s", __func__);
-
 }
 
 static void	usa26_outcont_callback(struct urb *urb)
@@ -452,7 +444,6 @@
 
 static void	usa26_glocont_callback(struct urb *urb)
 {
-	dbg("%s", __func__);
 }
 
 
@@ -465,8 +456,6 @@
 	struct keyspan_port_private             *p_priv;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	port =  urb->context;
 	p_priv = usb_get_serial_port_data(port);
 	data = urb->transfer_buffer;
@@ -505,7 +494,6 @@
 
 static void	usa28_inack_callback(struct urb *urb)
 {
-	dbg("%s", __func__);
 }
 
 static void	usa28_outcont_callback(struct urb *urb)
@@ -585,7 +573,6 @@
 
 static void	usa28_glocont_callback(struct urb *urb)
 {
-	dbg("%s", __func__);
 }
 
 
@@ -596,8 +583,6 @@
 	struct keyspan_port_private *p_priv;
 	int i;
 
-	dbg("%s", __func__);
-
 	serial =  urb->context;
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
@@ -625,8 +610,6 @@
 	int old_dcd_state;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	serial =  urb->context;
 
 	if (status) {
@@ -679,7 +662,6 @@
 
 static void	usa49_inack_callback(struct urb *urb)
 {
-	dbg("%s", __func__);
 }
 
 static void	usa49_indat_callback(struct urb *urb)
@@ -691,8 +673,6 @@
 	unsigned char 		*data = urb->transfer_buffer;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (status) {
@@ -742,8 +722,6 @@
 	unsigned char 		*data = urb->transfer_buffer;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	serial = urb->context;
 
 	if (status) {
@@ -806,7 +784,6 @@
 /* not used, usa-49 doesn't have per-port control endpoints */
 static void usa49_outcont_callback(struct urb *urb)
 {
-	dbg("%s", __func__);
 }
 
 static void usa90_indat_callback(struct urb *urb)
@@ -819,8 +796,6 @@
 	unsigned char 		*data = urb->transfer_buffer;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (status) {
@@ -957,8 +932,6 @@
 	int old_dcd_state;
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	serial = urb->context;
 
 	if (status) {
@@ -1010,8 +983,6 @@
 	struct keyspan_port_private *p_priv;
 	int i;
 
-	dbg("%s", __func__);
-
 	serial = urb->context;
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
@@ -1035,7 +1006,6 @@
 	int				data_len;
 	struct urb			*this_urb;
 
-	dbg("%s", __func__);
 	p_priv = usb_get_serial_port_data(port);
 	d_details = p_priv->device_details;
 
@@ -1078,8 +1048,6 @@
 	p_priv = usb_get_serial_port_data(port);
 	d_details = p_priv->device_details;
 
-	dbg("%s - port%d.", __func__, port->number);
-
 	/* Set some sane defaults */
 	p_priv->rts_state = 1;
 	p_priv->dtr_state = 1;
@@ -1165,7 +1133,6 @@
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private 	*p_priv;
 
-	dbg("%s", __func__);
 	s_priv = usb_get_serial_data(serial);
 	p_priv = usb_get_serial_port_data(port);
 
@@ -1438,8 +1405,6 @@
 	struct callbacks		*cback;
 	int				endp;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 	d_details = s_priv->device_details;
 
@@ -1853,8 +1818,6 @@
 	struct urb				*this_urb;
 	int 					device_port, err;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 	p_priv = usb_get_serial_port_data(port);
 	d_details = s_priv->device_details;
@@ -1980,8 +1943,6 @@
 	struct urb				*this_urb;
 	int 					err, device_port;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 	p_priv = usb_get_serial_port_data(port);
 	d_details = s_priv->device_details;
@@ -2168,8 +2129,6 @@
 	int 					err;
 	u8						prescaler;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 	p_priv = usb_get_serial_port_data(port);
 	d_details = s_priv->device_details;
@@ -2300,8 +2259,6 @@
 	struct urb				*this_urb;
 	int 					err, device_port;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 	p_priv = usb_get_serial_port_data(port);
 	d_details = s_priv->device_details;
@@ -2442,8 +2399,6 @@
 	struct keyspan_serial_private *s_priv;
 	const struct keyspan_device_details *d_details;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 	d_details = s_priv->device_details;
 
@@ -2477,8 +2432,6 @@
 	struct keyspan_port_private	*p_priv;
 	const struct keyspan_device_details	*d_details;
 
-	dbg("%s", __func__);
-
 	for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
 		if (d_details->product_id ==
 				le16_to_cpu(serial->dev->descriptor.idProduct))
@@ -2538,8 +2491,6 @@
 	struct keyspan_serial_private 	*s_priv;
 	struct keyspan_port_private	*p_priv;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 
 	/* Stop reading/writing urbs */
@@ -2579,8 +2530,6 @@
 	struct usb_serial_port		*port;
 	struct keyspan_serial_private 	*s_priv;
 
-	dbg("%s", __func__);
-
 	s_priv = usb_get_serial_data(serial);
 
 	/*  dbg("Freeing serial->private."); */
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 622853c..fe1c5d9 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -487,13 +487,6 @@
 
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
-static struct usb_driver keyspan_driver = {
-	.name =		"keyspan",                
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	keyspan_ids_combined,
-};
-
 /* usb_device_id table for the pre-firmware download keyspan devices */
 static const struct usb_device_id keyspan_pre_ids[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa18x_pre_product_id) },
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 693bcdf..a4ac3cf 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -86,13 +86,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver keyspan_pda_driver = {
-	.name =		"keyspan_pda",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
 static const struct usb_device_id id_table_std[] = {
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, KEYSPAN_PDA_ID) },
 	{ }						/* Terminating entry */
@@ -131,7 +124,6 @@
 	struct usb_serial *serial = priv->serial;
 	int result;
 
-	dbg(" request_unthrottle");
 	/* ask the device to tell us when the tx buffer becomes
 	   sufficiently empty */
 	result = usb_control_msg(serial->dev,
@@ -226,7 +218,7 @@
 	   send an XOFF, although it might make sense to foist that off
 	   upon the device too. */
 	struct usb_serial_port *port = tty->driver_data;
-	dbg("keyspan_pda_rx_throttle port %d", port->number);
+
 	usb_kill_urb(port->interrupt_in_urb);
 }
 
@@ -235,7 +227,7 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 	/* just restart the receive interrupt URB */
-	dbg("keyspan_pda_rx_unthrottle port %d", port->number);
+
 	if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
 		dbg(" usb_submit_urb(read urb) failed");
 }
@@ -466,7 +458,6 @@
 	   select() or poll() too) until we receive that unthrottle interrupt.
 	   Block if we can't write anything at all, otherwise write as much as
 	   we can. */
-	dbg("keyspan_pda_write(%d)", count);
 	if (count == 0) {
 		dbg(" write request of 0 bytes");
 		return 0;
@@ -766,8 +757,6 @@
 
 static void keyspan_pda_release(struct usb_serial *serial)
 {
-	dbg("%s", __func__);
-
 	kfree(usb_get_serial_port_data(serial->port[0]));
 }
 
@@ -834,7 +823,7 @@
 	NULL
 };
 
-module_usb_serial_driver(keyspan_pda_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 10f0540..5bed59c 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -86,13 +86,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver kl5kusb105d_driver = {
-	.name =		"kl5kusb105d",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver kl5kusb105d_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -282,8 +275,6 @@
 {
 	int i;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i)
 		kfree(usb_get_serial_port_data(serial->port[i]));
 }
@@ -298,8 +289,6 @@
 	struct klsi_105_port_settings *cfg;
 	unsigned long flags;
 
-	dbg("%s port %d", __func__, port->number);
-
 	/* Do a defined restart:
 	 * Set up sane default baud rate and send the 'READ_ON'
 	 * vendor command.
@@ -376,8 +365,6 @@
 {
 	int rc;
 
-	dbg("%s port %d", __func__, port->number);
-
 	mutex_lock(&port->serial->disc_mutex);
 	if (!port->serial->disconnected) {
 		/* send READ_OFF */
@@ -646,7 +633,6 @@
 	unsigned long flags;
 	int rc;
 	unsigned long line_state;
-	dbg("%s - request, just guessing", __func__);
 
 	rc = klsi_105_get_line_state(port, &line_state);
 	if (rc < 0) {
@@ -668,8 +654,6 @@
 {
 	int retval = -EINVAL;
 
-	dbg("%s", __func__);
-
 /* if this ever gets implemented, it should be done something like this:
 	struct usb_serial *serial = port->serial;
 	struct klsi_105_private *priv = usb_get_serial_port_data(port);
@@ -692,7 +676,7 @@
 	return retval;
 }
 
-module_usb_serial_driver(kl5kusb105d_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 4a9a75e..fafeabb 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -81,18 +81,8 @@
 	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_KAAN_SIM_PRODUCT_ID) },
 	{ }			/* Terminating entry */
 };
-
-
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver kobil_driver = {
-	.name =		"kobil",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
-
 static struct usb_serial_driver kobil_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -193,7 +183,6 @@
 static void kobil_release(struct usb_serial *serial)
 {
 	int i;
-	dbg("%s - port %d", __func__, serial->port[0]->number);
 
 	for (i = 0; i < serial->num_ports; ++i)
 		kfree(usb_get_serial_port_data(serial->port[i]));
@@ -217,7 +206,6 @@
 	int transfer_buffer_length = 8;
 	int write_urb_transfer_buffer_length = 8;
 
-	dbg("%s - port %d", __func__, port->number);
 	priv = usb_get_serial_port_data(port);
 
 	/* allocate memory for transfer buffer */
@@ -327,8 +315,6 @@
 
 static void kobil_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	/* FIXME: Add rts/dtr methods */
 	if (port->write_urb) {
 		usb_poison_urb(port->write_urb);
@@ -349,8 +335,6 @@
 	int status = urb->status;
 /*	char *dbg_data; */
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (status) {
 		dbg("%s - port %d Read int status not zero: %d",
 		    __func__, port->number, status);
@@ -474,7 +458,6 @@
 
 static int kobil_write_room(struct tty_struct *tty)
 {
-	/* dbg("%s - port %d", __func__, port->number); */
 	/* FIXME */
 	return 8;
 }
@@ -683,7 +666,7 @@
 	}
 }
 
-module_usb_serial_driver(kobil_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 6edd261..d0ec1aa 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -73,22 +73,14 @@
 /*
  * All of the device info needed for the MCT USB-RS232 converter.
  */
-static const struct usb_device_id id_table_combined[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) },
 	{ USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) },
 	{ USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) },
 	{ }		/* Terminating entry */
 };
-
-MODULE_DEVICE_TABLE(usb, id_table_combined);
-
-static struct usb_driver mct_u232_driver = {
-	.name =		"mct_u232",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_serial_driver mct_u232_device = {
 	.driver = {
@@ -96,7 +88,7 @@
 		.name =		"mct_u232",
 	},
 	.description =	     "MCT U232",
-	.id_table =	     id_table_combined,
+	.id_table =	     id_table,
 	.num_ports =	     1,
 	.open =		     mct_u232_open,
 	.close =	     mct_u232_close,
@@ -427,8 +419,6 @@
 	struct mct_u232_private *priv;
 	int i;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		/* My special items, the standard routines free my urbs */
 		priv = usb_get_serial_port_data(serial->port[i]);
@@ -446,8 +436,6 @@
 	unsigned char last_lcr;
 	unsigned char last_msr;
 
-	dbg("%s port %d", __func__, port->number);
-
 	/* Compensate for a hardware bug: although the Sitecom U232-P25
 	 * device reports a maximum output packet size of 32 bytes,
 	 * it seems to be able to accept only 16 bytes (and that's what
@@ -528,8 +516,6 @@
 
 static void mct_u232_close(struct usb_serial_port *port)
 {
-	dbg("%s port %d", __func__, port->number);
-
 	if (port->serial->dev) {
 		/* shutdown our urbs */
 		usb_kill_urb(port->write_urb);
@@ -572,7 +558,6 @@
 		return;
 	}
 
-	dbg("%s - port %d", __func__, port->number);
 	usb_serial_debug_data(debug, &port->dev, __func__,
 					urb->actual_length, data);
 
@@ -733,8 +718,6 @@
 	unsigned char lcr;
 	unsigned long flags;
 
-	dbg("%sstate=%d", __func__, break_state);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	lcr = priv->last_lcr;
 
@@ -753,8 +736,6 @@
 	unsigned int control_state;
 	unsigned long flags;
 
-	dbg("%s", __func__);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	control_state = priv->control_state;
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -771,8 +752,6 @@
 	unsigned int control_state;
 	unsigned long flags;
 
-	dbg("%s", __func__);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	control_state = priv->control_state;
 
@@ -796,8 +775,6 @@
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
 	unsigned int control_state;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irq(&priv->lock);
 	priv->rx_flags |= THROTTLED;
 	if (C_CRTSCTS(tty)) {
@@ -816,8 +793,6 @@
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
 	unsigned int control_state;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irq(&priv->lock);
 	if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
 		priv->rx_flags &= ~THROTTLED;
@@ -906,7 +881,7 @@
 	return 0;
 }
 
-module_usb_serial_driver(mct_u232_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index 08d16e8..81423f7 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -17,7 +17,6 @@
 #include <linux/tty_flip.h>
 #include <linux/moduleparam.h>
 #include <linux/spinlock.h>
-#include <linux/errno.h>
 #include <linux/uaccess.h>
 #include <linux/usb/serial.h>
 
@@ -56,6 +55,47 @@
 /* Input parameter constants. */
 static bool debug;
 
+/* UNI-Directional mode commands for device configure */
+#define UNI_CMD_OPEN	0x80
+#define UNI_CMD_CLOSE	0xFF
+
+inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port)
+{
+	__u16 product_id = le16_to_cpu(
+		port->serial->dev->descriptor.idProduct);
+
+	return product_id == FOCUS_PRODUCT_ID_UNI;
+}
+
+static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port)
+{
+	int ret;
+	int actual_len;
+	u8 *buffer_cmd = NULL;
+
+	if (!metrousb_is_unidirectional_mode(port))
+		return 0;
+
+	buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL);
+	if (!buffer_cmd)
+		return -ENOMEM;
+
+	*buffer_cmd = cmd;
+
+	ret = usb_interrupt_msg(port->serial->dev,
+		usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
+		buffer_cmd, sizeof(cmd),
+		&actual_len, USB_CTRL_SET_TIMEOUT);
+
+	kfree(buffer_cmd);
+
+	if (ret < 0)
+		return ret;
+	else if (actual_len != sizeof(cmd))
+		return -EIO;
+	return 0;
+}
+
 static void metrousb_read_int_callback(struct urb *urb)
 {
 	struct usb_serial_port *port = urb->context;
@@ -78,12 +118,12 @@
 		/* urb has been terminated. */
 		dev_dbg(&port->dev,
 			"%s - urb shutting down, error code=%d\n",
-			__func__, result);
+			__func__, urb->status);
 		return;
 	default:
 		dev_dbg(&port->dev,
 			"%s - non-zero urb received, error code=%d\n",
-			__func__, result);
+			__func__, urb->status);
 		goto exit;
 	}
 
@@ -91,7 +131,7 @@
 	/* Set the data read from the usb port into the serial port buffer. */
 	tty = tty_port_tty_get(&port->port);
 	if (!tty) {
-		dev_dbg(&port->dev, "%s - bad tty pointer - exiting\n",
+		dev_err(&port->dev, "%s - bad tty pointer - exiting\n",
 			__func__);
 		return;
 	}
@@ -121,7 +161,7 @@
 		result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
 
 		if (result)
-			dev_dbg(&port->dev,
+			dev_err(&port->dev,
 				"%s - failed submitting interrupt in urb, error code=%d\n",
 				__func__, result);
 	}
@@ -131,11 +171,19 @@
 	/* Try to resubmit the urb. */
 	result = usb_submit_urb(urb, GFP_ATOMIC);
 	if (result)
-		dev_dbg(&port->dev,
+		dev_err(&port->dev,
 			"%s - failed submitting interrupt in urb, error code=%d\n",
 			__func__, result);
 }
 
+static void metrousb_write_int_callback(struct urb *urb)
+{
+	struct usb_serial_port *port = urb->context;
+
+	dev_warn(&port->dev, "%s not implemented yet.\n",
+		__func__);
+}
+
 static void metrousb_cleanup(struct usb_serial_port *port)
 {
 	dev_dbg(&port->dev, "%s\n", __func__);
@@ -146,6 +194,9 @@
 			usb_unlink_urb(port->interrupt_in_urb);
 			usb_kill_urb(port->interrupt_in_urb);
 		}
+
+		/* Send deactivate cmd to device */
+		metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
 	}
 }
 
@@ -160,7 +211,7 @@
 
 	/* Make sure the urb is initialized. */
 	if (!port->interrupt_in_urb) {
-		dev_dbg(&port->dev, "%s - interrupt urb not initialized\n",
+		dev_err(&port->dev, "%s - interrupt urb not initialized\n",
 			__func__);
 		return -ENODEV;
 	}
@@ -191,12 +242,21 @@
 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 
 	if (result) {
-		dev_dbg(&port->dev,
+		dev_err(&port->dev,
 			"%s - failed submitting interrupt in urb, error code=%d\n",
 			__func__, result);
 		goto exit;
 	}
 
+	/* Send activate cmd to device */
+	result = metrousb_send_unidirectional_cmd(UNI_CMD_OPEN, port);
+	if (result) {
+		dev_err(&port->dev,
+			"%s - failed to configure device for port number=%d, error code=%d\n",
+			__func__, port->number, result);
+		goto exit;
+	}
+
 	dev_dbg(&port->dev, "%s - port open\n", __func__);
 exit:
 	return result;
@@ -221,7 +281,7 @@
 				METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST,
 				control_state, 0, NULL, 0, WDR_TIMEOUT);
 	if (retval < 0)
-		dev_dbg(&serial->dev->dev,
+		dev_err(&serial->dev->dev,
 			"%s - set modem ctrl=0x%x failed, error code=%d\n",
 			__func__, mcr, retval);
 
@@ -354,29 +414,23 @@
 	port->interrupt_in_urb->dev = port->serial->dev;
 	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
 	if (result)
-		dev_dbg(tty->dev,
+		dev_err(tty->dev,
 			"failed submitting interrupt in urb error code=%d\n",
 			result);
 }
 
-static struct usb_driver metrousb_driver = {
-	.name =		"metro-usb",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table
-};
-
 static struct usb_serial_driver metrousb_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
 		.name =		"metro-usb",
 	},
-	.description		= "Metrologic USB to serial converter.",
+	.description		= "Metrologic USB to Serial",
 	.id_table		= id_table,
 	.num_ports		= 1,
 	.open			= metrousb_open,
 	.close			= metrousb_cleanup,
 	.read_int_callback	= metrousb_read_int_callback,
+	.write_int_callback	= metrousb_write_int_callback,
 	.attach			= metrousb_startup,
 	.release		= metrousb_shutdown,
 	.throttle		= metrousb_throttle,
@@ -390,7 +444,7 @@
 	NULL,
 };
 
-module_usb_serial_driver(metrousb_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Philip Nicastro");
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index bdce820..a07dd3c 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -79,12 +79,12 @@
 #define MOSCHIP_DEVICE_ID_7720		0x7720
 #define MOSCHIP_DEVICE_ID_7715		0x7715
 
-static const struct usb_device_id moschip_port_id_table[] = {
+static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
 	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7715) },
 	{ } /* terminating entry */
 };
-MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
 
@@ -257,7 +257,6 @@
 	struct mos7715_parport *mos_parport =
 		container_of(kref, struct mos7715_parport, ref_count);
 
-	dbg("%s called", __func__);
 	kfree(mos_parport);
 }
 
@@ -266,7 +265,7 @@
 	struct urbtracker *urbtrack =
 		container_of(kref, struct urbtracker, ref_count);
 	struct mos7715_parport *mos_parport = urbtrack->mos_parport;
-	dbg("%s called", __func__);
+
 	usb_free_urb(urbtrack->urb);
 	kfree(urbtrack);
 	kref_put(&mos_parport->ref_count, destroy_mos_parport);
@@ -285,8 +284,6 @@
 	struct urbtracker *urbtrack;
 	struct list_head *cursor, *next;
 
-	dbg("%s called", __func__);
-
 	/* if release function ran, game over */
 	if (unlikely(mos_parport->serial == NULL))
 		return;
@@ -335,7 +332,7 @@
 {
 	struct urbtracker *urbtrack = urb->context;
 	int status = urb->status;
-	dbg("%s called", __func__);
+
 	if (unlikely(status))
 		dbg("%s - nonzero urb status received: %d", __func__, status);
 
@@ -355,7 +352,6 @@
 	struct usb_ctrlrequest setup;
 	struct usb_serial *serial = mos_parport->serial;
 	struct usb_device *usbdev = serial->dev;
-	dbg("%s called", __func__);
 
 	/* create and initialize the control urb and containing urbtracker */
 	urbtrack = kmalloc(sizeof(struct urbtracker), GFP_ATOMIC);
@@ -476,7 +472,7 @@
 static void parport_mos7715_write_data(struct parport *pp, unsigned char d)
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
-	dbg("%s called: %2.2x", __func__, d);
+
 	if (parport_prologue(pp) < 0)
 		return;
 	mos7715_change_mode(mos_parport, SPP);
@@ -488,7 +484,7 @@
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
 	unsigned char d;
-	dbg("%s called", __func__);
+
 	if (parport_prologue(pp) < 0)
 		return 0;
 	read_mos_reg(mos_parport->serial, dummy, DPR, &d);
@@ -500,7 +496,7 @@
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
 	__u8 data;
-	dbg("%s called: %2.2x", __func__, d);
+
 	if (parport_prologue(pp) < 0)
 		return;
 	data = ((__u8)d & 0x0f) | (mos_parport->shadowDCR & 0xf0);
@@ -513,7 +509,7 @@
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
 	__u8 dcr;
-	dbg("%s called", __func__);
+
 	spin_lock(&release_lock);
 	mos_parport = pp->private_data;
 	if (unlikely(mos_parport == NULL)) {
@@ -531,7 +527,7 @@
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
 	__u8 dcr;
-	dbg("%s called", __func__);
+
 	mask &= 0x0f;
 	val &= 0x0f;
 	if (parport_prologue(pp) < 0)
@@ -547,7 +543,7 @@
 {
 	unsigned char status;
 	struct mos7715_parport *mos_parport = pp->private_data;
-	dbg("%s called", __func__);
+
 	spin_lock(&release_lock);
 	mos_parport = pp->private_data;
 	if (unlikely(mos_parport == NULL)) {	/* release called */
@@ -561,17 +557,16 @@
 
 static void parport_mos7715_enable_irq(struct parport *pp)
 {
-	dbg("%s called", __func__);
 }
+
 static void parport_mos7715_disable_irq(struct parport *pp)
 {
-	dbg("%s called", __func__);
 }
 
 static void parport_mos7715_data_forward(struct parport *pp)
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
-	dbg("%s called", __func__);
+
 	if (parport_prologue(pp) < 0)
 		return;
 	mos7715_change_mode(mos_parport, PS2);
@@ -583,7 +578,7 @@
 static void parport_mos7715_data_reverse(struct parport *pp)
 {
 	struct mos7715_parport *mos_parport = pp->private_data;
-	dbg("%s called", __func__);
+
 	if (parport_prologue(pp) < 0)
 		return;
 	mos7715_change_mode(mos_parport, PS2);
@@ -595,7 +590,6 @@
 static void parport_mos7715_init_state(struct pardevice *dev,
 				       struct parport_state *s)
 {
-	dbg("%s called", __func__);
 	s->u.pc.ctr = DCR_INIT_VAL;
 	s->u.pc.ecr = ECR_INIT_VAL;
 }
@@ -605,7 +599,7 @@
 				       struct parport_state *s)
 {
 	struct mos7715_parport *mos_parport;
-	dbg("%s called", __func__);
+
 	spin_lock(&release_lock);
 	mos_parport = pp->private_data;
 	if (unlikely(mos_parport == NULL)) {	/* release called */
@@ -622,7 +616,7 @@
 					  struct parport_state *s)
 {
 	struct mos7715_parport *mos_parport;
-	dbg("%s called", __func__);
+
 	spin_lock(&release_lock);
 	mos_parport = pp->private_data;
 	if (unlikely(mos_parport == NULL)) {	/* release called */
@@ -641,7 +635,7 @@
 	int retval;
 	struct mos7715_parport *mos_parport = pp->private_data;
 	int actual_len;
-	dbg("%s called: %u chars", __func__, (unsigned int)len);
+
 	if (parport_prologue(pp) < 0)
 		return 0;
 	mos7715_change_mode(mos_parport, PPF);
@@ -2164,20 +2158,13 @@
 		kfree(usb_get_serial_port_data(serial->port[i]));
 }
 
-static struct usb_driver usb_driver = {
-	.name =		"moschip7720",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	moschip_port_id_table,
-};
-
 static struct usb_serial_driver moschip7720_2port_driver = {
 	.driver = {
 		.owner =	THIS_MODULE,
 		.name =		"moschip7720",
 	},
 	.description		= "Moschip 2 port adapter",
-	.id_table		= moschip_port_id_table,
+	.id_table		= id_table,
 	.calc_num_ports		= mos77xx_calc_num_ports,
 	.open			= mos7720_open,
 	.close			= mos7720_close,
@@ -2203,7 +2190,7 @@
 	&moschip7720_2port_driver, NULL
 };
 
-module_usb_serial_driver(usb_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index c526550..29160f8 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -114,10 +114,10 @@
 #define USB_VENDOR_ID_MOSCHIP           0x9710
 #define MOSCHIP_DEVICE_ID_7840          0x7840
 #define MOSCHIP_DEVICE_ID_7820          0x7820
+#define MOSCHIP_DEVICE_ID_7810          0x7810
 /* The native component can have its vendor/device id's overridden
  * in vendor-specific implementations.  Such devices can be handled
- * by making a change here, in moschip_port_id_table, and in
- * moschip_id_table_combined
+ * by making a change here, in id_table.
  */
 #define USB_VENDOR_ID_BANDB              0x0856
 #define BANDB_DEVICE_ID_USO9ML2_2        0xAC22
@@ -184,10 +184,16 @@
 #define NUM_URBS                        16	/* URB Count */
 #define URB_TRANSFER_BUFFER_SIZE        32	/* URB Size  */
 
+/* LED on/off milliseconds*/
+#define LED_ON_MS	500
+#define LED_OFF_MS	500
 
-static const struct usb_device_id moschip_port_id_table[] = {
+static int device_type;
+
+static const struct usb_device_id id_table[] __devinitconst = {
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
 	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
+	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7810)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
 	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
@@ -205,29 +211,7 @@
 	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
 	{}			/* terminating entry */
 };
-
-static const struct usb_device_id moschip_id_table_combined[] __devinitconst = {
-	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)},
-	{USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)},
-	{USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)},
-	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)},
-	{USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)},
-	{}			/* terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, moschip_id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 /* This structure holds all of the local port information */
 
@@ -261,8 +245,13 @@
 	struct urb *write_urb_pool[NUM_URBS];
 	char busy[NUM_URBS];
 	bool read_urb_busy;
-};
 
+	/* For device(s) with LED indicator */
+	bool has_led;
+	bool led_flag;
+	struct timer_list led_timer1;	/* Timer for LED on */
+	struct timer_list led_timer2;	/* Timer for LED off */
+};
 
 static bool debug;
 
@@ -572,6 +561,69 @@
 	return ret;
 }
 
+static void mos7840_set_led_callback(struct urb *urb)
+{
+	switch (urb->status) {
+	case 0:
+		/* Success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* This urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d", __func__,
+			urb->status);
+		break;
+	default:
+		dbg("%s - nonzero urb status received: %d", __func__,
+			urb->status);
+	}
+}
+
+static void mos7840_set_led_async(struct moschip_port *mcs, __u16 wval,
+				__u16 reg)
+{
+	struct usb_device *dev = mcs->port->serial->dev;
+	struct usb_ctrlrequest *dr = mcs->dr;
+
+	dr->bRequestType = MCS_WR_RTYPE;
+	dr->bRequest = MCS_WRREQ;
+	dr->wValue = cpu_to_le16(wval);
+	dr->wIndex = cpu_to_le16(reg);
+	dr->wLength = cpu_to_le16(0);
+
+	usb_fill_control_urb(mcs->control_urb, dev, usb_sndctrlpipe(dev, 0),
+		(unsigned char *)dr, NULL, 0, mos7840_set_led_callback, NULL);
+
+	usb_submit_urb(mcs->control_urb, GFP_ATOMIC);
+}
+
+static void mos7840_set_led_sync(struct usb_serial_port *port, __u16 reg,
+				__u16 val)
+{
+	struct usb_device *dev = port->serial->dev;
+
+	usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ, MCS_WR_RTYPE,
+			val, reg, NULL, 0, MOS_WDR_TIMEOUT);
+}
+
+static void mos7840_led_off(unsigned long arg)
+{
+	struct moschip_port *mcs = (struct moschip_port *) arg;
+
+	/* Turn off LED */
+	mos7840_set_led_async(mcs, 0x0300, MODEM_CONTROL_REGISTER);
+	mod_timer(&mcs->led_timer2,
+				jiffies + msecs_to_jiffies(LED_OFF_MS));
+}
+
+static void mos7840_led_flag_off(unsigned long arg)
+{
+	struct moschip_port *mcs = (struct moschip_port *) arg;
+
+	mcs->led_flag = false;
+}
+
 /*****************************************************************************
  * mos7840_interrupt_callback
  *	this is the callback function for when we have received data on the
@@ -591,8 +643,6 @@
 	__u16 wval, wreg = 0;
 	int status = urb->status;
 
-	dbg("%s", " : Entering");
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -766,12 +816,8 @@
 		return;
 	}
 
-	dbg("%s", "Entering... ");
-
 	data = urb->transfer_buffer;
 
-	dbg("%s", "Entering ...........");
-
 	if (urb->actual_length) {
 		tty = tty_port_tty_get(&mos7840_port->port->port);
 		if (tty) {
@@ -792,6 +838,14 @@
 		return;
 	}
 
+	/* Turn on LED */
+	if (mos7840_port->has_led && !mos7840_port->led_flag) {
+		mos7840_port->led_flag = true;
+		mos7840_set_led_async(mos7840_port, 0x0301,
+					MODEM_CONTROL_REGISTER);
+		mod_timer(&mos7840_port->led_timer1,
+				jiffies + msecs_to_jiffies(LED_ON_MS));
+	}
 
 	mos7840_port->read_urb_busy = true;
 	retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);
@@ -835,8 +889,6 @@
 		return;
 	}
 
-	dbg("%s", "Entering .........");
-
 	tty = tty_port_tty_get(&mos7840_port->port->port);
 	if (tty && mos7840_port->open)
 		tty_wakeup(tty);
@@ -878,8 +930,6 @@
 	struct moschip_port *mos7840_port;
 	struct moschip_port *port0;
 
-	dbg ("%s enter", __func__);
-
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Port Paranoia failed");
 		return -ENODEV;
@@ -1151,10 +1201,7 @@
 	dbg("usb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p",
 				serial, mos7840_port, port);
 
-	dbg ("%s leave", __func__);
-
 	return 0;
-
 }
 
 /*****************************************************************************
@@ -1175,18 +1222,14 @@
 	unsigned long flags;
 	struct moschip_port *mos7840_port;
 
-	dbg("%s", " mos7840_chars_in_buffer:entering ...........");
-
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Invalid port");
 		return 0;
 	}
 
 	mos7840_port = mos7840_get_port_private(port);
-	if (mos7840_port == NULL) {
-		dbg("%s", "mos7840_break:leaving ...........");
+	if (mos7840_port == NULL)
 		return 0;
-	}
 
 	spin_lock_irqsave(&mos7840_port->pool_lock, flags);
 	for (i = 0; i < NUM_URBS; ++i)
@@ -1211,8 +1254,6 @@
 	int j;
 	__u16 Data;
 
-	dbg("%s", "mos7840_close:entering...");
-
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Port Paranoia failed");
 		return;
@@ -1287,8 +1328,6 @@
 	mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 
 	mos7840_port->open = 0;
-
-	dbg("%s", "Leaving ............");
 }
 
 /************************************************************************
@@ -1343,9 +1382,6 @@
 	struct usb_serial *serial;
 	struct moschip_port *mos7840_port;
 
-	dbg("%s", "Entering ...........");
-	dbg("mos7840_break: Start");
-
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Port Paranoia failed");
 		return;
@@ -1395,8 +1431,6 @@
 	unsigned long flags;
 	struct moschip_port *mos7840_port;
 
-	dbg("%s", " mos7840_write_room:entering ...........");
-
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Invalid port");
 		dbg("%s", " mos7840_write_room:leaving ...........");
@@ -1445,9 +1479,6 @@
 	/* __u16 Data; */
 	const unsigned char *current_position = data;
 	unsigned char *data1;
-	dbg("%s", "entering ...........");
-	/* dbg("mos7840_write: mos7840_port->shadowLCR is %x",
-					mos7840_port->shadowLCR); */
 
 #ifdef NOTMOS7840
 	Data = 0x00;
@@ -1554,6 +1585,14 @@
 	data1 = urb->transfer_buffer;
 	dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
 
+	/* Turn on LED */
+	if (mos7840_port->has_led && !mos7840_port->led_flag) {
+		mos7840_port->led_flag = true;
+		mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0301);
+		mod_timer(&mos7840_port->led_timer1,
+				jiffies + msecs_to_jiffies(LED_ON_MS));
+	}
+
 	/* send it down the pipe */
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 
@@ -1602,8 +1641,6 @@
 		return;
 	}
 
-	dbg("%s", "Entering ..........");
-
 	/* if we are implementing XON/XOFF, send the stop character */
 	if (I_IXOFF(tty)) {
 		unsigned char stop_char = STOP_CHAR(tty);
@@ -1646,8 +1683,6 @@
 		return;
 	}
 
-	dbg("%s", "Entering ..........");
-
 	/* if we are implementing XON/XOFF, send the start character */
 	if (I_IXOFF(tty)) {
 		unsigned char start_char = START_CHAR(tty);
@@ -1676,8 +1711,6 @@
 	int status;
 	mos7840_port = mos7840_get_port_private(port);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (mos7840_port == NULL)
 		return -ENODEV;
 
@@ -1704,8 +1737,6 @@
 	unsigned int mcr;
 	int status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	mos7840_port = mos7840_get_port_private(port);
 
 	if (mos7840_port == NULL)
@@ -1746,7 +1777,6 @@
 static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
 					  __u16 *clk_sel_val)
 {
-
 	dbg("%s - %d", __func__, baudRate);
 
 	if (baudRate <= 115200) {
@@ -1839,8 +1869,6 @@
 		return -1;
 	}
 
-	dbg("%s", "Entering ..........");
-
 	number = mos7840_port->port->number - mos7840_port->port->serial->minor;
 
 	dbg("%s - port = %d, baud = %d", __func__,
@@ -1966,8 +1994,6 @@
 		return;
 	}
 
-	dbg("%s", "Entering ..........");
-
 	lData = LCR_BITS_8;
 	lStop = LCR_STOP_1;
 	lParity = LCR_PAR_NONE;
@@ -2108,7 +2134,7 @@
 	unsigned int cflag;
 	struct usb_serial *serial;
 	struct moschip_port *mos7840_port;
-	dbg("mos7840_set_termios: START");
+
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Invalid port");
 		return;
@@ -2327,28 +2353,74 @@
 	return -ENOIOCTLCMD;
 }
 
+static int mos7810_check(struct usb_serial *serial)
+{
+	int i, pass_count = 0;
+	__u16 data = 0, mcr_data = 0;
+	__u16 test_pattern = 0x55AA;
+
+	/* Store MCR setting */
+	usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+		MCS_RDREQ, MCS_RD_RTYPE, 0x0300, MODEM_CONTROL_REGISTER,
+		&mcr_data, VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+	for (i = 0; i < 16; i++) {
+		/* Send the 1-bit test pattern out to MCS7810 test pin */
+		usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			MCS_WRREQ, MCS_WR_RTYPE,
+			(0x0300 | (((test_pattern >> i) & 0x0001) << 1)),
+			MODEM_CONTROL_REGISTER, NULL, 0, MOS_WDR_TIMEOUT);
+
+		/* Read the test pattern back */
+		usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+			MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
+			VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
+
+		/* If this is a MCS7810 device, both test patterns must match */
+		if (((test_pattern >> i) ^ (~data >> 1)) & 0x0001)
+			break;
+
+		pass_count++;
+	}
+
+	/* Restore MCR setting */
+	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), MCS_WRREQ,
+		MCS_WR_RTYPE, 0x0300 | mcr_data, MODEM_CONTROL_REGISTER, NULL,
+		0, MOS_WDR_TIMEOUT);
+
+	if (pass_count == 16)
+		return 1;
+
+	return 0;
+}
+
 static int mos7840_calc_num_ports(struct usb_serial *serial)
 {
-	__u16 Data = 0x00;
-	int ret = 0;
+	__u16 data = 0x00;
 	int mos7840_num_ports;
 
-	ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-		MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
+	usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+		MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &data,
 		VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
 
-	if ((Data & 0x01) == 0) {
-		mos7840_num_ports = 2;
-		serial->num_bulk_in = 2;
-		serial->num_bulk_out = 2;
-		serial->num_ports = 2;
+	if (serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7810 ||
+		serial->dev->descriptor.idProduct == MOSCHIP_DEVICE_ID_7820) {
+		device_type = serial->dev->descriptor.idProduct;
 	} else {
-		mos7840_num_ports = 4;
-		serial->num_bulk_in = 4;
-		serial->num_bulk_out = 4;
-		serial->num_ports = 4;
+		/* For a MCS7840 device GPIO0 must be set to 1 */
+		if ((data & 0x01) == 1)
+			device_type = MOSCHIP_DEVICE_ID_7840;
+		else if (mos7810_check(serial))
+			device_type = MOSCHIP_DEVICE_ID_7810;
+		else
+			device_type = MOSCHIP_DEVICE_ID_7820;
 	}
 
+	mos7840_num_ports = (device_type >> 4) & 0x000F;
+	serial->num_bulk_in = mos7840_num_ports;
+	serial->num_bulk_out = mos7840_num_ports;
+	serial->num_ports = mos7840_num_ports;
+
 	return mos7840_num_ports;
 }
 
@@ -2361,9 +2433,7 @@
 	struct moschip_port *mos7840_port;
 	struct usb_device *dev;
 	int i, status;
-
 	__u16 Data;
-	dbg("%s", "mos7840_startup :Entering..........");
 
 	if (!serial) {
 		dbg("%s", "Invalid Handler");
@@ -2372,9 +2442,6 @@
 
 	dev = serial->dev;
 
-	dbg("%s", "Entering...");
-	dbg ("mos7840_startup: serial = %p", serial);
-
 	/* we set up the pointers to the endpoints in the mos7840_open *
 	 * function, as the structures aren't created yet.             */
 
@@ -2563,6 +2630,34 @@
 			status = -ENOMEM;
 			goto error;
 		}
+
+		mos7840_port->has_led = false;
+
+		/* Initialize LED timers */
+		if (device_type == MOSCHIP_DEVICE_ID_7810) {
+			mos7840_port->has_led = true;
+
+			init_timer(&mos7840_port->led_timer1);
+			mos7840_port->led_timer1.function = mos7840_led_off;
+			mos7840_port->led_timer1.expires =
+					jiffies + msecs_to_jiffies(LED_ON_MS);
+			mos7840_port->led_timer1.data =
+						(unsigned long)mos7840_port;
+
+			init_timer(&mos7840_port->led_timer2);
+			mos7840_port->led_timer2.function =
+						mos7840_led_flag_off;
+			mos7840_port->led_timer2.expires =
+					jiffies + msecs_to_jiffies(LED_OFF_MS);
+			mos7840_port->led_timer2.data =
+						(unsigned long)mos7840_port;
+
+			mos7840_port->led_flag = false;
+
+			/* Turn off LED */
+			mos7840_set_led_sync(serial->port[i],
+						MODEM_CONTROL_REGISTER, 0x0300);
+		}
 	}
 	dbg ("mos7840_startup: all ports configured...........");
 
@@ -2602,7 +2697,6 @@
 	int i;
 	unsigned long flags;
 	struct moschip_port *mos7840_port;
-	dbg("%s", " disconnect :entering..........");
 
 	if (!serial) {
 		dbg("%s", "Invalid Handler");
@@ -2624,9 +2718,6 @@
 			usb_kill_urb(mos7840_port->control_urb);
 		}
 	}
-
-	dbg("%s", "Thank u :: ");
-
 }
 
 /****************************************************************************
@@ -2638,7 +2729,6 @@
 {
 	int i;
 	struct moschip_port *mos7840_port;
-	dbg("%s", " release :entering..........");
 
 	if (!serial) {
 		dbg("%s", "Invalid Handler");
@@ -2654,30 +2744,28 @@
 		mos7840_port = mos7840_get_port_private(serial->port[i]);
 		dbg("mos7840_port %d = %p", i, mos7840_port);
 		if (mos7840_port) {
+			if (mos7840_port->has_led) {
+				/* Turn off LED */
+				mos7840_set_led_sync(mos7840_port->port,
+						MODEM_CONTROL_REGISTER, 0x0300);
+
+				del_timer_sync(&mos7840_port->led_timer1);
+				del_timer_sync(&mos7840_port->led_timer2);
+			}
 			kfree(mos7840_port->ctrl_buf);
 			kfree(mos7840_port->dr);
 			kfree(mos7840_port);
 		}
 	}
-
-	dbg("%s", "Thank u :: ");
-
 }
 
-static struct usb_driver io_driver = {
-	.name = "mos7840",
-	.probe = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-	.id_table = moschip_id_table_combined,
-};
-
 static struct usb_serial_driver moschip7840_4port_device = {
 	.driver = {
 		   .owner = THIS_MODULE,
 		   .name = "mos7840",
 		   },
 	.description = DRIVER_DESC,
-	.id_table = moschip_port_id_table,
+	.id_table = id_table,
 	.num_ports = 4,
 	.open = mos7840_open,
 	.close = mos7840_close,
@@ -2707,7 +2795,7 @@
 	&moschip7840_4port_device, NULL
 };
 
-module_usb_serial_driver(io_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c
index 3ab6214..c5ff6c7 100644
--- a/drivers/usb/serial/moto_modem.c
+++ b/drivers/usb/serial/moto_modem.c
@@ -31,13 +31,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver moto_driver = {
-	.name =		"moto-modem",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver moto_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -51,5 +44,5 @@
 	&moto_device, NULL
 };
 
-module_usb_serial_driver(moto_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index 29ab6eb..d95452c 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -30,13 +30,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver navman_driver = {
-	.name =		"navman",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static void navman_read_int_callback(struct urb *urb)
 {
 	struct usb_serial_port *port = urb->context;
@@ -53,12 +46,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
@@ -84,10 +77,9 @@
 {
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (port->interrupt_in_urb) {
-		dbg("%s - adding interrupt input for treo", __func__);
+		dev_dbg(&port->dev, "%s - adding interrupt input for treo\n",
+			__func__);
 		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (result)
 			dev_err(&port->dev,
@@ -99,16 +91,12 @@
 
 static void navman_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	usb_kill_urb(port->interrupt_in_urb);
 }
 
 static int navman_write(struct tty_struct *tty, struct usb_serial_port *port,
 			const unsigned char *buf, int count)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	/*
 	 * This device can't write any data, only read from the device
 	 */
@@ -132,7 +120,7 @@
 	&navman_device, NULL
 };
 
-module_usb_serial_driver(navman_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 88dc785..6f3d705 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -54,17 +54,8 @@
 	{ USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) },
 	{ }						/* Terminating entry */
 };
-
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver omninet_driver = {
-	.name =		"omninet",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
-
 static struct usb_serial_driver zyxel_omninet_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -144,8 +135,6 @@
 	struct usb_serial_port	*wport;
 	int			result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	wport = serial->port[1];
 	tty_port_tty_set(&wport->port, tty);
 
@@ -160,7 +149,6 @@
 
 static void omninet_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
 	usb_kill_urb(port->read_urb);
 }
 
@@ -178,8 +166,6 @@
 	int result;
 	int i;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (status) {
 		dbg("%s - nonzero read bulk status received: %d",
 		    __func__, status);
@@ -225,8 +211,6 @@
 
 	int			result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (count == 0) {
 		dbg("%s - write request of 0 bytes", __func__);
 		return 0;
@@ -289,8 +273,6 @@
 	struct usb_serial_port 	*port   =  urb->context;
 	int status = urb->status;
 
-	dbg("%s - port %0x", __func__, port->number);
-
 	set_bit(0, &port->write_urbs_free);
 	if (status) {
 		dbg("%s - nonzero write bulk status received: %d",
@@ -306,8 +288,6 @@
 {
 	struct usb_serial_port *wport = serial->port[1];
 
-	dbg("%s", __func__);
-
 	usb_kill_urb(wport->write_urb);
 }
 
@@ -316,12 +296,10 @@
 {
 	struct usb_serial_port *port = serial->port[0];
 
-	dbg("%s", __func__);
-
 	kfree(usb_get_serial_port_data(port));
 }
 
-module_usb_serial_driver(omninet_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 82cc9d2..02cb1b7 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -70,8 +70,6 @@
 	int data_length;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -179,8 +177,6 @@
 	unsigned long flags;
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->throttled = false;
 	priv->actually_throttled = false;
@@ -216,8 +212,6 @@
 {
 	struct opticon_private *priv = usb_get_serial_data(port->serial);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* shutdown our urbs */
 	usb_kill_urb(priv->bulk_read_urb);
 }
@@ -256,8 +250,6 @@
 	int status;
 	struct usb_ctrlrequest *dr;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -338,8 +330,6 @@
 	struct opticon_private *priv = usb_get_serial_data(port->serial);
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/*
 	 * We really can take almost anything the user throws at us
 	 * but let's pick a nice big number to tell the tty
@@ -362,7 +352,6 @@
 	struct opticon_private *priv = usb_get_serial_data(port->serial);
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->throttled = true;
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -376,8 +365,6 @@
 	unsigned long flags;
 	int result, was_throttled;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->throttled = false;
 	was_throttled = priv->actually_throttled;
@@ -400,10 +387,6 @@
 	unsigned long flags;
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-	if (!usb_get_intfdata(port->serial->interface))
-		return -ENODEV;
-
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->rts)
 		result |= TIOCM_RTS;
@@ -419,13 +402,13 @@
 			   unsigned int set, unsigned int clear)
 {
 	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
 	struct opticon_private *priv = usb_get_serial_data(port->serial);
 	unsigned long flags;
 	bool rts;
 	bool changed = false;
+	int ret;
 
-	if (!usb_get_intfdata(port->serial->interface))
-		return -ENODEV;
 	/* We only support RTS so we only handle that */
 	spin_lock_irqsave(&priv->lock, flags);
 
@@ -441,7 +424,14 @@
 		return 0;
 
 	/* Send the new RTS state to the connected device */
-	return send_control_msg(port, CONTROL_RTS, !rts);
+	mutex_lock(&serial->disc_mutex);
+	if (!serial->disconnected)
+		ret = send_control_msg(port, CONTROL_RTS, !rts);
+	else
+		ret = -ENODEV;
+	mutex_unlock(&serial->disc_mutex);
+
+	return ret;
 }
 
 static int get_serial_info(struct opticon_private *priv,
@@ -555,8 +545,6 @@
 {
 	struct opticon_private *priv = usb_get_serial_data(serial);
 
-	dbg("%s", __func__);
-
 	usb_kill_urb(priv->bulk_read_urb);
 	usb_free_urb(priv->bulk_read_urb);
 }
@@ -565,24 +553,20 @@
 {
 	struct opticon_private *priv = usb_get_serial_data(serial);
 
-	dbg("%s", __func__);
-
 	kfree(priv->bulk_in_buffer);
 	kfree(priv);
 }
 
-static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
+static int opticon_suspend(struct usb_serial *serial, pm_message_t message)
 {
-	struct usb_serial *serial = usb_get_intfdata(intf);
 	struct opticon_private *priv = usb_get_serial_data(serial);
 
 	usb_kill_urb(priv->bulk_read_urb);
 	return 0;
 }
 
-static int opticon_resume(struct usb_interface *intf)
+static int opticon_resume(struct usb_serial *serial)
 {
-	struct usb_serial *serial = usb_get_intfdata(intf);
 	struct opticon_private *priv = usb_get_serial_data(serial);
 	struct usb_serial_port *port = serial->port[0];
 	int result;
@@ -597,15 +581,6 @@
 	return result;
 }
 
-static struct usb_driver opticon_driver = {
-	.name =		"opticon",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.suspend =	opticon_suspend,
-	.resume =	opticon_resume,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver opticon_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -625,13 +600,15 @@
 	.ioctl =		opticon_ioctl,
 	.tiocmget =		opticon_tiocmget,
 	.tiocmset =		opticon_tiocmset,
+	.suspend = 		opticon_suspend,
+	.resume =		opticon_resume,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
 	&opticon_device, NULL
 };
 
-module_usb_serial_driver(opticon_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index f4465cc..1aae902 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1220,18 +1220,6 @@
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
 
-static struct usb_driver option_driver = {
-	.name       = "option",
-	.probe      = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-#ifdef CONFIG_PM
-	.suspend    = usb_serial_suspend,
-	.resume     = usb_serial_resume,
-	.supports_autosuspend =	1,
-#endif
-	.id_table   = option_ids,
-};
-
 /* The card has three separate interfaces, which the serial driver
  * recognizes separately, thus num_port=1.
  */
@@ -1300,7 +1288,7 @@
 	unsigned long tx_start_time[N_OUT_URB];
 };
 
-module_usb_serial_driver(option_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, option_ids);
 
 static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
 			   const struct option_blacklist_info *blacklist)
@@ -1375,7 +1363,6 @@
 	struct usb_serial_port *port =  urb->context;
 	struct option_port_private *portdata = usb_get_serial_port_data(port);
 
-	dbg("%s", __func__);
 	dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
 
 	if (status == 0) {
@@ -1413,7 +1400,7 @@
 				req_pkt->bRequestType, req_pkt->bRequest);
 		}
 	} else
-		err("%s: error %d", __func__, status);
+		dev_err(&port->dev, "%s: error %d\n", __func__, status);
 
 	/* Resubmit urb so we continue receiving IRQ data */
 	if (status != -ESHUTDOWN && status != -ENOENT) {
@@ -1437,7 +1424,6 @@
 	struct option_port_private *portdata;
 	int ifNum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
 	int val = 0;
-	dbg("%s", __func__);
 
 	if (is_blacklisted(ifNum, OPTION_BLACKLIST_SENDSETUP,
 			(struct option_blacklist_info *) intfdata->private)) {
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 5fdc33c..5976b65 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -66,13 +66,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver oti6858_driver = {
-	.name =		"oti6858",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static bool debug;
 
 /* requests */
@@ -211,8 +204,6 @@
 	unsigned long flags;
 	int result;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
 	if (new_setup == NULL) {
 		dev_err(&port->dev, "%s(): out of memory!\n", __func__);
@@ -282,8 +273,6 @@
 	unsigned long flags;
 	u8 *allow;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->flags.write_urb_in_use) {
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -379,8 +368,6 @@
 static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
 			const unsigned char *buf, int count)
 {
-	dbg("%s(port = %d, count = %d)", __func__, port->number, count);
-
 	if (!count)
 		return count;
 
@@ -395,8 +382,6 @@
 	int room = 0;
 	unsigned long flags;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	spin_lock_irqsave(&port->lock, flags);
 	room = kfifo_avail(&port->write_fifo);
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -410,8 +395,6 @@
 	int chars = 0;
 	unsigned long flags;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	spin_lock_irqsave(&port->lock, flags);
 	chars = kfifo_len(&port->write_fifo);
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -437,8 +420,6 @@
 	__le16 divisor;
 	int br;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	if (!tty) {
 		dbg("%s(): no tty structures", __func__);
 		return;
@@ -545,8 +526,6 @@
 	unsigned long flags;
 	int result;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	usb_clear_halt(serial->dev, port->write_urb->pipe);
 	usb_clear_halt(serial->dev, port->read_urb->pipe);
 
@@ -602,8 +581,6 @@
 	struct oti6858_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
 	spin_lock_irqsave(&port->lock, flags);
 	/* clear out any remaining data in the buffer */
 	kfifo_reset_out(&port->write_fifo);
@@ -633,9 +610,6 @@
 	dbg("%s(port = %d, set = 0x%08x, clear = 0x%08x)",
 				__func__, port->number, set, clear);
 
-	if (!usb_get_intfdata(port->serial->interface))
-		return -ENODEV;
-
 	/* FIXME: check if this is correct (active high/low) */
 	spin_lock_irqsave(&priv->lock, flags);
 	control = priv->pending_setup.control;
@@ -663,11 +637,6 @@
 	unsigned pin_state;
 	unsigned result = 0;
 
-	dbg("%s(port = %d)", __func__, port->number);
-
-	if (!usb_get_intfdata(port->serial->interface))
-		return -ENODEV;
-
 	spin_lock_irqsave(&priv->lock, flags);
 	pin_state = priv->status.pin_state & PIN_MASK;
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -750,8 +719,6 @@
 {
 	int i;
 
-	dbg("%s()", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i)
 		kfree(usb_get_serial_port_data(serial->port[i]));
 }
@@ -763,9 +730,6 @@
 	int transient = 0, can_recv = 0, resubmit = 1;
 	int status = urb->status;
 
-	dbg("%s(port = %d, status = %d)",
-				__func__, port->number, status);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -882,9 +846,6 @@
 	int status = urb->status;
 	int result;
 
-	dbg("%s(port = %d, status = %d)",
-				__func__, port->number, status);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->flags.read_urb_in_use = 0;
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -916,9 +877,6 @@
 	int status = urb->status;
 	int result;
 
-	dbg("%s(port = %d, status = %d)",
-				__func__, port->number, status);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -958,7 +916,7 @@
 	}
 }
 
-module_usb_serial_driver(oti6858_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(OTI6858_DESCRIPTION);
 MODULE_AUTHOR(OTI6858_AUTHOR);
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index a1a9062..13b8dd6 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -38,8 +38,6 @@
 
 static bool debug;
 
-#define PL2303_CLOSING_WAIT	(30*HZ)
-
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
@@ -97,16 +95,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver pl2303_driver = {
-	.name =		"pl2303",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-	.suspend =      usb_serial_suspend,
-	.resume =       usb_serial_resume,
-	.supports_autosuspend =	1,
-};
-
 #define SET_LINE_REQUEST_TYPE		0x21
 #define SET_LINE_REQUEST		0x20
 
@@ -161,8 +149,9 @@
 	int res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 			VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE,
 			value, index, buf, 1, 100);
-	dbg("0x%x:0x%x:0x%x:0x%x  %d - %x", VENDOR_READ_REQUEST_TYPE,
-			VENDOR_READ_REQUEST, value, index, res, buf[0]);
+	dev_dbg(&serial->dev->dev, "0x%x:0x%x:0x%x:0x%x  %d - %x\n",
+		VENDOR_READ_REQUEST_TYPE, VENDOR_READ_REQUEST, value, index,
+		res, buf[0]);
 	return res;
 }
 
@@ -172,8 +161,9 @@
 	int res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE,
 			value, index, NULL, 0, 100);
-	dbg("0x%x:0x%x:0x%x:0x%x  %d", VENDOR_WRITE_REQUEST_TYPE,
-			VENDOR_WRITE_REQUEST, value, index, res);
+	dev_dbg(&serial->dev->dev, "0x%x:0x%x:0x%x:0x%x  %d\n",
+		VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, value, index,
+		res);
 	return res;
 }
 
@@ -196,7 +186,7 @@
 		type = type_1;
 	else if (serial->dev->descriptor.bDeviceClass == 0xFF)
 		type = type_1;
-	dbg("device type: %d", type);
+	dev_dbg(&serial->interface->dev, "device type: %d\n", type);
 
 	for (i = 0; i < serial->num_ports; ++i) {
 		priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);
@@ -243,7 +233,8 @@
 	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 				 SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
 				 value, 0, NULL, 0, 100);
-	dbg("%s - value = %d, retval = %d", __func__, value, retval);
+	dev_dbg(&dev->dev, "%s - value = %d, retval = %d\n", __func__,
+		value, retval);
 	return retval;
 }
 
@@ -265,8 +256,6 @@
 	int baud_floor, baud_ceil;
 	int k;
 
-	dbg("%s -  port %d", __func__, port->number);
-
 	/* The PL2303 is reported to lose bytes if you change
 	   serial settings even to the same values as before. Thus
 	   we actually need to filter in this specific case */
@@ -287,7 +276,7 @@
 	i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 			    GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
 			    0, 0, buf, 7, 100);
-	dbg("0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x", i,
+	dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x\n", i,
 	    buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
 
 	if (cflag & CSIZE) {
@@ -306,7 +295,7 @@
 			buf[6] = 8;
 			break;
 		}
-		dbg("%s - data bits = %d", __func__, buf[6]);
+		dev_dbg(&port->dev, "data bits = %d\n", buf[6]);
 	}
 
 	/* For reference buf[0]:buf[3] baud rate value */
@@ -315,7 +304,7 @@
 	 *          9600 baud (at least my PL2303X always does)
 	 */
 	baud = tty_get_baud_rate(tty);
-	dbg("%s - baud requested = %d", __func__, baud);
+	dev_dbg(&port->dev, "baud requested = %d\n", baud);
 	if (baud) {
 		/* Set baudrate to nearest supported value */
 		for (k=0; k<ARRAY_SIZE(baud_sup); k++) {
@@ -341,7 +330,7 @@
 			else if (baud > 6000000)
 				baud = 6000000;
 		}
-		dbg("%s - baud set = %d", __func__, baud);
+		dev_dbg(&port->dev, "baud set = %d\n", baud);
 		if (baud <= 115200) {
 			buf[0] = baud & 0xff;
 			buf[1] = (baud >> 8) & 0xff;
@@ -372,14 +361,14 @@
 		 */
 		if ((cflag & CSIZE) == CS5) {
 			buf[4] = 1;
-			dbg("%s - stop bits = 1.5", __func__);
+			dev_dbg(&port->dev, "stop bits = 1.5\n");
 		} else {
 			buf[4] = 2;
-			dbg("%s - stop bits = 2", __func__);
+			dev_dbg(&port->dev, "stop bits = 2\n");
 		}
 	} else {
 		buf[4] = 0;
-		dbg("%s - stop bits = 1", __func__);
+		dev_dbg(&port->dev, "stop bits = 1\n");
 	}
 
 	if (cflag & PARENB) {
@@ -391,29 +380,29 @@
 		if (cflag & PARODD) {
 			if (cflag & CMSPAR) {
 				buf[5] = 3;
-				dbg("%s - parity = mark", __func__);
+				dev_dbg(&port->dev, "parity = mark\n");
 			} else {
 				buf[5] = 1;
-				dbg("%s - parity = odd", __func__);
+				dev_dbg(&port->dev, "parity = odd\n");
 			}
 		} else {
 			if (cflag & CMSPAR) {
 				buf[5] = 4;
-				dbg("%s - parity = space", __func__);
+				dev_dbg(&port->dev, "parity = space\n");
 			} else {
 				buf[5] = 2;
-				dbg("%s - parity = even", __func__);
+				dev_dbg(&port->dev, "parity = even\n");
 			}
 		}
 	} else {
 		buf[5] = 0;
-		dbg("%s - parity = none", __func__);
+		dev_dbg(&port->dev, "parity = none\n");
 	}
 
 	i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 			    SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
 			    0, 0, buf, 7, 100);
-	dbg("0x21:0x20:0:0  %d", i);
+	dev_dbg(&port->dev, "0x21:0x20:0:0  %d\n", i);
 
 	/* change control lines if we are switching to or from B0 */
 	spin_lock_irqsave(&priv->lock, flags);
@@ -435,7 +424,7 @@
 	i = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 			    GET_LINE_REQUEST, GET_LINE_REQUEST_TYPE,
 			    0, 0, buf, 7, 100);
-	dbg("0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x", i,
+	dev_dbg(&port->dev, "0xa1:0x21:0:0  %d - %x %x %x %x %x %x %x\n", i,
 	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
 
 	if (cflag & CRTSCTS) {
@@ -473,8 +462,6 @@
 
 static void pl2303_close(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __func__, port->number);
-
 	usb_serial_generic_close(port);
 	usb_kill_urb(port->interrupt_in_urb);
 }
@@ -486,8 +473,6 @@
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	int result;
 
-	dbg("%s -  port %d", __func__, port->number);
-
 	if (priv->type != HX) {
 		usb_clear_halt(serial->dev, port->write_urb->pipe);
 		usb_clear_halt(serial->dev, port->read_urb->pipe);
@@ -501,7 +486,6 @@
 	if (tty)
 		pl2303_set_termios(tty, port, &tmp_termios);
 
-	dbg("%s - submitting interrupt urb", __func__);
 	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 	if (result) {
 		dev_err(&port->dev, "%s - failed submitting interrupt urb,"
@@ -523,12 +507,11 @@
 			   unsigned int set, unsigned int clear)
 {
 	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 	u8 control;
-
-	if (!usb_get_intfdata(port->serial->interface))
-		return -ENODEV;
+	int ret;
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (set & TIOCM_RTS)
@@ -542,7 +525,14 @@
 	control = priv->line_control;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return set_control_lines(port->serial->dev, control);
+	mutex_lock(&serial->disc_mutex);
+	if (!serial->disconnected)
+		ret = set_control_lines(serial->dev, control);
+	else
+		ret = -ENODEV;
+	mutex_unlock(&serial->disc_mutex);
+
+	return ret;
 }
 
 static int pl2303_tiocmget(struct tty_struct *tty)
@@ -554,11 +544,6 @@
 	unsigned int status;
 	unsigned int result;
 
-	dbg("%s (%d)", __func__, port->number);
-
-	if (!usb_get_intfdata(port->serial->interface))
-		return -ENODEV;
-
 	spin_lock_irqsave(&priv->lock, flags);
 	mcr = priv->line_control;
 	status = priv->line_status;
@@ -571,7 +556,7 @@
 		  | ((status & UART_RING)	? TIOCM_RI  : 0)
 		  | ((status & UART_DCD)	? TIOCM_CD  : 0);
 
-	dbg("%s - result = %x", __func__, result);
+	dev_dbg(&port->dev, "%s - result = %x\n", __func__, result);
 
 	return result;
 }
@@ -625,7 +610,8 @@
 {
 	struct serial_struct ser;
 	struct usb_serial_port *port = tty->driver_data;
-	dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
+
+	dev_dbg(&port->dev, "%s cmd = 0x%04x\n", __func__, cmd);
 
 	switch (cmd) {
 	case TIOCGSERIAL:
@@ -641,10 +627,10 @@
 		return 0;
 
 	case TIOCMIWAIT:
-		dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+		dev_dbg(&port->dev, "%s TIOCMIWAIT\n", __func__);
 		return wait_modem_info(port, arg);
 	default:
-		dbg("%s not supported = 0x%04x", __func__, cmd);
+		dev_dbg(&port->dev, "%s not supported = 0x%04x\n", __func__, cmd);
 		break;
 	}
 	return -ENOIOCTLCMD;
@@ -657,20 +643,18 @@
 	u16 state;
 	int result;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (break_state == 0)
 		state = BREAK_OFF;
 	else
 		state = BREAK_ON;
-	dbg("%s - turning break %s", __func__,
+	dev_dbg(&port->dev, "%s - turning break %s\n", __func__,
 			state == BREAK_OFF ? "off" : "on");
 
 	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
 				 BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
 				 0, NULL, 0, 100);
 	if (result)
-		dbg("%s - error sending break = %d", __func__, result);
+		dev_err(&port->dev, "error sending break = %d\n", result);
 }
 
 static void pl2303_release(struct usb_serial *serial)
@@ -678,8 +662,6 @@
 	int i;
 	struct pl2303_private *priv;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		priv = usb_get_serial_port_data(serial->port[i]);
 		kfree(priv);
@@ -742,8 +724,6 @@
 	int status = urb->status;
 	int retval;
 
-	dbg("%s (%d)", __func__, port->number);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -752,12 +732,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __func__,
-		    status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __func__,
-		    status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
@@ -769,7 +749,7 @@
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		dev_err(&urb->dev->dev,
+		dev_err(&port->dev,
 			"%s - usb_submit_urb failed with result %d\n",
 			__func__, retval);
 }
@@ -807,7 +787,7 @@
 		tty_flag = TTY_PARITY;
 	else if (line_status & UART_FRAME_ERROR)
 		tty_flag = TTY_FRAME;
-	dbg("%s - tty_flag = %d", __func__, tty_flag);
+	dev_dbg(&port->dev, "%s - tty_flag = %d\n", __func__, tty_flag);
 
 	/* overrun is special, not associated with a char */
 	if (line_status & UART_OVERRUN_ERROR)
@@ -855,7 +835,7 @@
 	&pl2303_device, NULL
 };
 
-module_usb_serial_driver(pl2303_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
index 9662456..a4edc7e 100644
--- a/drivers/usb/serial/qcaux.c
+++ b/drivers/usb/serial/qcaux.c
@@ -77,13 +77,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver qcaux_driver = {
-	.name =		"qcaux",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver qcaux_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -97,5 +90,5 @@
 	&qcaux_device, NULL
 };
 
-module_usb_serial_driver(qcaux_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 0206b10..0d5fe59 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -112,32 +112,22 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver qcdriver = {
-	.name			= "qcserial",
-	.probe			= usb_serial_probe,
-	.disconnect		= usb_serial_disconnect,
-	.id_table		= id_table,
-	.suspend		= usb_serial_suspend,
-	.resume			= usb_serial_resume,
-	.supports_autosuspend	= true,
-};
-
 static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 {
 	struct usb_wwan_intf_private *data;
 	struct usb_host_interface *intf = serial->interface->cur_altsetting;
+	struct device *dev = &serial->dev->dev;
 	int retval = -ENODEV;
 	__u8 nintf;
 	__u8 ifnum;
 	bool is_gobi1k = id->driver_info ? true : false;
 
-	dbg("%s", __func__);
-	dbg("Is Gobi 1000 = %d", is_gobi1k);
+	dev_dbg(dev, "Is Gobi 1000 = %d\n", is_gobi1k);
 
 	nintf = serial->dev->actconfig->desc.bNumInterfaces;
-	dbg("Num Interfaces = %d", nintf);
+	dev_dbg(dev, "Num Interfaces = %d\n", nintf);
 	ifnum = intf->desc.bInterfaceNumber;
-	dbg("This Interface = %d", ifnum);
+	dev_dbg(dev, "This Interface = %d\n", ifnum);
 
 	data = kzalloc(sizeof(struct usb_wwan_intf_private),
 					 GFP_KERNEL);
@@ -158,7 +148,7 @@
 		if (intf->desc.bNumEndpoints == 2 &&
 		    usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) &&
 		    usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
-			dbg("QDL port found");
+			dev_dbg(dev, "QDL port found\n");
 
 			if (serial->interface->num_altsetting == 1) {
 				retval = 0; /* Success */
@@ -167,7 +157,7 @@
 
 			retval = usb_set_interface(serial->dev, ifnum, 1);
 			if (retval < 0) {
-				dev_err(&serial->dev->dev,
+				dev_err(dev,
 					"Could not set interface, error %d\n",
 					retval);
 				retval = -ENODEV;
@@ -196,20 +186,20 @@
 		 */
 
 		if (ifnum == 1 && !is_gobi1k) {
-			dbg("Gobi 2K+ DM/DIAG interface found");
+			dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n");
 			retval = usb_set_interface(serial->dev, ifnum, 0);
 			if (retval < 0) {
-				dev_err(&serial->dev->dev,
+				dev_err(dev,
 					"Could not set interface, error %d\n",
 					retval);
 				retval = -ENODEV;
 				kfree(data);
 			}
 		} else if (ifnum == 2) {
-			dbg("Modem port found");
+			dev_dbg(dev, "Modem port found\n");
 			retval = usb_set_interface(serial->dev, ifnum, 0);
 			if (retval < 0) {
-				dev_err(&serial->dev->dev,
+				dev_err(dev,
 					"Could not set interface, error %d\n",
 					retval);
 				retval = -ENODEV;
@@ -221,10 +211,10 @@
 			 * # echo "\$GPS_START" > /dev/ttyUSBx
 			 * # echo "\$GPS_STOP"  > /dev/ttyUSBx
 			 */
-			dbg("Gobi 2K+ NMEA GPS interface found");
+			dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n");
 			retval = usb_set_interface(serial->dev, ifnum, 0);
 			if (retval < 0) {
-				dev_err(&serial->dev->dev,
+				dev_err(dev,
 					"Could not set interface, error %d\n",
 					retval);
 				retval = -ENODEV;
@@ -234,8 +224,7 @@
 		break;
 
 	default:
-		dev_err(&serial->dev->dev,
-			"unknown number of interfaces: %d\n", nintf);
+		dev_err(dev, "unknown number of interfaces: %d\n", nintf);
 		kfree(data);
 		retval = -ENODEV;
 	}
@@ -250,8 +239,6 @@
 {
 	struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
 
-	dbg("%s", __func__);
-
 	/* Call usb_wwan release & free the private data allocated in qcprobe */
 	usb_wwan_release(serial);
 	usb_set_serial_data(serial, NULL);
@@ -285,7 +272,7 @@
 	&qcdevice, NULL
 };
 
-module_usb_serial_driver(qcdriver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
new file mode 100644
index 0000000..8dd88eb
--- /dev/null
+++ b/drivers/usb/serial/quatech2.c
@@ -0,0 +1,1155 @@
+/*
+ * usb-serial driver for Quatech USB 2 devices
+ *
+ * Copyright (C) 2012 Bill Pemberton (wfp5p@virginia.edu)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ *
+ *  These devices all have only 1 bulk in and 1 bulk out that is shared
+ *  for all serial ports.
+ *
+ */
+
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/serial_reg.h>
+#include <linux/uaccess.h>
+
+static bool debug;
+
+/* default urb timeout for usb operations */
+#define QT2_USB_TIMEOUT USB_CTRL_SET_TIMEOUT
+
+#define QT_OPEN_CLOSE_CHANNEL       0xca
+#define QT_SET_GET_DEVICE           0xc2
+#define QT_SET_GET_REGISTER         0xc0
+#define QT_GET_SET_PREBUF_TRIG_LVL  0xcc
+#define QT_SET_ATF                  0xcd
+#define QT_TRANSFER_IN              0xc0
+#define QT_HW_FLOW_CONTROL_MASK     0xc5
+#define QT_SW_FLOW_CONTROL_MASK     0xc6
+#define QT2_BREAK_CONTROL	    0xc8
+#define QT2_GET_SET_UART            0xc1
+#define QT2_FLUSH_DEVICE	    0xc4
+#define QT2_GET_SET_QMCR            0xe1
+#define QT2_QMCR_RS232              0x40
+#define QT2_QMCR_RS422              0x10
+
+#define  SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS)
+
+#define  SERIAL_EVEN_PARITY         (UART_LCR_PARITY | UART_LCR_EPAR)
+
+/* status bytes for the device */
+#define QT2_CONTROL_BYTE    0x1b
+#define QT2_LINE_STATUS     0x00  /* following 1 byte is line status */
+#define QT2_MODEM_STATUS    0x01  /* following 1 byte is modem status */
+#define QT2_XMIT_HOLD       0x02  /* following 2 bytes are ?? */
+#define QT2_CHANGE_PORT     0x03  /* following 1 byte is port to change to */
+#define QT2_REC_FLUSH       0x04  /* no following info */
+#define QT2_XMIT_FLUSH      0x05  /* no following info */
+#define QT2_CONTROL_ESCAPE  0xff  /* pass through previous 2 control bytes */
+
+#define  MAX_BAUD_RATE              921600
+#define  DEFAULT_BAUD_RATE          9600
+
+#define QT2_WRITE_BUFFER_SIZE   512  /* size of write buffer */
+#define QT2_WRITE_CONTROL_SIZE  5    /* control bytes used for a write */
+
+/* Version Information */
+#define DRIVER_VERSION "v0.1"
+#define DRIVER_DESC "Quatech 2nd gen USB to Serial Driver"
+
+#define	USB_VENDOR_ID_QUATECH	0x061d
+#define QUATECH_SSU2_100	0xC120	/* RS232 single port */
+#define QUATECH_DSU2_100	0xC140	/* RS232 dual port */
+#define QUATECH_DSU2_400	0xC150	/* RS232/422/485 dual port */
+#define QUATECH_QSU2_100	0xC160	/* RS232 four port */
+#define QUATECH_QSU2_400	0xC170	/* RS232/422/485 four port */
+#define QUATECH_ESU2_100	0xC1A0	/* RS232 eight port */
+#define QUATECH_ESU2_400	0xC180	/* RS232/422/485 eight port */
+
+struct qt2_device_detail {
+	int product_id;
+	int num_ports;
+};
+
+#define QT_DETAILS(prod, ports)	\
+	.product_id = (prod),   \
+	.num_ports = (ports)
+
+static const struct qt2_device_detail qt2_device_details[] = {
+	{QT_DETAILS(QUATECH_SSU2_100, 1)},
+	{QT_DETAILS(QUATECH_DSU2_400, 2)},
+	{QT_DETAILS(QUATECH_DSU2_100, 2)},
+	{QT_DETAILS(QUATECH_QSU2_400, 4)},
+	{QT_DETAILS(QUATECH_QSU2_100, 4)},
+	{QT_DETAILS(QUATECH_ESU2_400, 8)},
+	{QT_DETAILS(QUATECH_ESU2_100, 8)},
+	{QT_DETAILS(0, 0)}	/* Terminating entry */
+};
+
+static const struct usb_device_id id_table[] = {
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_400)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_400)},
+	{}			/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+struct qt2_serial_private {
+	unsigned char current_port;  /* current port for incoming data */
+
+	struct urb	*read_urb;   /* shared among all ports */
+	char		read_buffer[512];
+};
+
+struct qt2_port_private {
+	bool is_open;
+	u8   device_port;
+
+	spinlock_t urb_lock;
+	bool       urb_in_use;
+	struct urb *write_urb;
+	char       write_buffer[QT2_WRITE_BUFFER_SIZE];
+
+	spinlock_t  lock;
+	u8          shadowLSR;
+	u8          shadowMSR;
+
+	wait_queue_head_t   delta_msr_wait; /* Used for TIOCMIWAIT */
+	struct async_icount icount;
+
+	struct usb_serial_port *port;
+};
+
+static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch);
+static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch);
+static void qt2_write_bulk_callback(struct urb *urb);
+static void qt2_read_bulk_callback(struct urb *urb);
+
+static void qt2_release(struct usb_serial *serial)
+{
+	int i;
+
+	kfree(usb_get_serial_data(serial));
+
+	for (i = 0; i < serial->num_ports; i++)
+		kfree(usb_get_serial_port_data(serial->port[i]));
+}
+
+static inline int calc_baud_divisor(int baudrate)
+{
+	int divisor, rem;
+
+	divisor = MAX_BAUD_RATE / baudrate;
+	rem = MAX_BAUD_RATE % baudrate;
+	/* Round to nearest divisor */
+	if (((rem * 2) >= baudrate) && (baudrate != 110))
+		divisor++;
+
+	return divisor;
+}
+
+static inline int qt2_set_port_config(struct usb_device *dev,
+				      unsigned char port_number,
+				      u16 baudrate, u16 lcr)
+{
+	int divisor = calc_baud_divisor(baudrate);
+	u16 index = ((u16) (lcr << 8) | (u16) (port_number));
+
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			       QT2_GET_SET_UART, 0x40,
+			       divisor, index, NULL, 0, QT2_USB_TIMEOUT);
+}
+
+static inline int qt2_control_msg(struct usb_device *dev,
+				  u8 request, u16 data, u16 index)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			       request, 0x40, data, index,
+			       NULL, 0, QT2_USB_TIMEOUT);
+}
+
+static inline int qt2_setdevice(struct usb_device *dev, u8 *data)
+{
+	u16 x = ((u16) (data[1] << 8) | (u16) (data[0]));
+
+	return qt2_control_msg(dev, QT_SET_GET_DEVICE, x, 0);
+}
+
+
+static inline int qt2_getdevice(struct usb_device *dev, u8 *data)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			       QT_SET_GET_DEVICE, 0xc0, 0, 0,
+			       data, 3, QT2_USB_TIMEOUT);
+}
+
+static inline int qt2_getregister(struct usb_device *dev,
+				  u8 uart,
+				  u8 reg,
+				  u8 *data)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			       QT_SET_GET_REGISTER, 0xc0, reg,
+			       uart, data, sizeof(*data), QT2_USB_TIMEOUT);
+
+}
+
+static inline int qt2_setregister(struct usb_device *dev,
+				  u8 uart, u8 reg, u16 data)
+{
+	u16 value = (data << 8) | reg;
+
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			       QT_SET_GET_REGISTER, 0x40, value, uart,
+			       NULL, 0, QT2_USB_TIMEOUT);
+}
+
+static inline int update_mctrl(struct qt2_port_private *port_priv,
+			       unsigned int set, unsigned int clear)
+{
+	struct usb_serial_port *port = port_priv->port;
+	struct usb_device *dev = port->serial->dev;
+	unsigned urb_value;
+	int status;
+
+	if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
+		dev_dbg(&port->dev,
+			"update_mctrl - DTR|RTS not being set|cleared\n");
+		return 0;	/* no change */
+	}
+
+	clear &= ~set;	/* 'set' takes precedence over 'clear' */
+	urb_value = 0;
+	if (set & TIOCM_DTR)
+		urb_value |= UART_MCR_DTR;
+	if (set & TIOCM_RTS)
+		urb_value |= UART_MCR_RTS;
+
+	status = qt2_setregister(dev, port_priv->device_port, UART_MCR,
+				 urb_value);
+	if (status < 0)
+		dev_err(&port->dev,
+			"update_mctrl - Error from MODEM_CTRL urb: %i\n",
+			status);
+	return status;
+}
+
+static int qt2_calc_num_ports(struct usb_serial *serial)
+{
+	struct qt2_device_detail d;
+	int i;
+
+	for (i = 0; d = qt2_device_details[i], d.product_id != 0; i++) {
+		if (d.product_id == le16_to_cpu(serial->dev->descriptor.idProduct))
+			return d.num_ports;
+	}
+
+	/* we didn't recognize the device */
+	dev_err(&serial->dev->dev,
+		 "don't know the number of ports, assuming 1\n");
+
+	return 1;
+}
+
+static void qt2_set_termios(struct tty_struct *tty,
+			    struct usb_serial_port *port,
+			    struct ktermios *old_termios)
+{
+	struct usb_device *dev = port->serial->dev;
+	struct qt2_port_private *port_priv;
+	struct ktermios *termios = tty->termios;
+	u16 baud;
+	unsigned int cflag = termios->c_cflag;
+	u16 new_lcr = 0;
+	int status;
+
+	port_priv = usb_get_serial_port_data(port);
+
+	if (cflag & PARENB) {
+		if (cflag & PARODD)
+			new_lcr |= UART_LCR_PARITY;
+		else
+			new_lcr |= SERIAL_EVEN_PARITY;
+	}
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		new_lcr |= UART_LCR_WLEN5;
+		break;
+	case CS6:
+		new_lcr |= UART_LCR_WLEN6;
+		break;
+	case CS7:
+		new_lcr |= UART_LCR_WLEN7;
+		break;
+	default:
+	case CS8:
+		new_lcr |= UART_LCR_WLEN8;
+		break;
+	}
+
+	baud = tty_get_baud_rate(tty);
+	if (!baud)
+		baud = 9600;
+
+	status = qt2_set_port_config(dev, port_priv->device_port, baud,
+				     new_lcr);
+	if (status < 0)
+		dev_err(&port->dev, "%s - qt2_set_port_config failed: %i\n",
+			__func__, status);
+
+	if (cflag & CRTSCTS)
+		status = qt2_control_msg(dev, QT_HW_FLOW_CONTROL_MASK,
+					 SERIAL_CRTSCTS,
+					 port_priv->device_port);
+	else
+		status = qt2_control_msg(dev, QT_HW_FLOW_CONTROL_MASK,
+					 0, port_priv->device_port);
+	if (status < 0)
+		dev_err(&port->dev, "%s - set HW flow control failed: %i\n",
+			__func__, status);
+
+	if (I_IXOFF(tty) || I_IXON(tty)) {
+		u16 x = ((u16) (START_CHAR(tty) << 8) | (u16) (STOP_CHAR(tty)));
+
+		status = qt2_control_msg(dev, QT_SW_FLOW_CONTROL_MASK,
+					 x, port_priv->device_port);
+	} else
+		status = qt2_control_msg(dev, QT_SW_FLOW_CONTROL_MASK,
+					 0, port_priv->device_port);
+
+	if (status < 0)
+		dev_err(&port->dev, "%s - set SW flow control failed: %i\n",
+			__func__, status);
+
+}
+
+static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
+{
+	struct usb_serial *serial;
+	struct qt2_serial_private *serial_priv;
+	struct qt2_port_private *port_priv;
+	u8 *data;
+	u16 device_port;
+	int status;
+	unsigned long flags;
+
+	device_port = (u16) (port->number - port->serial->minor);
+
+	serial = port->serial;
+
+	port_priv = usb_get_serial_port_data(port);
+	serial_priv = usb_get_serial_data(serial);
+
+	/* set the port to RS232 mode */
+	status = qt2_control_msg(serial->dev, QT2_GET_SET_QMCR,
+				 QT2_QMCR_RS232, device_port);
+	if (status < 0) {
+		dev_err(&port->dev,
+			"%s failed to set RS232 mode for port %i error %i\n",
+			__func__, device_port, status);
+		return status;
+	}
+
+	data = kzalloc(2, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* open the port */
+	status = usb_control_msg(serial->dev,
+				 usb_rcvctrlpipe(serial->dev, 0),
+				 QT_OPEN_CLOSE_CHANNEL,
+				 0xc0, 0,
+				 device_port, data, 2, QT2_USB_TIMEOUT);
+
+	if (status < 0) {
+		dev_err(&port->dev, "%s - open port failed %i", __func__,
+			status);
+		kfree(data);
+		return status;
+	}
+
+	spin_lock_irqsave(&port_priv->lock, flags);
+	port_priv->shadowLSR = data[0];
+	port_priv->shadowMSR = data[1];
+	spin_unlock_irqrestore(&port_priv->lock, flags);
+
+	kfree(data);
+
+	/* set to default speed and 8bit word size */
+	status = qt2_set_port_config(serial->dev, device_port,
+				     DEFAULT_BAUD_RATE, UART_LCR_WLEN8);
+	if (status < 0) {
+		dev_err(&port->dev,
+			"%s - initial setup failed for port %i (%i)\n",
+			__func__, port->number, device_port);
+		return status;
+	}
+
+	port_priv->is_open = true;
+	port_priv->device_port = (u8) device_port;
+
+	if (tty)
+		qt2_set_termios(tty, port, tty->termios);
+
+	return 0;
+
+}
+
+static void qt2_close(struct usb_serial_port *port)
+{
+	struct usb_serial *serial;
+	struct qt2_serial_private *serial_priv;
+	struct qt2_port_private *port_priv;
+	unsigned long flags;
+	int i;
+
+	serial = port->serial;
+	serial_priv = usb_get_serial_data(serial);
+	port_priv = usb_get_serial_port_data(port);
+
+	port_priv->is_open = false;
+
+	spin_lock_irqsave(&port_priv->urb_lock, flags);
+	if (port_priv->write_urb->status == -EINPROGRESS)
+		usb_kill_urb(port_priv->write_urb);
+	port_priv->urb_in_use = false;
+	spin_unlock_irqrestore(&port_priv->urb_lock, flags);
+
+	/* flush the port transmit buffer */
+	i = usb_control_msg(serial->dev,
+			    usb_rcvctrlpipe(serial->dev, 0),
+			    QT2_FLUSH_DEVICE, 0x40, 1,
+			    port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT);
+
+	if (i < 0)
+		dev_err(&port->dev, "%s - transmit buffer flush failed: %i\n",
+			__func__, i);
+
+	/* flush the port receive buffer */
+	i = usb_control_msg(serial->dev,
+			    usb_rcvctrlpipe(serial->dev, 0),
+			    QT2_FLUSH_DEVICE, 0x40, 0,
+			    port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT);
+
+	if (i < 0)
+		dev_err(&port->dev, "%s - receive buffer flush failed: %i\n",
+			__func__, i);
+
+	/* close the port */
+	i = usb_control_msg(serial->dev,
+			    usb_sndctrlpipe(serial->dev, 0),
+			    QT_OPEN_CLOSE_CHANNEL,
+			    0x40, 0,
+			    port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT);
+
+	if (i < 0)
+		dev_err(&port->dev, "%s - close port failed %i\n",
+			__func__, i);
+
+}
+
+static void qt2_disconnect(struct usb_serial *serial)
+{
+	struct qt2_serial_private *serial_priv = usb_get_serial_data(serial);
+	struct qt2_port_private *port_priv;
+	int i;
+
+	if (serial_priv->read_urb->status == -EINPROGRESS)
+		usb_kill_urb(serial_priv->read_urb);
+
+	usb_free_urb(serial_priv->read_urb);
+
+	for (i = 0; i < serial->num_ports; i++) {
+		port_priv = usb_get_serial_port_data(serial->port[i]);
+
+		if (port_priv->write_urb->status == -EINPROGRESS)
+			usb_kill_urb(port_priv->write_urb);
+		usb_free_urb(port_priv->write_urb);
+	}
+}
+
+static int get_serial_info(struct usb_serial_port *port,
+			   struct serial_struct __user *retinfo)
+{
+	struct serial_struct tmp;
+
+	if (!retinfo)
+		return -EFAULT;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.line		= port->serial->minor;
+	tmp.port		= 0;
+	tmp.irq			= 0;
+	tmp.flags		= ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+	tmp.xmit_fifo_size	= port->bulk_out_size;
+	tmp.baud_base		= 9600;
+	tmp.close_delay		= 5*HZ;
+	tmp.closing_wait	= 30*HZ;
+
+	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+	struct qt2_port_private *priv = usb_get_serial_port_data(port);
+	struct async_icount prev, cur;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	prev = priv->icount;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	while (1) {
+		wait_event_interruptible(priv->delta_msr_wait,
+					 ((priv->icount.rng != prev.rng) ||
+					  (priv->icount.dsr != prev.dsr) ||
+					  (priv->icount.dcd != prev.dcd) ||
+					  (priv->icount.cts != prev.cts)));
+
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+
+		spin_lock_irqsave(&priv->lock, flags);
+		cur = priv->icount;
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+		if ((prev.rng == cur.rng) &&
+		    (prev.dsr == cur.dsr) &&
+		    (prev.dcd == cur.dcd) &&
+		    (prev.cts == cur.cts))
+			return -EIO;
+
+		if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) ||
+		    (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) ||
+		    (arg & TIOCM_CD && (prev.dcd != cur.dcd)) ||
+		    (arg & TIOCM_CTS && (prev.cts != cur.cts)))
+			return 0;
+	}
+	return 0;
+}
+
+static int qt2_get_icount(struct tty_struct *tty,
+			  struct serial_icounter_struct *icount)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct qt2_port_private *priv = usb_get_serial_port_data(port);
+	struct async_icount cnow = priv->icount;
+
+	icount->cts = cnow.cts;
+	icount->dsr = cnow.dsr;
+	icount->rng = cnow.rng;
+	icount->dcd = cnow.dcd;
+	icount->rx = cnow.rx;
+	icount->tx = cnow.tx;
+	icount->frame = cnow.frame;
+	icount->overrun = cnow.overrun;
+	icount->parity = cnow.parity;
+	icount->brk = cnow.brk;
+	icount->buf_overrun = cnow.buf_overrun;
+
+	return 0;
+}
+
+static int qt2_ioctl(struct tty_struct *tty,
+		     unsigned int cmd, unsigned long arg)
+{
+	struct usb_serial_port *port = tty->driver_data;
+
+	switch (cmd) {
+	case TIOCGSERIAL:
+		return get_serial_info(port,
+				       (struct serial_struct __user *)arg);
+
+	case TIOCMIWAIT:
+		return wait_modem_info(port, arg);
+
+	default:
+		break;
+	}
+
+	return -ENOIOCTLCMD;
+}
+
+static void qt2_process_status(struct usb_serial_port *port, unsigned char *ch)
+{
+	switch (*ch) {
+	case QT2_LINE_STATUS:
+		qt2_update_lsr(port, ch + 1);
+		break;
+	case QT2_MODEM_STATUS:
+		qt2_update_msr(port, ch + 1);
+		break;
+	}
+}
+
+/* not needed, kept to document functionality */
+static void qt2_process_xmit_empty(struct usb_serial_port *port,
+				   unsigned char *ch)
+{
+	int bytes_written;
+
+	bytes_written = (int)(*ch) + (int)(*(ch + 1) << 4);
+}
+
+/* not needed, kept to document functionality */
+static void qt2_process_flush(struct usb_serial_port *port, unsigned char *ch)
+{
+	return;
+}
+
+void qt2_process_read_urb(struct urb *urb)
+{
+	struct usb_serial *serial;
+	struct qt2_serial_private *serial_priv;
+	struct usb_serial_port *port;
+	struct qt2_port_private *port_priv;
+	struct tty_struct *tty;
+	bool escapeflag;
+	unsigned char *ch;
+	int i;
+	unsigned char newport;
+	int len = urb->actual_length;
+
+	if (!len)
+		return;
+
+	ch = urb->transfer_buffer;
+	tty = NULL;
+	serial = urb->context;
+	serial_priv = usb_get_serial_data(serial);
+	port = serial->port[serial_priv->current_port];
+	port_priv = usb_get_serial_port_data(port);
+
+	if (port_priv->is_open)
+		tty = tty_port_tty_get(&port->port);
+
+	for (i = 0; i < urb->actual_length; i++) {
+		ch = (unsigned char *)urb->transfer_buffer + i;
+		if ((i <= (len - 3)) &&
+		    (*ch == QT2_CONTROL_BYTE) &&
+		    (*(ch + 1) == QT2_CONTROL_BYTE)) {
+			escapeflag = false;
+			switch (*(ch + 2)) {
+			case QT2_LINE_STATUS:
+			case QT2_MODEM_STATUS:
+				if (i > (len - 4)) {
+					dev_warn(&port->dev,
+						 "%s - status message too short\n",
+						__func__);
+					break;
+				}
+				qt2_process_status(port, ch + 2);
+				i += 3;
+				escapeflag = true;
+				break;
+			case QT2_XMIT_HOLD:
+				if (i > (len - 5)) {
+					dev_warn(&port->dev,
+						 "%s - xmit_empty message too short\n",
+						 __func__);
+					break;
+				}
+				qt2_process_xmit_empty(port, ch + 3);
+				i += 4;
+				escapeflag = true;
+				break;
+			case QT2_CHANGE_PORT:
+				if (i > (len - 4)) {
+					dev_warn(&port->dev,
+						 "%s - change_port message too short\n",
+						 __func__);
+					break;
+				}
+				if (tty) {
+					tty_flip_buffer_push(tty);
+					tty_kref_put(tty);
+				}
+
+				newport = *(ch + 3);
+
+				if (newport > serial->num_ports) {
+					dev_err(&port->dev,
+						"%s - port change to invalid port: %i\n",
+						__func__, newport);
+					break;
+				}
+
+				serial_priv->current_port = newport;
+				port = serial->port[serial_priv->current_port];
+				port_priv = usb_get_serial_port_data(port);
+				if (port_priv->is_open)
+					tty = tty_port_tty_get(&port->port);
+				else
+					tty = NULL;
+				i += 3;
+				escapeflag = true;
+				break;
+			case QT2_REC_FLUSH:
+			case QT2_XMIT_FLUSH:
+				qt2_process_flush(port, ch + 2);
+				i += 2;
+				escapeflag = true;
+				break;
+			case QT2_CONTROL_ESCAPE:
+				tty_buffer_request_room(tty, 2);
+				tty_insert_flip_string(tty, ch, 2);
+				i += 2;
+				escapeflag = true;
+				break;
+			default:
+				dev_warn(&port->dev,
+					 "%s - unsupported command %i\n",
+					 __func__, *(ch + 2));
+				break;
+			}
+			if (escapeflag)
+				continue;
+		}
+
+		if (tty) {
+			tty_buffer_request_room(tty, 1);
+			tty_insert_flip_string(tty, ch, 1);
+		}
+	}
+
+	if (tty) {
+		tty_flip_buffer_push(tty);
+		tty_kref_put(tty);
+	}
+}
+
+static void qt2_write_bulk_callback(struct urb *urb)
+{
+	struct usb_serial_port *port;
+	struct qt2_port_private *port_priv;
+
+	port = urb->context;
+	port_priv = usb_get_serial_port_data(port);
+
+	spin_lock(&port_priv->urb_lock);
+
+	port_priv->urb_in_use = false;
+	usb_serial_port_softint(port);
+
+	spin_unlock(&port_priv->urb_lock);
+
+}
+
+static void qt2_read_bulk_callback(struct urb *urb)
+{
+	struct usb_serial *serial = urb->context;
+	int status;
+
+	if (urb->status) {
+		dev_warn(&serial->dev->dev,
+			 "%s - non-zero urb status: %i\n", __func__,
+			 urb->status);
+		return;
+	}
+
+	qt2_process_read_urb(urb);
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status != 0)
+		dev_err(&serial->dev->dev,
+			"%s - resubmit read urb failed: %i\n",
+			__func__, status);
+}
+
+static int qt2_setup_urbs(struct usb_serial *serial)
+{
+	struct usb_serial_port *port;
+	struct usb_serial_port *port0;
+	struct qt2_serial_private *serial_priv;
+	struct qt2_port_private *port_priv;
+	int pcount, status;
+
+	port0 = serial->port[0];
+
+	serial_priv = usb_get_serial_data(serial);
+	serial_priv->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!serial_priv->read_urb) {
+		dev_err(&serial->dev->dev, "No free urbs available\n");
+		return -ENOMEM;
+	}
+
+	usb_fill_bulk_urb(serial_priv->read_urb, serial->dev,
+			  usb_rcvbulkpipe(serial->dev,
+					  port0->bulk_in_endpointAddress),
+			  serial_priv->read_buffer,
+			  sizeof(serial_priv->read_buffer),
+			  qt2_read_bulk_callback, serial);
+
+	/* setup write_urb for each port */
+	for (pcount = 0; pcount < serial->num_ports; pcount++) {
+
+		port = serial->port[pcount];
+		port_priv = usb_get_serial_port_data(port);
+
+		port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!port_priv->write_urb) {
+			dev_err(&serial->dev->dev,
+				"failed to alloc write_urb for port %i\n",
+				pcount);
+			return -ENOMEM;
+		}
+
+		usb_fill_bulk_urb(port_priv->write_urb,
+				  serial->dev,
+				  usb_sndbulkpipe(serial->dev,
+						  port0->
+						  bulk_out_endpointAddress),
+				  port_priv->write_buffer,
+				  sizeof(port_priv->write_buffer),
+				  qt2_write_bulk_callback, port);
+	}
+
+	status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL);
+	if (status != 0) {
+		dev_err(&serial->dev->dev,
+			"%s - submit read urb failed %i\n", __func__, status);
+		return status;
+	}
+
+	return 0;
+
+}
+
+static int qt2_attach(struct usb_serial *serial)
+{
+	struct qt2_serial_private *serial_priv;
+	struct qt2_port_private *port_priv;
+	int status, pcount;
+
+	/* power on unit */
+	status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+				 0xc2, 0x40, 0x8000, 0, NULL, 0,
+				 QT2_USB_TIMEOUT);
+	if (status < 0) {
+		dev_err(&serial->dev->dev,
+			"%s - failed to power on unit: %i\n", __func__, status);
+		return status;
+	}
+
+	serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
+	if (!serial_priv) {
+		dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	usb_set_serial_data(serial, serial_priv);
+
+	for (pcount = 0; pcount < serial->num_ports; pcount++) {
+		port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
+		if (!port_priv) {
+			dev_err(&serial->dev->dev,
+				"%s- kmalloc(%Zd) failed.\n", __func__,
+				sizeof(*port_priv));
+			pcount--;
+			status = -ENOMEM;
+			goto attach_failed;
+		}
+
+		spin_lock_init(&port_priv->lock);
+		spin_lock_init(&port_priv->urb_lock);
+		init_waitqueue_head(&port_priv->delta_msr_wait);
+
+		port_priv->port = serial->port[pcount];
+
+		usb_set_serial_port_data(serial->port[pcount], port_priv);
+	}
+
+	status = qt2_setup_urbs(serial);
+	if (status != 0)
+		goto attach_failed;
+
+	return 0;
+
+attach_failed:
+	for (/* empty */; pcount >= 0; pcount--) {
+		port_priv = usb_get_serial_port_data(serial->port[pcount]);
+		kfree(port_priv);
+	}
+	kfree(serial_priv);
+	return status;
+}
+
+static int qt2_tiocmget(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_device *dev = port->serial->dev;
+	struct qt2_port_private *port_priv = usb_get_serial_port_data(port);
+	u8 *d;
+	int r;
+
+	d = kzalloc(2, GFP_KERNEL);
+	if (!d)
+		return -ENOMEM;
+
+	r = qt2_getregister(dev, port_priv->device_port, UART_MCR, d);
+	if (r < 0)
+		goto mget_out;
+
+	r = qt2_getregister(dev, port_priv->device_port, UART_MSR, d + 1);
+	if (r < 0)
+		goto mget_out;
+
+	r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) |
+	    (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) |
+	    (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) |
+	    (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) |
+	    (d[1] & UART_MSR_RI ? TIOCM_RI : 0) |
+	    (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0);
+
+mget_out:
+	kfree(d);
+	return r;
+}
+
+static int qt2_tiocmset(struct tty_struct *tty,
+			unsigned int set, unsigned int clear)
+{
+	struct qt2_port_private *port_priv;
+
+	port_priv = usb_get_serial_port_data(tty->driver_data);
+	return update_mctrl(port_priv, set, clear);
+}
+
+static void qt2_break_ctl(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct qt2_port_private *port_priv;
+	int status;
+	u16 val;
+
+	port_priv = usb_get_serial_port_data(port);
+
+	if (!port_priv->is_open) {
+		dev_err(&port->dev,
+			"%s - port is not open\n", __func__);
+		return;
+	}
+
+	val = (break_state == -1) ? 1 : 0;
+
+	status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL,
+				 val, port_priv->device_port);
+	if (status < 0)
+		dev_warn(&port->dev,
+			 "%s - failed to send control message: %i\n", __func__,
+			 status);
+}
+
+
+
+static void qt2_dtr_rts(struct usb_serial_port *port, int on)
+{
+	struct usb_device *dev = port->serial->dev;
+	struct qt2_port_private *port_priv = usb_get_serial_port_data(port);
+
+	mutex_lock(&port->serial->disc_mutex);
+	if (!port->serial->disconnected) {
+		/* Disable flow control */
+		if (!on && qt2_setregister(dev, port_priv->device_port,
+					   UART_MCR, 0) < 0)
+			dev_warn(&port->dev, "error from flowcontrol urb\n");
+		/* drop RTS and DTR */
+		if (on)
+			update_mctrl(port_priv, TIOCM_DTR | TIOCM_RTS, 0);
+		else
+			update_mctrl(port_priv, 0, TIOCM_DTR | TIOCM_RTS);
+	}
+	mutex_unlock(&port->serial->disc_mutex);
+}
+
+static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
+{
+	struct qt2_port_private *port_priv;
+	u8 newMSR = (u8) *ch;
+	unsigned long flags;
+
+	port_priv = usb_get_serial_port_data(port);
+
+	spin_lock_irqsave(&port_priv->lock, flags);
+	port_priv->shadowMSR = newMSR;
+	spin_unlock_irqrestore(&port_priv->lock, flags);
+
+	if (newMSR & UART_MSR_ANY_DELTA) {
+		/* update input line counters */
+		if (newMSR & UART_MSR_DCTS)
+			port_priv->icount.cts++;
+
+		if (newMSR & UART_MSR_DDSR)
+			port_priv->icount.dsr++;
+
+		if (newMSR & UART_MSR_DDCD)
+			port_priv->icount.dcd++;
+
+		if (newMSR & UART_MSR_TERI)
+			port_priv->icount.rng++;
+
+		wake_up_interruptible(&port_priv->delta_msr_wait);
+	}
+}
+
+static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch)
+{
+	struct qt2_port_private *port_priv;
+	struct async_icount *icount;
+	unsigned long flags;
+	u8 newLSR = (u8) *ch;
+
+	port_priv = usb_get_serial_port_data(port);
+
+	if (newLSR & UART_LSR_BI)
+		newLSR &= (u8) (UART_LSR_OE | UART_LSR_BI);
+
+	spin_lock_irqsave(&port_priv->lock, flags);
+	port_priv->shadowLSR = newLSR;
+	spin_unlock_irqrestore(&port_priv->lock, flags);
+
+	icount = &port_priv->icount;
+
+	if (newLSR & UART_LSR_BRK_ERROR_BITS) {
+
+		if (newLSR & UART_LSR_BI)
+			icount->brk++;
+
+		if (newLSR & UART_LSR_OE)
+			icount->overrun++;
+
+		if (newLSR & UART_LSR_PE)
+			icount->parity++;
+
+		if (newLSR & UART_LSR_FE)
+			icount->frame++;
+	}
+
+}
+
+static int qt2_write_room(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct qt2_port_private *port_priv;
+	unsigned long flags = 0;
+	int r;
+
+	port_priv = usb_get_serial_port_data(port);
+
+	spin_lock_irqsave(&port_priv->urb_lock, flags);
+
+	if (port_priv->urb_in_use)
+		r = 0;
+	else
+		r = QT2_WRITE_BUFFER_SIZE - QT2_WRITE_CONTROL_SIZE;
+
+	spin_unlock_irqrestore(&port_priv->urb_lock, flags);
+
+	return r;
+}
+
+static int qt2_write(struct tty_struct *tty,
+		     struct usb_serial_port *port,
+		     const unsigned char *buf, int count)
+{
+	struct qt2_port_private *port_priv;
+	struct urb *write_urb;
+	unsigned char *data;
+	unsigned long flags;
+	int status;
+	int bytes_out = 0;
+
+	port_priv = usb_get_serial_port_data(port);
+
+	if (port_priv->write_urb == NULL) {
+		dev_err(&port->dev, "%s - no output urb\n", __func__);
+		return 0;
+	}
+	write_urb = port_priv->write_urb;
+
+	count = min(count, QT2_WRITE_BUFFER_SIZE - QT2_WRITE_CONTROL_SIZE);
+
+	data = write_urb->transfer_buffer;
+	spin_lock_irqsave(&port_priv->urb_lock, flags);
+	if (port_priv->urb_in_use == true) {
+		printk(KERN_INFO "qt2_write - urb is in use\n");
+		goto write_out;
+	}
+
+	*data++ = QT2_CONTROL_BYTE;
+	*data++ = QT2_CONTROL_BYTE;
+	*data++ = port_priv->device_port;
+	put_unaligned_le16(count, data);
+	data += 2;
+	memcpy(data, buf, count);
+
+	write_urb->transfer_buffer_length = count + QT2_WRITE_CONTROL_SIZE;
+
+	status = usb_submit_urb(write_urb, GFP_ATOMIC);
+	if (status == 0) {
+		port_priv->urb_in_use = true;
+		bytes_out += count;
+	}
+
+write_out:
+	spin_unlock_irqrestore(&port_priv->urb_lock, flags);
+	return bytes_out;
+}
+
+
+static struct usb_serial_driver qt2_device = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "quatech-serial",
+	},
+	.description	     = DRIVER_DESC,
+	.id_table	     = id_table,
+	.open		     = qt2_open,
+	.close		     = qt2_close,
+	.write               = qt2_write,
+	.write_room          = qt2_write_room,
+	.calc_num_ports      = qt2_calc_num_ports,
+	.attach              = qt2_attach,
+	.release             = qt2_release,
+	.disconnect          = qt2_disconnect,
+	.dtr_rts             = qt2_dtr_rts,
+	.break_ctl           = qt2_break_ctl,
+	.tiocmget            = qt2_tiocmget,
+	.tiocmset            = qt2_tiocmset,
+	.get_icount	     = qt2_get_icount,
+	.ioctl               = qt2_ioctl,
+	.set_termios         = qt2_set_termios,
+};
+
+static struct usb_serial_driver *const serial_drivers[] = {
+	&qt2_device, NULL
+};
+
+module_usb_serial_driver(serial_drivers, id_table);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index ae4ee30..36e9d9f 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -151,13 +151,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver safe_driver = {
-	.name =		"safe_serial",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static const __u16 crc10_table[256] = {
 	0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff,
 	0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
@@ -339,12 +332,12 @@
 		}
 	}
 
-	return usb_serial_register_drivers(&safe_driver, serial_drivers);
+	return usb_serial_register_drivers(serial_drivers, KBUILD_MODNAME, id_table);
 }
 
 static void __exit safe_exit(void)
 {
-	usb_serial_deregister_drivers(&safe_driver, serial_drivers);
+	usb_serial_deregister_drivers(serial_drivers);
 }
 
 module_init(safe_init);
diff --git a/drivers/usb/serial/siemens_mpi.c b/drivers/usb/serial/siemens_mpi.c
index 46c0430..e4a1787 100644
--- a/drivers/usb/serial/siemens_mpi.c
+++ b/drivers/usb/serial/siemens_mpi.c
@@ -29,13 +29,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver siemens_usb_mpi_driver = {
-	.name =		"siemens_mpi",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver siemens_usb_mpi_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -49,7 +42,7 @@
 	&siemens_usb_mpi_device, NULL
 };
 
-module_usb_serial_driver(siemens_usb_mpi_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 8c8bf80..ba54a0a 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -63,9 +63,7 @@
 
 static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
 {
-	int result;
-	dev_dbg(&udev->dev, "%s\n", __func__);
-	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			SWIMS_USB_REQUEST_SetPower,	/* __u8 request      */
 			USB_TYPE_VENDOR,		/* __u8 request type */
 			swiState,			/* __u16 value       */
@@ -73,14 +71,11 @@
 			NULL,				/* void *data        */
 			0,				/* __u16 size 	     */
 			USB_CTRL_SET_TIMEOUT);		/* int timeout 	     */
-	return result;
 }
 
 static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
 {
-	int result;
-	dev_dbg(&udev->dev, "%s\n", __func__);
-	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			SWIMS_USB_REQUEST_SetNmea,	/* __u8 request      */
 			USB_TYPE_VENDOR,		/* __u8 request type */
 			enable,				/* __u16 value       */
@@ -88,7 +83,6 @@
 			NULL,				/* void *data        */
 			0,				/* __u16 size 	     */
 			USB_CTRL_SET_TIMEOUT);		/* int timeout       */
-	return result;
 }
 
 static int sierra_calc_num_ports(struct usb_serial *serial)
@@ -96,8 +90,6 @@
 	int num_ports = 0;
 	u8 ifnum, numendpoints;
 
-	dev_dbg(&serial->dev->dev, "%s\n", __func__);
-
 	ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
 	numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
 
@@ -150,7 +142,6 @@
 	int interface;
 	struct usb_interface *p_interface;
 	struct usb_host_interface *p_host_interface;
-	dev_dbg(&serial->dev->dev, "%s\n", __func__);
 
 	/* Get the interface structure pointer from the serial struct */
 	p_interface = serial->interface;
@@ -175,9 +166,8 @@
 	u8 ifnum;
 
 	udev = serial->dev;
-	dev_dbg(&udev->dev, "%s\n", __func__);
-
 	ifnum = sierra_calc_interface(serial);
+
 	/*
 	 * If this interface supports more than 1 alternate
 	 * select the 2nd one
@@ -344,8 +334,6 @@
 	int do_send = 0;
 	int retval;
 
-	dev_dbg(&port->dev, "%s\n", __func__);
-
 	portdata = usb_get_serial_port_data(port);
 
 	if (portdata->dtr_state)
@@ -393,7 +381,6 @@
 static void sierra_set_termios(struct tty_struct *tty,
 		struct usb_serial_port *port, struct ktermios *old_termios)
 {
-	dev_dbg(&port->dev, "%s\n", __func__);
 	tty_termios_copy_hw(tty->termios, old_termios);
 	sierra_send_setup(port);
 }
@@ -404,7 +391,6 @@
 	unsigned int value;
 	struct sierra_port_private *portdata;
 
-	dev_dbg(&port->dev, "%s\n", __func__);
 	portdata = usb_get_serial_port_data(port);
 
 	value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
@@ -441,8 +427,7 @@
 {
 	struct usb_serial_port *port;
 	if (urb) {
-		port =  urb->context;
-		dev_dbg(&port->dev, "%s: %p\n", __func__, urb);
+		port = urb->context;
 		kfree(urb->transfer_buffer);
 		usb_free_urb(urb);
 	}
@@ -455,7 +440,6 @@
 	struct sierra_intf_private *intfdata;
 	int status = urb->status;
 
-	dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number);
 	intfdata = port->serial->private;
 
 	/* free up the transfer buffer, as usb_free_urb() does not do this */
@@ -598,8 +582,6 @@
 	endpoint = usb_pipeendpoint(urb->pipe);
 	port = urb->context;
 
-	dev_dbg(&port->dev, "%s: %p\n", __func__, urb);
-
 	if (status) {
 		dev_dbg(&port->dev, "%s: nonzero status: %d on"
 			" endpoint %02x\n", __func__, status, endpoint);
@@ -697,8 +679,6 @@
 	struct sierra_port_private *portdata = usb_get_serial_port_data(port);
 	unsigned long flags;
 
-	dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number);
-
 	/* try to give a good number back based on if we have any free urbs at
 	 * this point in time */
 	spin_lock_irqsave(&portdata->lock, flags);
@@ -805,8 +785,6 @@
 	struct sierra_port_private *portdata;
 	struct sierra_intf_private *intfdata = port->serial->private;
 
-
-	dev_dbg(&port->dev, "%s\n", __func__);
 	portdata = usb_get_serial_port_data(port);
 
 	portdata->rts_state = 0;
@@ -851,8 +829,6 @@
 
 	portdata = usb_get_serial_port_data(port);
 
-	dev_dbg(&port->dev, "%s\n", __func__);
-
 	/* Set some sane defaults */
 	portdata->rts_state = 1;
 	portdata->dtr_state = 1;
@@ -915,8 +891,6 @@
 	int i;
 	u8 ifnum;
 
-	dev_dbg(&serial->dev->dev, "%s\n", __func__);
-
 	/* Set Device mode to D0 */
 	sierra_set_power_state(serial->dev, 0x0000);
 
@@ -977,8 +951,6 @@
 	struct usb_serial_port *port;
 	struct sierra_port_private *portdata;
 
-	dev_dbg(&serial->dev->dev, "%s\n", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
 		if (!port)
@@ -1067,29 +1039,11 @@
 	return ec ? -EIO : 0;
 }
 
-static int sierra_reset_resume(struct usb_interface *intf)
-{
-	struct usb_serial *serial = usb_get_intfdata(intf);
-	dev_err(&serial->dev->dev, "%s\n", __func__);
-	return usb_serial_resume(intf);
-}
 #else
 #define sierra_suspend NULL
 #define sierra_resume NULL
-#define sierra_reset_resume NULL
 #endif
 
-static struct usb_driver sierra_driver = {
-	.name       = "sierra",
-	.probe      = usb_serial_probe,
-	.disconnect = usb_serial_disconnect,
-	.suspend    = usb_serial_suspend,
-	.resume     = usb_serial_resume,
-	.reset_resume = sierra_reset_resume,
-	.id_table   = id_table,
-	.supports_autosuspend =	1,
-};
-
 static struct usb_serial_driver sierra_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -1118,7 +1072,7 @@
 	&sierra_device, NULL
 };
 
-module_usb_serial_driver(sierra_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index f06c9a8..cad6089 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -151,14 +151,6 @@
 	SPCP835_TYPE,
 };
 
-static struct usb_driver spcp8x5_driver = {
-	.name =			"spcp8x5",
-	.probe =		usb_serial_probe,
-	.disconnect =		usb_serial_disconnect,
-	.id_table =		id_table,
-};
-
-
 struct spcp8x5_private {
 	spinlock_t 	lock;
 	enum spcp8x5_type	type;
@@ -433,7 +425,7 @@
 	if (i < 0)
 		dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n",
 			uartdata, i);
-	dbg("0x21:0x40:0:0  %d", i);
+	dev_dbg(&port->dev, "0x21:0x40:0:0  %d\n", i);
 
 	if (cflag & CRTSCTS) {
 		/* enable hardware flow control */
@@ -454,8 +446,6 @@
 	u8 status = 0x30;
 	/* status 0x30 means DSR and CTS = 1 other CDC RI and delta = 0 */
 
-	dbg("%s -  port %d", __func__, port->number);
-
 	usb_clear_halt(serial->dev, port->write_urb->pipe);
 	usb_clear_halt(serial->dev, port->read_urb->pipe);
 
@@ -579,15 +569,19 @@
 			 unsigned int cmd, unsigned long arg)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
+
+	dev_dbg(&port->dev, "%s (%d) cmd = 0x%04x\n", __func__,
+		port->number, cmd);
 
 	switch (cmd) {
 	case TIOCMIWAIT:
-		dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+		dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__,
+			port->number);
 		return spcp8x5_wait_modem_info(port, arg);
 
 	default:
-		dbg("%s not supported = 0x%04x", __func__, cmd);
+		dev_dbg(&port->dev, "%s not supported = 0x%04x", __func__,
+			cmd);
 		break;
 	}
 
@@ -666,7 +660,7 @@
 	&spcp8x5_device, NULL
 };
 
-module_usb_serial_driver(spcp8x5_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 3cdc8a5..3fee23b 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -59,20 +59,8 @@
 	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)},
 	{}			/* Terminating entry */
 };
-
 MODULE_DEVICE_TABLE(usb, id_table);
 
-
-static struct usb_driver ssu100_driver = {
-	.name			       = "ssu100",
-	.probe			       = usb_serial_probe,
-	.disconnect		       = usb_serial_disconnect,
-	.id_table		       = id_table,
-	.suspend		       = usb_serial_suspend,
-	.resume			       = usb_serial_resume,
-	.supports_autosuspend	       = 1,
-};
-
 struct ssu100_port_private {
 	spinlock_t status_lock;
 	u8 shadowLSR;
@@ -85,7 +73,6 @@
 {
 	struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port);
 
-	dbg("%s", __func__);
 	kfree(priv);
 }
 
@@ -171,8 +158,6 @@
 	u8 *data;
 	int result = 0;
 
-	dbg("%s", __func__);
-
 	data = kzalloc(3, GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
@@ -237,8 +222,6 @@
 	u16 urb_value = 0; /* will hold the new flags */
 	int result;
 
-	dbg("%s", __func__);
-
 	if (cflag & PARENB) {
 		if (cflag & PARODD)
 			urb_value |= UART_LCR_PARITY;
@@ -312,8 +295,6 @@
 	int result;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	data = kzalloc(2, GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
@@ -348,7 +329,6 @@
 
 static void ssu100_close(struct usb_serial_port *port)
 {
-	dbg("%s", __func__);
 	usb_serial_generic_close(port);
 }
 
@@ -467,8 +447,6 @@
 	struct ssu100_port_private *priv;
 	struct usb_serial_port *port = *serial->port;
 
-	dbg("%s", __func__);
-
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
 		dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
@@ -490,8 +468,6 @@
 	u8 *d;
 	int r;
 
-	dbg("%s\n", __func__);
-
 	d = kzalloc(2, GFP_KERNEL);
 	if (!d)
 		return -ENOMEM;
@@ -522,7 +498,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct usb_device *dev = port->serial->dev;
 
-	dbg("%s\n", __func__);
 	return update_mctrl(dev, set, clear);
 }
 
@@ -530,8 +505,6 @@
 {
 	struct usb_device *dev = port->serial->dev;
 
-	dbg("%s\n", __func__);
-
 	mutex_lock(&port->serial->disc_mutex);
 	if (!port->serial->disconnected) {
 		/* Disable flow control */
@@ -618,8 +591,6 @@
 	int i;
 	char *ch;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if ((len >= 4) &&
 	    (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
 	    ((packet[2] == 0x00) || (packet[2] == 0x01))) {
@@ -656,8 +627,6 @@
 	struct tty_struct *tty;
 	int count;
 
-	dbg("%s", __func__);
-
 	tty = tty_port_tty_get(&port->port);
 	if (!tty)
 		return;
@@ -695,7 +664,7 @@
 	&ssu100_device, NULL
 };
 
-module_usb_serial_driver(ssu100_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 1a5be13..e53d2aa 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -54,8 +54,6 @@
 	int result;
 	int data_length;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	switch (status) {
 	case 0:
 		/* success */
@@ -64,12 +62,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
@@ -125,8 +123,6 @@
 	unsigned long flags;
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->throttled = false;
 	priv->actually_throttled = false;
@@ -150,8 +146,6 @@
 {
 	struct symbol_private *priv = usb_get_serial_data(port->serial);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* shutdown our urbs */
 	usb_kill_urb(priv->int_urb);
 }
@@ -161,7 +155,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct symbol_private *priv = usb_get_serial_data(port->serial);
 
-	dbg("%s - port %d", __func__, port->number);
 	spin_lock_irq(&priv->lock);
 	priv->throttled = true;
 	spin_unlock_irq(&priv->lock);
@@ -174,8 +167,6 @@
 	int result;
 	bool was_throttled;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irq(&priv->lock);
 	priv->throttled = false;
 	was_throttled = priv->actually_throttled;
@@ -266,8 +257,6 @@
 {
 	struct symbol_private *priv = usb_get_serial_data(serial);
 
-	dbg("%s", __func__);
-
 	usb_kill_urb(priv->int_urb);
 	usb_free_urb(priv->int_urb);
 }
@@ -276,19 +265,10 @@
 {
 	struct symbol_private *priv = usb_get_serial_data(serial);
 
-	dbg("%s", __func__);
-
 	kfree(priv->int_buffer);
 	kfree(priv);
 }
 
-static struct usb_driver symbol_driver = {
-	.name =			"symbol",
-	.probe =		usb_serial_probe,
-	.disconnect =		usb_serial_disconnect,
-	.id_table =		id_table,
-};
-
 static struct usb_serial_driver symbol_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -309,7 +289,7 @@
 	&symbol_device, NULL
 };
 
-module_usb_serial_driver(symbol_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index ab74123..a4404f5 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -165,7 +165,7 @@
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[14+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = {
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -180,6 +180,7 @@
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
 };
 
 static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -189,7 +190,7 @@
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[18+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = {
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
 	{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -208,16 +209,10 @@
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
 	{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
+	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
 	{ }
 };
 
-static struct usb_driver ti_usb_driver = {
-	.name			= "ti_usb_3410_5052",
-	.probe			= usb_serial_probe,
-	.disconnect		= usb_serial_disconnect,
-	.id_table		= ti_id_table_combined,
-};
-
 static struct usb_serial_driver ti_1port_device = {
 	.driver = {
 		.owner		= THIS_MODULE,
@@ -344,20 +339,18 @@
 		ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
 	}
 
-	ret = usb_serial_register_drivers(&ti_usb_driver, serial_drivers);
+	ret = usb_serial_register_drivers(serial_drivers, KBUILD_MODNAME, ti_id_table_combined);
 	if (ret == 0)
 		printk(KERN_INFO KBUILD_MODNAME ": " TI_DRIVER_VERSION ":"
 			       TI_DRIVER_DESC "\n");
 	return ret;
 }
 
-
 static void __exit ti_exit(void)
 {
-	usb_serial_deregister_drivers(&ti_usb_driver, serial_drivers);
+	usb_serial_deregister_drivers(serial_drivers);
 }
 
-
 module_init(ti_init);
 module_exit(ti_exit);
 
@@ -394,7 +387,9 @@
 
 	/* if we have only 1 configuration, download firmware */
 	if (dev->descriptor.bNumConfigurations == 1) {
-		if ((status = ti_download_firmware(tdev)) != 0)
+		status = ti_download_firmware(tdev);
+
+		if (status != 0)
 			goto free_tdev;
 
 		/* 3410 must be reset, 5052 resets itself */
@@ -463,8 +458,6 @@
 	struct ti_device *tdev = usb_get_serial_data(serial);
 	struct ti_port *tport;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		tport = usb_get_serial_port_data(serial->port[i]);
 		if (tport) {
@@ -489,8 +482,6 @@
 			     TI_PIPE_TIMEOUT_ENABLE |
 			     (TI_TRANSFER_TIMEOUT << 2));
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return -ENODEV;
 
@@ -631,8 +622,6 @@
 	int status;
 	int do_unlock;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	tdev = usb_get_serial_data(port->serial);
 	tport = usb_get_serial_port_data(port);
 	if (tdev == NULL || tport == NULL)
@@ -666,8 +655,6 @@
 	}
 	if (do_unlock)
 		mutex_unlock(&tdev->td_open_close_lock);
-
-	dbg("%s - exit", __func__);
 }
 
 
@@ -676,8 +663,6 @@
 {
 	struct ti_port *tport = usb_get_serial_port_data(port);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (count == 0) {
 		dbg("%s - write request of 0 bytes", __func__);
 		return 0;
@@ -701,8 +686,6 @@
 	int room = 0;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return 0;
 
@@ -722,8 +705,6 @@
 	int chars = 0;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return 0;
 
@@ -741,8 +722,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct ti_port *tport = usb_get_serial_port_data(port);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return;
 
@@ -758,8 +737,6 @@
 	struct ti_port *tport = usb_get_serial_port_data(port);
 	int status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return;
 
@@ -854,8 +831,6 @@
 	int port_number = port->number - port->serial->minor;
 	unsigned int mcr;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	cflag = tty->termios->c_cflag;
 	iflag = tty->termios->c_iflag;
 
@@ -988,8 +963,6 @@
 	unsigned int mcr;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return -ENODEV;
 
@@ -1020,8 +993,6 @@
 	unsigned int mcr;
 	unsigned long flags;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (tport == NULL)
 		return -ENODEV;
 
@@ -1084,8 +1055,6 @@
 	int retval;
 	__u8 msr;
 
-	dbg("%s", __func__);
-
 	switch (status) {
 	case 0:
 		break;
@@ -1165,8 +1134,6 @@
 	int retval = 0;
 	struct tty_struct *tty;
 
-	dbg("%s", __func__);
-
 	switch (status) {
 	case 0:
 		break;
@@ -1233,8 +1200,6 @@
 	struct usb_serial_port *port = tport->tp_port;
 	int status = urb->status;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	tport->tp_write_urb_in_use = 0;
 
 	switch (status) {
@@ -1287,9 +1252,6 @@
 	struct tty_struct *tty = tty_port_tty_get(&port->port);	/* FIXME */
 	unsigned long flags;
 
-
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irqsave(&tport->tp_lock, flags);
 
 	if (tport->tp_write_urb_in_use)
@@ -1366,8 +1328,6 @@
 	int port_number = port->number - port->serial->minor;
 	struct ti_port_status *data;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	size = sizeof(struct ti_port_status);
 	data = kmalloc(size, GFP_KERNEL);
 	if (!data) {
@@ -1480,8 +1440,6 @@
 	struct usb_serial_port *port = tport->tp_port;
 	wait_queue_t wait;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	spin_lock_irq(&tport->tp_lock);
 
 	/* wait for data to drain from the buffer */
@@ -1679,11 +1637,12 @@
 	const struct firmware *fw_p;
 	char buf[32];
 
-	dbg("%s\n", __func__);
 	/* try ID specific firmware first, then try generic firmware */
 	sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
 	    dev->descriptor.idProduct);
-	if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
+	status = request_firmware(&fw_p, buf, &dev->dev);
+
+	if (status != 0) {
 		buf[0] = '\0';
 		if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
 			switch (dev->descriptor.idProduct) {
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index f140f1b..b353e7e 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -37,6 +37,7 @@
 #define TI_5152_BOOT_PRODUCT_ID		0x5152	/* no EEPROM, no firmware */
 #define TI_5052_EEPROM_PRODUCT_ID	0x505A	/* EEPROM, no firmware */
 #define TI_5052_FIRMWARE_PRODUCT_ID	0x505F	/* firmware is running */
+#define FRI2_PRODUCT_ID			0x5053  /* Fish River Island II */
 
 /* Multi-Tech vendor and product ids */
 #define MTS_VENDOR_ID			0x06E0
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 97355a1..6a1b609 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter driver
  *
- * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (greg@kroah.com)
  * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
  * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
  *
@@ -43,17 +43,6 @@
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
 #define DRIVER_DESC "USB Serial Driver core"
 
-/* Driver structure we register with the USB core */
-static struct usb_driver usb_serial_driver = {
-	.name =		"usbserial",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.suspend =	usb_serial_suspend,
-	.resume =	usb_serial_resume,
-	.no_dynamic_id =	1,
-	.supports_autosuspend =	1,
-};
-
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
    the MODULE_DEVICE_TABLE declarations in each serial driver
    cause the "hotplug" program to pull in whatever module is necessary
@@ -710,7 +699,7 @@
 	.shutdown = serial_down,
 };
 
-int usb_serial_probe(struct usb_interface *interface,
+static int usb_serial_probe(struct usb_interface *interface,
 			       const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(interface);
@@ -856,6 +845,8 @@
 			module_put(type->driver.owner);
 			return -EIO;
 		}
+		dev_info(&interface->dev, "The \"generic\" usb-serial driver is only for testing and one-off prototypes.\n");
+		dev_info(&interface->dev, "Tell linux-usb@vger.kernel.org to add your device to a proper driver.\n");
 	}
 #endif
 	if (!num_ports) {
@@ -1043,6 +1034,8 @@
 		dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
 	}
 
+	usb_set_intfdata(interface, serial);
+
 	/* if this device type has an attach function, call it */
 	if (type->attach) {
 		retval = type->attach(serial);
@@ -1087,10 +1080,7 @@
 	serial->disconnected = 0;
 
 	usb_serial_console_init(debug, minor);
-
 exit:
-	/* success */
-	usb_set_intfdata(interface, serial);
 	module_put(type->driver.owner);
 	return 0;
 
@@ -1099,9 +1089,8 @@
 	module_put(type->driver.owner);
 	return -EIO;
 }
-EXPORT_SYMBOL_GPL(usb_serial_probe);
 
-void usb_serial_disconnect(struct usb_interface *interface)
+static void usb_serial_disconnect(struct usb_interface *interface)
 {
 	int i;
 	struct usb_serial *serial = usb_get_intfdata(interface);
@@ -1112,7 +1101,6 @@
 	dbg("%s", __func__);
 
 	mutex_lock(&serial->disc_mutex);
-	usb_set_intfdata(interface, NULL);
 	/* must set a flag, to signal subdrivers */
 	serial->disconnected = 1;
 	mutex_unlock(&serial->disc_mutex);
@@ -1137,7 +1125,6 @@
 	usb_serial_put(serial);
 	dev_info(dev, "device disconnected\n");
 }
-EXPORT_SYMBOL_GPL(usb_serial_disconnect);
 
 int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
 {
@@ -1181,6 +1168,22 @@
 }
 EXPORT_SYMBOL(usb_serial_resume);
 
+static int usb_serial_reset_resume(struct usb_interface *intf)
+{
+	struct usb_serial *serial = usb_get_intfdata(intf);
+	int rv;
+
+	serial->suspending = 0;
+	if (serial->type->reset_resume)
+		rv = serial->type->reset_resume(serial);
+	else {
+		rv = -EOPNOTSUPP;
+		intf->needs_binding = 1;
+	}
+
+	return rv;
+}
+
 static const struct tty_operations serial_ops = {
 	.open =			serial_open,
 	.close =		serial_close,
@@ -1204,6 +1207,17 @@
 
 struct tty_driver *usb_serial_tty_driver;
 
+/* Driver structure we register with the USB core */
+static struct usb_driver usb_serial_driver = {
+	.name =		"usbserial",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.suspend =	usb_serial_suspend,
+	.resume =	usb_serial_resume,
+	.no_dynamic_id =	1,
+	.supports_autosuspend =	1,
+};
+
 static int __init usb_serial_init(void)
 {
 	int i;
@@ -1338,7 +1352,6 @@
 				driver->description);
 		return -EINVAL;
 	}
-	driver->usb_driver->supports_autosuspend = 1;
 
 	/* Add this device to our list of devices */
 	mutex_lock(&table_lock);
@@ -1369,18 +1382,19 @@
 
 /**
  * usb_serial_register_drivers - register drivers for a usb-serial module
- * @udriver: usb_driver used for matching devices/interfaces
  * @serial_drivers: NULL-terminated array of pointers to drivers to be registered
+ * @name: name of the usb_driver for this set of @serial_drivers
+ * @id_table: list of all devices this @serial_drivers set binds to
  *
- * Registers @udriver and all the drivers in the @serial_drivers array.
- * Automatically fills in the .no_dynamic_id field in @udriver and
- * the .usb_driver field in each serial driver.
+ * Registers all the drivers in the @serial_drivers array, and dynamically
+ * creates a struct usb_driver with the name @name and id_table of @id_table.
  */
-int usb_serial_register_drivers(struct usb_driver *udriver,
-		struct usb_serial_driver * const serial_drivers[])
+int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
+				const char *name,
+				const struct usb_device_id *id_table)
 {
 	int rc;
-	const struct usb_device_id *saved_id_table;
+	struct usb_driver *udriver;
 	struct usb_serial_driver * const *sd;
 
 	/*
@@ -1391,12 +1405,30 @@
 	 * Performance hack: We don't want udriver to be probed until
 	 * the serial drivers are registered, because the probe would
 	 * simply fail for lack of a matching serial driver.
-	 * Therefore save off udriver's id_table until we are all set.
+	 * So we leave udriver's id_table set to NULL until we are all set.
+	 *
+	 * Suspend/resume support is implemented in the usb-serial core,
+	 * so fill in the PM-related fields in udriver.
 	 */
-	saved_id_table = udriver->id_table;
-	udriver->id_table = NULL;
+	udriver = kzalloc(sizeof(*udriver), GFP_KERNEL);
+	if (!udriver)
+		return -ENOMEM;
 
+	udriver->name = name;
 	udriver->no_dynamic_id = 1;
+	udriver->supports_autosuspend = 1;
+	udriver->suspend = usb_serial_suspend;
+	udriver->resume = usb_serial_resume;
+	udriver->probe = usb_serial_probe;
+	udriver->disconnect = usb_serial_disconnect;
+
+	/* we only set the reset_resume field if the serial_driver has one */
+	for (sd = serial_drivers; *sd; ++sd) {
+		if ((*sd)->reset_resume)
+			udriver->reset_resume = usb_serial_reset_resume;
+			break;
+	}
+
 	rc = usb_register(udriver);
 	if (rc)
 		return rc;
@@ -1408,8 +1440,8 @@
 			goto failed;
 	}
 
-	/* Now restore udriver's id_table and look for matches */
-	udriver->id_table = saved_id_table;
+	/* Now set udriver's id_table and look for matches */
+	udriver->id_table = id_table;
 	rc = driver_attach(&udriver->drvwrap.driver);
 	return 0;
 
@@ -1423,17 +1455,20 @@
 
 /**
  * usb_serial_deregister_drivers - deregister drivers for a usb-serial module
- * @udriver: usb_driver to unregister
  * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered
  *
- * Deregisters @udriver and all the drivers in the @serial_drivers array.
+ * Deregisters all the drivers in the @serial_drivers array and deregisters and
+ * frees the struct usb_driver that was created by the call to
+ * usb_serial_register_drivers().
  */
-void usb_serial_deregister_drivers(struct usb_driver *udriver,
-		struct usb_serial_driver * const serial_drivers[])
+void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[])
 {
+	struct usb_driver *udriver = (*serial_drivers)->usb_driver;
+
 	for (; *serial_drivers; ++serial_drivers)
 		usb_serial_deregister(*serial_drivers);
 	usb_deregister(udriver);
+	kfree(udriver);
 }
 EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers);
 
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index e3e8995..5760f97 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -35,13 +35,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver debug_driver = {
-	.name =		"debug",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 /* This HW really does not support a serial break, so one will be
  * emulated when ever the break state is set to true.
  */
@@ -83,5 +76,5 @@
 	&debug_device, NULL
 };
 
-module_usb_serial_driver(debug_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index c88657d..f35971d 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -43,11 +43,8 @@
 {
 	struct usb_serial *serial = port->serial;
 	struct usb_wwan_port_private *portdata;
-
 	struct usb_wwan_intf_private *intfdata;
 
-	dbg("%s", __func__);
-
 	intfdata = port->serial->private;
 
 	if (!intfdata->send_setup)
@@ -69,8 +66,6 @@
 {
 	struct usb_wwan_intf_private *intfdata = port->serial->private;
 
-	dbg("%s", __func__);
-
 	/* Doesn't support option setting */
 	tty_termios_copy_hw(tty->termios, old_termios);
 
@@ -286,8 +281,6 @@
 	unsigned char *data = urb->transfer_buffer;
 	int status = urb->status;
 
-	dbg("%s: %p", __func__, urb);
-
 	endpoint = usb_pipeendpoint(urb->pipe);
 	port = urb->context;
 
@@ -307,20 +300,17 @@
 		}
 
 		/* Resubmit urb so we continue receiving */
-		if (status != -ESHUTDOWN) {
-			err = usb_submit_urb(urb, GFP_ATOMIC);
-			if (err) {
-				if (err != -EPERM) {
-					printk(KERN_ERR "%s: resubmit read urb failed. "
-						"(%d)", __func__, err);
-					/* busy also in error unless we are killed */
-					usb_mark_last_busy(port->serial->dev);
-				}
-			} else {
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err) {
+			if (err != -EPERM) {
+				printk(KERN_ERR "%s: resubmit read urb failed. "
+					"(%d)", __func__, err);
+				/* busy also in error unless we are killed */
 				usb_mark_last_busy(port->serial->dev);
 			}
+		} else {
+			usb_mark_last_busy(port->serial->dev);
 		}
-
 	}
 }
 
@@ -331,8 +321,6 @@
 	struct usb_wwan_intf_private *intfdata;
 	int i;
 
-	dbg("%s", __func__);
-
 	port = urb->context;
 	intfdata = port->serial->private;
 
@@ -406,8 +394,6 @@
 	portdata = usb_get_serial_port_data(port);
 	intfdata = serial->private;
 
-	dbg("%s", __func__);
-
 	/* Start reading from the IN endpoint */
 	for (i = 0; i < N_IN_URB; i++) {
 		urb = portdata->in_urbs[i];
@@ -441,7 +427,6 @@
 	struct usb_wwan_port_private *portdata;
 	struct usb_wwan_intf_private *intfdata = port->serial->private;
 
-	dbg("%s", __func__);
 	portdata = usb_get_serial_port_data(port);
 
 	if (serial->dev) {
@@ -492,8 +477,6 @@
 	struct usb_serial_port *port;
 	struct usb_wwan_port_private *portdata;
 
-	dbg("%s", __func__);
-
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
 		portdata = usb_get_serial_port_data(port);
@@ -534,8 +517,6 @@
 	struct usb_wwan_port_private *portdata;
 	u8 *buffer;
 
-	dbg("%s", __func__);
-
 	/* Now setup per port private data */
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
@@ -603,8 +584,6 @@
 
 void usb_wwan_disconnect(struct usb_serial *serial)
 {
-	dbg("%s", __func__);
-
 	stop_read_write_urbs(serial);
 }
 EXPORT_SYMBOL(usb_wwan_disconnect);
@@ -615,8 +594,6 @@
 	struct usb_serial_port *port;
 	struct usb_wwan_port_private *portdata;
 
-	dbg("%s", __func__);
-
 	/* Now free them */
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
@@ -649,8 +626,6 @@
 	struct usb_wwan_intf_private *intfdata = serial->private;
 	int b;
 
-	dbg("%s entered", __func__);
-
 	if (PMSG_IS_AUTO(message)) {
 		spin_lock_irq(&intfdata->susp_lock);
 		b = intfdata->in_flight;
@@ -714,7 +689,6 @@
 	struct urb *urb;
 	int err = 0;
 
-	dbg("%s entered", __func__);
 	/* get the interrupt URBs resubmitted unconditionally */
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
@@ -725,8 +699,8 @@
 		err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
 		dbg("Submitted interrupt URB for port %d (result %d)", i, err);
 		if (err < 0) {
-			err("%s: Error %d for interrupt URB of port%d",
-			    __func__, err, i);
+			dev_err(&port->dev, "%s: Error %d for interrupt URB\n",
+				__func__, err);
 			goto err_out;
 		}
 	}
@@ -747,8 +721,8 @@
 			urb = portdata->in_urbs[j];
 			err = usb_submit_urb(urb, GFP_ATOMIC);
 			if (err < 0) {
-				err("%s: Error %d for bulk URB %d",
-				    __func__, err, i);
+				dev_err(&port->dev, "%s: Error %d for bulk URB %d\n",
+					__func__, err, i);
 				spin_unlock_irq(&intfdata->susp_lock);
 				goto err_out;
 			}
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 71d6964..f253c91 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -53,8 +53,6 @@
 
 /* Parameters that may be passed into the module. */
 static bool debug;
-static __u16 vendor;
-static __u16 product;
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
@@ -115,14 +113,12 @@
 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),
 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
-	{ },					/* optional parameter entry */
 	{ }					/* Terminating entry */
 };
 
 static struct usb_device_id clie_id_5_table [] = {
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),
 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
-	{ },					/* optional parameter entry */
 	{ }					/* Terminating entry */
 };
 
@@ -162,19 +158,11 @@
 	{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },
 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },
 	{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },
-	{ },					/* optional parameter entry */
 	{ }					/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver visor_driver = {
-	.name =		"visor",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
-
 /* All of the device info needed for the Handspring Visor,
    and Palm 4.0 devices */
 static struct usb_serial_driver handspring_device = {
@@ -244,8 +232,6 @@
 {
 	int result = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (!port->read_urb) {
 		/* this is needed for some brain dead Sony devices */
 		dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n");
@@ -258,7 +244,7 @@
 		goto exit;
 
 	if (port->interrupt_in_urb) {
-		dbg("%s - adding interrupt input for treo", __func__);
+		dev_dbg(&port->dev, "adding interrupt input for treo\n");
 		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (result)
 			dev_err(&port->dev,
@@ -274,8 +260,6 @@
 {
 	unsigned char *transfer_buffer;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	/* shutdown our urbs */
 	usb_serial_generic_close(port);
 	usb_kill_urb(port->interrupt_in_urb);
@@ -310,12 +294,12 @@
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n",
+			__func__, status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __func__, status);
+		dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n",
+			__func__, status);
 		goto exit;
 	}
 
@@ -348,8 +332,6 @@
 	int i;
 	int num_ports = 0;
 
-	dbg("%s", __func__);
-
 	transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
 	if (!transfer_buffer) {
 		dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__,
@@ -445,8 +427,6 @@
 	unsigned char *transfer_buffer;
 	int retval;
 
-	dbg("%s", __func__);
-
 	transfer_buffer =  kmalloc(sizeof(*connection_info), GFP_KERNEL);
 	if (!transfer_buffer) {
 		dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__,
@@ -478,8 +458,6 @@
 	int (*startup)(struct usb_serial *serial,
 					const struct usb_device_id *id);
 
-	dbg("%s", __func__);
-
 	/*
 	 * some Samsung Android phones in modem mode have the same ID
 	 * as SPH-I500, but they are ACM devices, so dont bind to them
@@ -521,8 +499,6 @@
 	int result;
 	u8 *data;
 
-	dbg("%s", __func__);
-
 	data = kmalloc(1, GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
@@ -585,8 +561,6 @@
 		(serial->num_interrupt_in == 0))
 		return 0;
 
-	dbg("%s", __func__);
-
 	/*
 	* It appears that Treos and Kyoceras want to use the
 	* 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
@@ -622,8 +596,6 @@
 	unsigned int pipe;
 	int j;
 
-	dbg("%s", __func__);
-
 	/* TH55 registers 2 ports.
 	   Communication in from the UX50/TH55 uses bulk_in_endpointAddress
 	   from port 0. Communication out to the UX50/TH55 uses
@@ -648,59 +620,7 @@
 	return 0;
 }
 
-static int __init visor_init(void)
-{
-	int i, retval;
-	/* Only if parameters were passed to us */
-	if (vendor > 0 && product > 0) {
-		struct usb_device_id usb_dev_temp[] = {
-			{
-				USB_DEVICE(vendor, product),
-				.driver_info =
-					(kernel_ulong_t) &palm_os_4_probe
-			}
-		};
-
-		/* Find the last entry in id_table */
-		for (i = 0;; i++) {
-			if (id_table[i].idVendor == 0) {
-				id_table[i] = usb_dev_temp[0];
-				break;
-			}
-		}
-		/* Find the last entry in id_table_combined */
-		for (i = 0;; i++) {
-			if (id_table_combined[i].idVendor == 0) {
-				id_table_combined[i] = usb_dev_temp[0];
-				break;
-			}
-		}
-		printk(KERN_INFO KBUILD_MODNAME
-		       ": Untested USB device specified at time of module insertion\n");
-		printk(KERN_INFO KBUILD_MODNAME
-		       ": Warning: This is not guaranteed to work\n");
-		printk(KERN_INFO KBUILD_MODNAME
-		       ": Using a newer kernel is preferred to this method\n");
-		printk(KERN_INFO KBUILD_MODNAME
-		       ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n",
-			vendor, product);
-	}
-
-	retval = usb_serial_register_drivers(&visor_driver, serial_drivers);
-	if (retval == 0)
-		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
-	return retval;
-}
-
-
-static void __exit visor_exit (void)
-{
-	usb_serial_deregister_drivers(&visor_driver, serial_drivers);
-}
-
-
-module_init(visor_init);
-module_exit(visor_exit);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -708,9 +628,3 @@
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-module_param(vendor, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified vendor ID");
-module_param(product, ushort, 0);
-MODULE_PARM_DESC(product, "User specified product ID");
-
diff --git a/drivers/usb/serial/vivopay-serial.c b/drivers/usb/serial/vivopay-serial.c
index 078f338..0c0aa87 100644
--- a/drivers/usb/serial/vivopay-serial.c
+++ b/drivers/usb/serial/vivopay-serial.c
@@ -25,13 +25,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver vivopay_serial_driver = {
-	.name =			"vivopay-serial",
-	.probe =		usb_serial_probe,
-	.disconnect =		usb_serial_disconnect,
-	.id_table =		id_table,
-};
-
 static struct usb_serial_driver vivopay_serial_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -45,7 +38,7 @@
 	&vivopay_serial_device, NULL
 };
 
-module_usb_serial_driver(vivopay_serial_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 
 MODULE_AUTHOR("Forest Bond <forest.bond@outpostembedded.com>");
 MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 407e23c..473635e 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -45,7 +45,6 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v2.0"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Stuart MacDonald <stuartm@connecttech.com>"
 #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
 
@@ -78,12 +77,6 @@
 
 MODULE_DEVICE_TABLE(usb, id_table_combined);
 
-static struct usb_driver whiteheat_driver = {
-	.name =		"whiteheat",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table_combined,
-};
 
 /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
 static int  whiteheat_firmware_download(struct usb_serial *serial,
@@ -96,10 +89,6 @@
 static int  whiteheat_open(struct tty_struct *tty,
 			struct usb_serial_port *port);
 static void whiteheat_close(struct usb_serial_port *port);
-static int  whiteheat_write(struct tty_struct *tty,
-			struct usb_serial_port *port,
-			const unsigned char *buf, int count);
-static int  whiteheat_write_room(struct tty_struct *tty);
 static int  whiteheat_ioctl(struct tty_struct *tty,
 			unsigned int cmd, unsigned long arg);
 static void whiteheat_set_termios(struct tty_struct *tty,
@@ -108,11 +97,6 @@
 static int  whiteheat_tiocmset(struct tty_struct *tty,
 			unsigned int set, unsigned int clear);
 static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
-static int  whiteheat_chars_in_buffer(struct tty_struct *tty);
-static void whiteheat_throttle(struct tty_struct *tty);
-static void whiteheat_unthrottle(struct tty_struct *tty);
-static void whiteheat_read_callback(struct urb *urb);
-static void whiteheat_write_callback(struct urb *urb);
 
 static struct usb_serial_driver whiteheat_fake_device = {
 	.driver = {
@@ -138,18 +122,13 @@
 	.release =		whiteheat_release,
 	.open =			whiteheat_open,
 	.close =		whiteheat_close,
-	.write =		whiteheat_write,
-	.write_room =		whiteheat_write_room,
 	.ioctl =		whiteheat_ioctl,
 	.set_termios =		whiteheat_set_termios,
 	.break_ctl =		whiteheat_break_ctl,
 	.tiocmget =		whiteheat_tiocmget,
 	.tiocmset =		whiteheat_tiocmset,
-	.chars_in_buffer =	whiteheat_chars_in_buffer,
-	.throttle =		whiteheat_throttle,
-	.unthrottle =		whiteheat_unthrottle,
-	.read_bulk_callback =	whiteheat_read_callback,
-	.write_bulk_callback =	whiteheat_write_callback,
+	.throttle =		usb_serial_generic_throttle,
+	.unthrottle =		usb_serial_generic_unthrottle,
 };
 
 static struct usb_serial_driver * const serial_drivers[] = {
@@ -166,29 +145,8 @@
 	__u8			result_buffer[64];
 };
 
-
-#define THROTTLED		0x01
-#define ACTUALLY_THROTTLED	0x02
-
-static int urb_pool_size = 8;
-
-struct whiteheat_urb_wrap {
-	struct list_head	list;
-	struct urb		*urb;
-};
-
 struct whiteheat_private {
-	spinlock_t		lock;
-	__u8			flags;
 	__u8			mcr;		/* FIXME: no locking on mcr */
-	struct list_head	rx_urbs_free;
-	struct list_head	rx_urbs_submitted;
-	struct list_head	rx_urb_q;
-	struct work_struct	rx_work;
-	struct usb_serial_port	*port;
-	struct list_head	tx_urbs_free;
-	struct list_head	tx_urbs_submitted;
-	struct mutex		deathwarrant;
 };
 
 
@@ -198,12 +156,6 @@
 static void command_port_write_callback(struct urb *urb);
 static void command_port_read_callback(struct urb *urb);
 
-static int start_port_read(struct usb_serial_port *port);
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
-						struct list_head *head);
-static struct list_head *list_first(struct list_head *head);
-static void rx_data_softint(struct work_struct *work);
-
 static int firm_send_command(struct usb_serial_port *port, __u8 command,
 						__u8 *data, __u8 datasize);
 static int firm_open(struct usb_serial_port *port);
@@ -247,8 +199,6 @@
 	const struct firmware *loader_fw = NULL, *firmware_fw = NULL;
 	const struct ihex_binrec *record;
 
-	dbg("%s", __func__);
-
 	if (request_ihex_firmware(&firmware_fw, "whiteheat.fw",
 				  &serial->dev->dev)) {
 		dev_err(&serial->dev->dev,
@@ -349,11 +299,6 @@
 	__u8 *command;
 	__u8 *result;
 	int i;
-	int j;
-	struct urb *urb;
-	int buf_size;
-	struct whiteheat_urb_wrap *wrap;
-	struct list_head *tmp;
 
 	command_port = serial->port[COMMAND_PORT];
 
@@ -408,8 +353,8 @@
 
 	hw_info = (struct whiteheat_hw_info *)&result[1];
 
-	dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n",
-		 serial->type->description, DRIVER_VERSION,
+	dev_info(&serial->dev->dev, "%s: Firmware v%d.%02d\n",
+		 serial->type->description,
 		 hw_info->sw_major_rev, hw_info->sw_minor_rev);
 
 	for (i = 0; i < serial->num_ports; i++) {
@@ -423,72 +368,7 @@
 			goto no_private;
 		}
 
-		spin_lock_init(&info->lock);
-		mutex_init(&info->deathwarrant);
-		info->flags = 0;
 		info->mcr = 0;
-		INIT_WORK(&info->rx_work, rx_data_softint);
-		info->port = port;
-
-		INIT_LIST_HEAD(&info->rx_urbs_free);
-		INIT_LIST_HEAD(&info->rx_urbs_submitted);
-		INIT_LIST_HEAD(&info->rx_urb_q);
-		INIT_LIST_HEAD(&info->tx_urbs_free);
-		INIT_LIST_HEAD(&info->tx_urbs_submitted);
-
-		for (j = 0; j < urb_pool_size; j++) {
-			urb = usb_alloc_urb(0, GFP_KERNEL);
-			if (!urb) {
-				dev_err(&port->dev, "No free urbs available\n");
-				goto no_rx_urb;
-			}
-			buf_size = port->read_urb->transfer_buffer_length;
-			urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
-			if (!urb->transfer_buffer) {
-				dev_err(&port->dev,
-					"Couldn't allocate urb buffer\n");
-				goto no_rx_buf;
-			}
-			wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
-			if (!wrap) {
-				dev_err(&port->dev,
-					"Couldn't allocate urb wrapper\n");
-				goto no_rx_wrap;
-			}
-			usb_fill_bulk_urb(urb, serial->dev,
-					usb_rcvbulkpipe(serial->dev,
-						port->bulk_in_endpointAddress),
-					urb->transfer_buffer, buf_size,
-					whiteheat_read_callback, port);
-			wrap->urb = urb;
-			list_add(&wrap->list, &info->rx_urbs_free);
-
-			urb = usb_alloc_urb(0, GFP_KERNEL);
-			if (!urb) {
-				dev_err(&port->dev, "No free urbs available\n");
-				goto no_tx_urb;
-			}
-			buf_size = port->write_urb->transfer_buffer_length;
-			urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
-			if (!urb->transfer_buffer) {
-				dev_err(&port->dev,
-					"Couldn't allocate urb buffer\n");
-				goto no_tx_buf;
-			}
-			wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
-			if (!wrap) {
-				dev_err(&port->dev,
-					"Couldn't allocate urb wrapper\n");
-				goto no_tx_wrap;
-			}
-			usb_fill_bulk_urb(urb, serial->dev,
-					usb_sndbulkpipe(serial->dev,
-						port->bulk_out_endpointAddress),
-					urb->transfer_buffer, buf_size,
-					whiteheat_write_callback, port);
-			wrap->urb = urb;
-			list_add(&wrap->list, &info->tx_urbs_free);
-		}
 
 		usb_set_serial_port_data(port, info);
 	}
@@ -531,29 +411,6 @@
 	for (i = serial->num_ports - 1; i >= 0; i--) {
 		port = serial->port[i];
 		info = usb_get_serial_port_data(port);
-		for (j = urb_pool_size - 1; j >= 0; j--) {
-			tmp = list_first(&info->tx_urbs_free);
-			list_del(tmp);
-			wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-			urb = wrap->urb;
-			kfree(wrap);
-no_tx_wrap:
-			kfree(urb->transfer_buffer);
-no_tx_buf:
-			usb_free_urb(urb);
-no_tx_urb:
-			tmp = list_first(&info->rx_urbs_free);
-			list_del(tmp);
-			wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-			urb = wrap->urb;
-			kfree(wrap);
-no_rx_wrap:
-			kfree(urb->transfer_buffer);
-no_rx_buf:
-			usb_free_urb(urb);
-no_rx_urb:
-			;
-		}
 		kfree(info);
 no_private:
 		;
@@ -569,56 +426,27 @@
 static void whiteheat_release(struct usb_serial *serial)
 {
 	struct usb_serial_port *command_port;
-	struct usb_serial_port *port;
 	struct whiteheat_private *info;
-	struct whiteheat_urb_wrap *wrap;
-	struct urb *urb;
-	struct list_head *tmp;
-	struct list_head *tmp2;
 	int i;
 
-	dbg("%s", __func__);
-
 	/* free up our private data for our command port */
 	command_port = serial->port[COMMAND_PORT];
 	kfree(usb_get_serial_port_data(command_port));
 
 	for (i = 0; i < serial->num_ports; i++) {
-		port = serial->port[i];
-		info = usb_get_serial_port_data(port);
-		list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
-			list_del(tmp);
-			wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-			urb = wrap->urb;
-			kfree(wrap);
-			kfree(urb->transfer_buffer);
-			usb_free_urb(urb);
-		}
-		list_for_each_safe(tmp, tmp2, &info->tx_urbs_free) {
-			list_del(tmp);
-			wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-			urb = wrap->urb;
-			kfree(wrap);
-			kfree(urb->transfer_buffer);
-			usb_free_urb(urb);
-		}
+		info = usb_get_serial_port_data(serial->port[i]);
 		kfree(info);
 	}
 }
 
 static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	int		retval = 0;
-
-	dbg("%s - port %d", __func__, port->number);
+	int retval;
 
 	retval = start_command_port(port->serial);
 	if (retval)
 		goto exit;
 
-	if (tty)
-		tty->low_latency = 1;
-
 	/* send an open port command */
 	retval = firm_open(port);
 	if (retval) {
@@ -640,154 +468,33 @@
 	usb_clear_halt(port->serial->dev, port->read_urb->pipe);
 	usb_clear_halt(port->serial->dev, port->write_urb->pipe);
 
-	/* Start reading from the device */
-	retval = start_port_read(port);
+	retval = usb_serial_generic_open(tty, port);
 	if (retval) {
-		dev_err(&port->dev,
-			"%s - failed submitting read urb, error %d\n",
-			__func__, retval);
 		firm_close(port);
 		stop_command_port(port->serial);
 		goto exit;
 	}
-
 exit:
-	dbg("%s - exit, retval = %d", __func__, retval);
 	return retval;
 }
 
 
 static void whiteheat_close(struct usb_serial_port *port)
 {
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	struct whiteheat_urb_wrap *wrap;
-	struct urb *urb;
-	struct list_head *tmp;
-	struct list_head *tmp2;
-
-	dbg("%s - port %d", __func__, port->number);
-
 	firm_report_tx_done(port);
 	firm_close(port);
 
-	/* shutdown our bulk reads and writes */
-	mutex_lock(&info->deathwarrant);
-	spin_lock_irq(&info->lock);
-	list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		urb = wrap->urb;
-		list_del(tmp);
-		spin_unlock_irq(&info->lock);
-		usb_kill_urb(urb);
-		spin_lock_irq(&info->lock);
-		list_add(tmp, &info->rx_urbs_free);
-	}
-	list_for_each_safe(tmp, tmp2, &info->rx_urb_q)
-		list_move(tmp, &info->rx_urbs_free);
-	list_for_each_safe(tmp, tmp2, &info->tx_urbs_submitted) {
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		urb = wrap->urb;
-		list_del(tmp);
-		spin_unlock_irq(&info->lock);
-		usb_kill_urb(urb);
-		spin_lock_irq(&info->lock);
-		list_add(tmp, &info->tx_urbs_free);
-	}
-	spin_unlock_irq(&info->lock);
-	mutex_unlock(&info->deathwarrant);
+	usb_serial_generic_close(port);
+
 	stop_command_port(port->serial);
 }
 
-
-static int whiteheat_write(struct tty_struct *tty,
-	struct usb_serial_port *port, const unsigned char *buf, int count)
-{
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	struct whiteheat_urb_wrap *wrap;
-	struct urb *urb;
-	int result;
-	int bytes;
-	int sent = 0;
-	unsigned long flags;
-	struct list_head *tmp;
-
-	dbg("%s - port %d", __func__, port->number);
-
-	if (count == 0) {
-		dbg("%s - write request of 0 bytes", __func__);
-		return (0);
-	}
-
-	while (count) {
-		spin_lock_irqsave(&info->lock, flags);
-		if (list_empty(&info->tx_urbs_free)) {
-			spin_unlock_irqrestore(&info->lock, flags);
-			break;
-		}
-		tmp = list_first(&info->tx_urbs_free);
-		list_del(tmp);
-		spin_unlock_irqrestore(&info->lock, flags);
-
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		urb = wrap->urb;
-		bytes = (count > port->bulk_out_size) ?
-					port->bulk_out_size : count;
-		memcpy(urb->transfer_buffer, buf + sent, bytes);
-
-		usb_serial_debug_data(debug, &port->dev,
-				__func__, bytes, urb->transfer_buffer);
-
-		urb->transfer_buffer_length = bytes;
-		result = usb_submit_urb(urb, GFP_ATOMIC);
-		if (result) {
-			dev_err_console(port,
-				"%s - failed submitting write urb, error %d\n",
-				__func__, result);
-			sent = result;
-			spin_lock_irqsave(&info->lock, flags);
-			list_add(tmp, &info->tx_urbs_free);
-			spin_unlock_irqrestore(&info->lock, flags);
-			break;
-		} else {
-			sent += bytes;
-			count -= bytes;
-			spin_lock_irqsave(&info->lock, flags);
-			list_add(tmp, &info->tx_urbs_submitted);
-			spin_unlock_irqrestore(&info->lock, flags);
-		}
-	}
-
-	return sent;
-}
-
-static int whiteheat_write_room(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	struct list_head *tmp;
-	int room = 0;
-	unsigned long flags;
-
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock_irqsave(&info->lock, flags);
-	list_for_each(tmp, &info->tx_urbs_free)
-		room++;
-	spin_unlock_irqrestore(&info->lock, flags);
-	room *= port->bulk_out_size;
-
-	dbg("%s - returns %d", __func__, room);
-	return (room);
-}
-
 static int whiteheat_tiocmget(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
 	struct whiteheat_private *info = usb_get_serial_port_data(port);
 	unsigned int modem_signals = 0;
 
-	dbg("%s - port %d", __func__, port->number);
-
 	firm_get_dtr_rts(port);
 	if (info->mcr & UART_MCR_DTR)
 		modem_signals |= TIOCM_DTR;
@@ -803,8 +510,6 @@
 	struct usb_serial_port *port = tty->driver_data;
 	struct whiteheat_private *info = usb_get_serial_port_data(port);
 
-	dbg("%s - port %d", __func__, port->number);
-
 	if (set & TIOCM_RTS)
 		info->mcr |= UART_MCR_RTS;
 	if (set & TIOCM_DTR)
@@ -837,7 +542,7 @@
 		serstruct.line = port->serial->minor;
 		serstruct.port = port->number;
 		serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-		serstruct.xmit_fifo_size = port->bulk_out_size;
+		serstruct.xmit_fifo_size = kfifo_size(&port->write_fifo);
 		serstruct.custom_divisor = 0;
 		serstruct.baud_base = 460800;
 		serstruct.close_delay = CLOSING_DELAY;
@@ -867,60 +572,6 @@
 }
 
 
-static int whiteheat_chars_in_buffer(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	struct list_head *tmp;
-	struct whiteheat_urb_wrap *wrap;
-	int chars = 0;
-	unsigned long flags;
-
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock_irqsave(&info->lock, flags);
-	list_for_each(tmp, &info->tx_urbs_submitted) {
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		chars += wrap->urb->transfer_buffer_length;
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	dbg("%s - returns %d", __func__, chars);
-	return chars;
-}
-
-
-static void whiteheat_throttle(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock_irq(&info->lock);
-	info->flags |= THROTTLED;
-	spin_unlock_irq(&info->lock);
-}
-
-
-static void whiteheat_unthrottle(struct tty_struct *tty)
-{
-	struct usb_serial_port *port = tty->driver_data;
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	int actually_throttled;
-
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock_irq(&info->lock);
-	actually_throttled = info->flags & ACTUALLY_THROTTLED;
-	info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
-	spin_unlock_irq(&info->lock);
-
-	if (actually_throttled)
-		rx_data_softint(&info->rx_work);
-}
-
-
 /*****************************************************************************
  * Connect Tech's White Heat callback routines
  *****************************************************************************/
@@ -928,8 +579,6 @@
 {
 	int status = urb->status;
 
-	dbg("%s", __func__);
-
 	if (status) {
 		dbg("nonzero urb status: %d", status);
 		return;
@@ -945,8 +594,6 @@
 	unsigned char *data = urb->transfer_buffer;
 	int result;
 
-	dbg("%s", __func__);
-
 	command_info = usb_get_serial_port_data(command_port);
 	if (!command_info) {
 		dbg("%s - command_info is NULL, exiting.", __func__);
@@ -989,80 +636,6 @@
 }
 
 
-static void whiteheat_read_callback(struct urb *urb)
-{
-	struct usb_serial_port *port = urb->context;
-	struct whiteheat_urb_wrap *wrap;
-	unsigned char *data = urb->transfer_buffer;
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	int status = urb->status;
-
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock(&info->lock);
-	wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
-	if (!wrap) {
-		spin_unlock(&info->lock);
-		dev_err(&port->dev, "%s - Not my urb!\n", __func__);
-		return;
-	}
-	list_del(&wrap->list);
-	spin_unlock(&info->lock);
-
-	if (status) {
-		dbg("%s - nonzero read bulk status received: %d",
-		    __func__, status);
-		spin_lock(&info->lock);
-		list_add(&wrap->list, &info->rx_urbs_free);
-		spin_unlock(&info->lock);
-		return;
-	}
-
-	usb_serial_debug_data(debug, &port->dev,
-				__func__, urb->actual_length, data);
-
-	spin_lock(&info->lock);
-	list_add_tail(&wrap->list, &info->rx_urb_q);
-	if (info->flags & THROTTLED) {
-		info->flags |= ACTUALLY_THROTTLED;
-		spin_unlock(&info->lock);
-		return;
-	}
-	spin_unlock(&info->lock);
-
-	schedule_work(&info->rx_work);
-}
-
-
-static void whiteheat_write_callback(struct urb *urb)
-{
-	struct usb_serial_port *port = urb->context;
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	struct whiteheat_urb_wrap *wrap;
-	int status = urb->status;
-
-	dbg("%s - port %d", __func__, port->number);
-
-	spin_lock(&info->lock);
-	wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
-	if (!wrap) {
-		spin_unlock(&info->lock);
-		dev_err(&port->dev, "%s - Not my urb!\n", __func__);
-		return;
-	}
-	list_move(&wrap->list, &info->tx_urbs_free);
-	spin_unlock(&info->lock);
-
-	if (status) {
-		dbg("%s - nonzero write bulk status received: %d",
-		    __func__, status);
-		return;
-	}
-
-	usb_serial_port_softint(port);
-}
-
-
 /*****************************************************************************
  * Connect Tech's White Heat firmware interface
  *****************************************************************************/
@@ -1337,124 +910,7 @@
 	mutex_unlock(&command_info->mutex);
 }
 
-
-static int start_port_read(struct usb_serial_port *port)
-{
-	struct whiteheat_private *info = usb_get_serial_port_data(port);
-	struct whiteheat_urb_wrap *wrap;
-	struct urb *urb;
-	int retval = 0;
-	unsigned long flags;
-	struct list_head *tmp;
-	struct list_head *tmp2;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	list_for_each_safe(tmp, tmp2, &info->rx_urbs_free) {
-		list_del(tmp);
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		urb = wrap->urb;
-		spin_unlock_irqrestore(&info->lock, flags);
-		retval = usb_submit_urb(urb, GFP_KERNEL);
-		if (retval) {
-			spin_lock_irqsave(&info->lock, flags);
-			list_add(tmp, &info->rx_urbs_free);
-			list_for_each_safe(tmp, tmp2, &info->rx_urbs_submitted) {
-				wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-				urb = wrap->urb;
-				list_del(tmp);
-				spin_unlock_irqrestore(&info->lock, flags);
-				usb_kill_urb(urb);
-				spin_lock_irqsave(&info->lock, flags);
-				list_add(tmp, &info->rx_urbs_free);
-			}
-			break;
-		}
-		spin_lock_irqsave(&info->lock, flags);
-		list_add(tmp, &info->rx_urbs_submitted);
-	}
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	return retval;
-}
-
-
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
-						struct list_head *head)
-{
-	struct whiteheat_urb_wrap *wrap;
-	struct list_head *tmp;
-
-	list_for_each(tmp, head) {
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		if (wrap->urb == urb)
-			return wrap;
-	}
-
-	return NULL;
-}
-
-
-static struct list_head *list_first(struct list_head *head)
-{
-	return head->next;
-}
-
-
-static void rx_data_softint(struct work_struct *work)
-{
-	struct whiteheat_private *info =
-		container_of(work, struct whiteheat_private, rx_work);
-	struct usb_serial_port *port = info->port;
-	struct tty_struct *tty = tty_port_tty_get(&port->port);
-	struct whiteheat_urb_wrap *wrap;
-	struct urb *urb;
-	unsigned long flags;
-	struct list_head *tmp;
-	struct list_head *tmp2;
-	int result;
-	int sent = 0;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->flags & THROTTLED) {
-		spin_unlock_irqrestore(&info->lock, flags);
-		goto out;
-	}
-
-	list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
-		list_del(tmp);
-		spin_unlock_irqrestore(&info->lock, flags);
-
-		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
-		urb = wrap->urb;
-
-		if (tty && urb->actual_length)
-			sent += tty_insert_flip_string(tty,
-				urb->transfer_buffer, urb->actual_length);
-
-		result = usb_submit_urb(urb, GFP_ATOMIC);
-		if (result) {
-			dev_err(&port->dev,
-				"%s - failed resubmitting read urb, error %d\n",
-				__func__, result);
-			spin_lock_irqsave(&info->lock, flags);
-			list_add(tmp, &info->rx_urbs_free);
-			continue;
-		}
-
-		spin_lock_irqsave(&info->lock, flags);
-		list_add(tmp, &info->rx_urbs_submitted);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	if (sent)
-		tty_flip_buffer_push(tty);
-out:
-	tty_kref_put(tty);
-}
-
-module_usb_serial_driver(whiteheat_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table_combined);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -1463,8 +919,5 @@
 MODULE_FIRMWARE("whiteheat.fw");
 MODULE_FIRMWARE("whiteheat_loader.fw");
 
-module_param(urb_pool_size, int, 0);
-MODULE_PARM_DESC(urb_pool_size, "Number of urbs to use for buffering");
-
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/serial/zio.c b/drivers/usb/serial/zio.c
index 9d0bb37..c043aa8 100644
--- a/drivers/usb/serial/zio.c
+++ b/drivers/usb/serial/zio.c
@@ -22,13 +22,6 @@
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-static struct usb_driver zio_driver = {
-	.name =		"zio",
-	.probe =	usb_serial_probe,
-	.disconnect =	usb_serial_disconnect,
-	.id_table =	id_table,
-};
-
 static struct usb_serial_driver zio_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -42,5 +35,5 @@
 	&zio_device, NULL
 };
 
-module_usb_serial_driver(zio_driver, serial_drivers);
+module_usb_serial_driver(serial_drivers, id_table);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index e7e6781..b28f2ad 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -1933,11 +1933,7 @@
 	kfree(buf);
 
 nofw:
-	if (sd_fw != NULL) {
-		release_firmware(sd_fw);
-		sd_fw = NULL;
-	}
-
+	release_firmware(sd_fw);
 	return result;
 }
 
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 856ad92..8f3cbb8 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1885,6 +1885,13 @@
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Jesse Feddema <jdfeddema@gmail.com> */
+UNUSUAL_DEV(  0x177f, 0x0400, 0x0000, 0x0000,
+		"Yarvik",
+		"PMP400",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ),
+
 /* Reported by Hans de Goede <hdegoede@redhat.com>
  * These Appotech controllers are found in Picture Frames, they provide a
  * (buggy) emulation of a cdrom drive which contains the windows software
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index b4a7167..0616f23 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -93,8 +93,8 @@
 
 	interface = usb_find_interface(&skel_driver, subminor);
 	if (!interface) {
-		err("%s - error, can't find device for minor %d",
-		     __func__, subminor);
+		pr_err("%s - error, can't find device for minor %d\n",
+			__func__, subminor);
 		retval = -ENODEV;
 		goto exit;
 	}
@@ -179,8 +179,9 @@
 		if (!(urb->status == -ENOENT ||
 		    urb->status == -ECONNRESET ||
 		    urb->status == -ESHUTDOWN))
-			err("%s - nonzero write bulk status received: %d",
-			    __func__, urb->status);
+			dev_err(&dev->interface->dev,
+				"%s - nonzero write bulk status received: %d\n",
+				__func__, urb->status);
 
 		dev->errors = urb->status;
 	} else {
@@ -213,7 +214,8 @@
 	/* do it */
 	rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
 	if (rv < 0) {
-		err("%s - failed submitting read urb, error %d",
+		dev_err(&dev->interface->dev,
+			"%s - failed submitting read urb, error %d\n",
 			__func__, rv);
 		dev->bulk_in_filled = 0;
 		rv = (rv == -ENOMEM) ? rv : -EIO;
@@ -364,8 +366,9 @@
 		if (!(urb->status == -ENOENT ||
 		    urb->status == -ECONNRESET ||
 		    urb->status == -ESHUTDOWN))
-			err("%s - nonzero write bulk status received: %d",
-			    __func__, urb->status);
+			dev_err(&dev->interface->dev,
+				"%s - nonzero write bulk status received: %d\n",
+				__func__, urb->status);
 
 		spin_lock(&dev->err_lock);
 		dev->errors = urb->status;
@@ -459,8 +462,9 @@
 	retval = usb_submit_urb(urb, GFP_KERNEL);
 	mutex_unlock(&dev->io_mutex);
 	if (retval) {
-		err("%s - failed submitting write urb, error %d", __func__,
-		    retval);
+		dev_err(&dev->interface->dev,
+			"%s - failed submitting write urb, error %d\n",
+			__func__, retval);
 		goto error_unanchor;
 	}
 
@@ -519,7 +523,7 @@
 	/* allocate memory for our device state and initialize it */
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		err("Out of memory");
+		dev_err(&interface->dev, "Out of memory\n");
 		goto error;
 	}
 	kref_init(&dev->kref);
@@ -546,12 +550,14 @@
 			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
 			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
 			if (!dev->bulk_in_buffer) {
-				err("Could not allocate bulk_in_buffer");
+				dev_err(&interface->dev,
+					"Could not allocate bulk_in_buffer\n");
 				goto error;
 			}
 			dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
 			if (!dev->bulk_in_urb) {
-				err("Could not allocate bulk_in_urb");
+				dev_err(&interface->dev,
+					"Could not allocate bulk_in_urb\n");
 				goto error;
 			}
 		}
@@ -563,7 +569,8 @@
 		}
 	}
 	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
-		err("Could not find both bulk-in and bulk-out endpoints");
+		dev_err(&interface->dev,
+			"Could not find both bulk-in and bulk-out endpoints\n");
 		goto error;
 	}
 
@@ -574,7 +581,8 @@
 	retval = usb_register_dev(interface, &skel_class);
 	if (retval) {
 		/* something prevented us from registering this driver */
-		err("Not able to get a minor for this device.");
+		dev_err(&interface->dev,
+			"Not able to get a minor for this device.\n");
 		usb_set_intfdata(interface, NULL);
 		goto error;
 	}
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index a159b63..7af1e81 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -1594,7 +1594,7 @@
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
-		err("dlfb_usb_probe: failed alloc of dev struct\n");
+		dev_err(&interface->dev, "dlfb_usb_probe: failed alloc of dev struct\n");
 		goto error;
 	}
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index f1c8ca6..b0d6282 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -51,6 +51,37 @@
 			struct acpi_object_list *arguments,
 			struct acpi_handle_list *list);
 
+struct acpi_pld {
+	unsigned int revision:7; /* 0 */
+	unsigned int ignore_colour:1; /* 7 */
+	unsigned int colour:24; /* 8 */
+	unsigned int width:16; /* 32 */
+	unsigned int height:16; /* 48 */
+	unsigned int user_visible:1; /* 64 */
+	unsigned int dock:1; /* 65 */
+	unsigned int lid:1; /* 66 */
+	unsigned int panel:3; /* 67 */
+	unsigned int vertical_pos:2; /* 70 */
+	unsigned int horizontal_pos:2; /* 72 */
+	unsigned int shape:4; /* 74 */
+	unsigned int group_orientation:1; /* 78 */
+	unsigned int group_token:8; /* 79 */
+	unsigned int group_position:8; /* 87 */
+	unsigned int bay:1; /* 95 */
+	unsigned int ejectable:1; /* 96 */
+	unsigned int ospm_eject_required:1; /* 97 */
+	unsigned int cabinet_number:8; /* 98 */
+	unsigned int card_cage_number:8; /* 106 */
+	unsigned int reference:1; /* 114 */
+	unsigned int rotation:4; /* 115 */
+	unsigned int order:5; /* 119 */
+	unsigned int reserved:4; /* 124 */
+	unsigned int vertical_offset:16; /* 128 */
+	unsigned int horizontal_offset:16; /* 144 */
+} __attribute__((__packed__));
+
+acpi_status
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld);
 #ifdef CONFIG_ACPI
 
 #include <linux/proc_fs.h>
@@ -407,6 +438,11 @@
 }
 #endif
 
+#else	/* CONFIG_ACPI */
+
+static int register_acpi_bus_type(struct acpi_bus_type *bus) { return 0; }
+static int unregister_acpi_bus_type(struct acpi_bus_type *bus) { return 0; }
+
 #endif				/* CONFIG_ACPI */
 
 #endif /*__ACPI_BUS_H__*/
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 5af9a07..98bb290 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -139,6 +139,7 @@
 	u8 core_unit;
 
 	u32 addr;
+	u32 addr1;
 	u32 wrap;
 
 	void __iomem *io_addr;
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index fffdf00..15be561 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -6,7 +6,7 @@
  *
  * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2012 Freescale Semiconductor, Inc
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -17,6 +17,12 @@
 #ifndef _FSL_DEVICE_H_
 #define _FSL_DEVICE_H_
 
+#define FSL_UTMI_PHY_DLY	10	/*As per P1010RM, delay for UTMI
+				PHY CLK to become stable - 10ms*/
+#define FSL_USB_VER_OLD		0
+#define FSL_USB_VER_1_6		1
+#define FSL_USB_VER_2_2		2
+
 #include <linux/types.h>
 
 /*
@@ -63,6 +69,7 @@
 
 struct fsl_usb2_platform_data {
 	/* board specific information */
+	int				controller_ver;
 	enum fsl_usb2_operating_modes	operating_mode;
 	enum fsl_usb2_phy_modes		phy_mode;
 	unsigned int			port_enables;
diff --git a/include/linux/platform_data/ehci-sh.h b/include/linux/platform_data/ehci-sh.h
new file mode 100644
index 0000000..5c15a73
--- /dev/null
+++ b/include/linux/platform_data/ehci-sh.h
@@ -0,0 +1,28 @@
+/*
+ * EHCI SuperH driver platform data
+ *
+ * Copyright (C) 2012  Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+ * Copyright (C) 2012  Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __USB_EHCI_SH_H
+#define __USB_EHCI_SH_H
+
+struct ehci_sh_platdata {
+	void (*phy_init)(void); /* Phy init function */
+};
+
+#endif /* __USB_EHCI_SH_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/include/linux/platform_data/s3c-hsotg.h
similarity index 89%
rename from arch/arm/plat-samsung/include/plat/udc-hs.h
rename to include/linux/platform_data/s3c-hsotg.h
index c9e3667..97ec12c 100644
--- a/arch/arm/plat-samsung/include/plat/udc-hs.h
+++ b/include/linux/platform_data/s3c-hsotg.h
@@ -1,4 +1,4 @@
-/* arch/arm/plat-s3c/include/plat/udc-hs.h
+/* include/linux/platform_data/s3c-hsotg.h
  *
  * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
@@ -25,7 +25,8 @@
  */
 struct s3c_hsotg_plat {
 	enum s3c_hsotg_dmamode	dma;
-	unsigned int		is_osc : 1;
+	unsigned int		is_osc:1;
+	int                     phy_type;
 
 	int (*phy_init)(struct platform_device *pdev, int type);
 	int (*phy_exit)(struct platform_device *pdev, int type);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 73b68d1..1493345 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -351,10 +351,6 @@
 	int bandwidth_int_reqs;		/* number of Interrupt requests */
 	int bandwidth_isoc_reqs;	/* number of Isoc. requests */
 
-#ifdef CONFIG_USB_DEVICEFS
-	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the bus */
-#endif
-
 #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
 	struct mon_bus *mon_bus;	/* non-null when associated */
 	int monitored;			/* non-zero when monitored */
@@ -493,12 +489,6 @@
 	char *serial;
 
 	struct list_head filelist;
-#ifdef CONFIG_USB_DEVICE_CLASS
-	struct device *usb_classdev;
-#endif
-#ifdef CONFIG_USB_DEVICEFS
-	struct dentry *usbfs_dentry;
-#endif
 
 	int maxchild;
 	struct usb_device **children;
@@ -800,6 +790,8 @@
 				struct device_driver *driver,
 				const char *buf, size_t count);
 
+extern ssize_t usb_show_dynids(struct usb_dynids *dynids, char *buf);
+
 /**
  * struct usbdrv_wrap - wrapper for driver-model structure
  * @driver: The driver-model core driver structure.
@@ -1379,6 +1371,7 @@
 extern void usb_kill_urb(struct urb *urb);
 extern void usb_poison_urb(struct urb *urb);
 extern void usb_unpoison_urb(struct urb *urb);
+extern void usb_block_urb(struct urb *urb);
 extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
 extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
@@ -1391,6 +1384,8 @@
 extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor);
 extern int usb_anchor_empty(struct usb_anchor *anchor);
 
+#define usb_unblock_urb	usb_unpoison_urb
+
 /**
  * usb_urb_dir_in - check if an URB describes an IN transfer
  * @urb: URB to be checked
@@ -1627,6 +1622,7 @@
 	case 0:
 	case -ENOMEM:
 	case -ENODEV:
+	case -EOPNOTSUPP:
 		return error_code;
 	default:
 		return -EIO;
@@ -1652,9 +1648,6 @@
 } while (0)
 #endif
 
-#define err(format, arg...)					\
-	printk(KERN_ERR KBUILD_MODNAME ": " format "\n", ##arg)
-
 /* debugfs stuff */
 extern struct dentry *usb_debug_root;
 
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index af21f31..e785d85 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -88,6 +88,8 @@
 #define USB_REQ_GET_INTERFACE		0x0A
 #define USB_REQ_SET_INTERFACE		0x0B
 #define USB_REQ_SYNCH_FRAME		0x0C
+#define USB_REQ_SET_SEL			0x30
+#define USB_REQ_SET_ISOCH_DELAY		0x31
 
 #define USB_REQ_SET_ENCRYPTION		0x0D	/* Wireless USB */
 #define USB_REQ_GET_ENCRYPTION		0x0E
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
new file mode 100644
index 0000000..edb90d6
--- /dev/null
+++ b/include/linux/usb/chipidea.h
@@ -0,0 +1,28 @@
+/*
+ * Platform data for the chipidea USB dual role controller
+ */
+
+#ifndef __LINUX_USB_CHIPIDEA_H
+#define __LINUX_USB_CHIPIDEA_H
+
+struct ci13xxx;
+struct ci13xxx_udc_driver {
+	const char	*name;
+	/* offset of the capability registers */
+	uintptr_t	 capoffset;
+	unsigned	 power_budget;
+	unsigned long	 flags;
+#define CI13XXX_REGS_SHARED		BIT(0)
+#define CI13XXX_REQUIRE_TRANSCEIVER	BIT(1)
+#define CI13XXX_PULLUP_ON_VBUS		BIT(2)
+#define CI13XXX_DISABLE_STREAMING	BIT(3)
+
+#define CI13XXX_CONTROLLER_RESET_EVENT		0
+#define CI13XXX_CONTROLLER_STOPPED_EVENT	1
+	void	(*notify_event) (struct ci13xxx *udc, unsigned event);
+};
+
+/* Default offset of capability registers */
+#define DEF_CAPOFFSET		0x100
+
+#endif
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index a316fba..9d8c3b6 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -242,6 +242,9 @@
 		struct usb_configuration *,
 		int (*)(struct usb_configuration *));
 
+void usb_remove_config(struct usb_composite_dev *,
+		struct usb_configuration *);
+
 /**
  * struct usb_composite_driver - groups configurations into a gadget
  * @name: For diagnostics, identifies the driver.
@@ -250,6 +253,8 @@
  * @iManufacturer: Used as iManufacturer override if @dev->iManufacturer is
  *	not set. If NULL a default "<system> <release> with <udc>" value
  *	will be used.
+ * @iSerialNumber: Used as iSerialNumber override if @dev->iSerialNumber is
+ *	not set.
  * @dev: Template descriptor for the device, including default device
  *	identifiers.
  * @strings: tables of strings, keyed by identifiers assigned during bind()
@@ -280,6 +285,7 @@
 	const char				*name;
 	const char				*iProduct;
 	const char				*iManufacturer;
+	const char				*iSerialNumber;
 	const struct usb_device_descriptor	*dev;
 	struct usb_gadget_strings		**strings;
 	enum usb_device_speed			max_speed;
diff --git a/include/linux/usb/functionfs.h b/include/linux/usb/functionfs.h
index 7587ef9..a843d08 100644
--- a/include/linux/usb/functionfs.h
+++ b/include/linux/usb/functionfs.h
@@ -190,8 +190,10 @@
 	__attribute__((warn_unused_result, nonnull));
 static void functionfs_closed_callback(struct ffs_data *ffs)
 	__attribute__((nonnull));
-static int functionfs_check_dev_callback(const char *dev_name)
+static void *functionfs_acquire_dev_callback(const char *dev_name)
 	__attribute__((warn_unused_result, nonnull));
+static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
+	__attribute__((nonnull));
 
 
 #endif
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index d28cc78..bbb9464 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -584,29 +584,6 @@
 }
 #endif /* CONFIG_USB_SUSPEND */
 
-
-/*
- * USB device fs stuff
- */
-
-#ifdef CONFIG_USB_DEVICEFS
-
-/*
- * these are expected to be called from the USB core/hub thread
- * with the kernel lock held
- */
-extern void usbfs_update_special(void);
-extern int usbfs_init(void);
-extern void usbfs_cleanup(void);
-
-#else /* CONFIG_USB_DEVICEFS */
-
-static inline void usbfs_update_special(void) {}
-static inline int usbfs_init(void) { return 0; }
-static inline void usbfs_cleanup(void) { }
-
-#endif /* CONFIG_USB_DEVICEFS */
-
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
diff --git a/include/linux/usb/isp1301.h b/include/linux/usb/isp1301.h
new file mode 100644
index 0000000..d3a851c
--- /dev/null
+++ b/include/linux/usb/isp1301.h
@@ -0,0 +1,80 @@
+/*
+ * NXP ISP1301 USB transceiver driver
+ *
+ * Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_USB_ISP1301_H
+#define __LINUX_USB_ISP1301_H
+
+#include <linux/of.h>
+
+/* I2C Register definitions: */
+
+#define ISP1301_I2C_MODE_CONTROL_1	0x04	/* u8 read, set, +1 clear */
+
+#define MC1_SPEED_REG			(1 << 0)
+#define MC1_SUSPEND_REG			(1 << 1)
+#define MC1_DAT_SE0			(1 << 2)
+#define MC1_TRANSPARENT			(1 << 3)
+#define MC1_BDIS_ACON_EN		(1 << 4)
+#define MC1_OE_INT_EN			(1 << 5)
+#define MC1_UART_EN			(1 << 6)
+#define MC1_MASK			0x7f
+
+#define ISP1301_I2C_MODE_CONTROL_2	0x12	/* u8 read, set, +1 clear */
+
+#define MC2_GLOBAL_PWR_DN		(1 << 0)
+#define MC2_SPD_SUSP_CTRL		(1 << 1)
+#define MC2_BI_DI			(1 << 2)
+#define MC2_TRANSP_BDIR0		(1 << 3)
+#define MC2_TRANSP_BDIR1		(1 << 4)
+#define MC2_AUDIO_EN			(1 << 5)
+#define MC2_PSW_EN			(1 << 6)
+#define MC2_EN2V7			(1 << 7)
+
+#define ISP1301_I2C_OTG_CONTROL_1	0x06	/* u8 read, set, +1 clear */
+
+#define OTG1_DP_PULLUP			(1 << 0)
+#define OTG1_DM_PULLUP			(1 << 1)
+#define OTG1_DP_PULLDOWN		(1 << 2)
+#define OTG1_DM_PULLDOWN		(1 << 3)
+#define OTG1_ID_PULLDOWN		(1 << 4)
+#define OTG1_VBUS_DRV			(1 << 5)
+#define OTG1_VBUS_DISCHRG		(1 << 6)
+#define OTG1_VBUS_CHRG			(1 << 7)
+
+#define ISP1301_I2C_OTG_CONTROL_2	0x10	/* u8 readonly */
+
+#define OTG_B_SESS_END			(1 << 6)
+#define OTG_B_SESS_VLD			(1 << 7)
+
+#define ISP1301_I2C_INTERRUPT_SOURCE	0x8
+#define ISP1301_I2C_INTERRUPT_LATCH	0xA
+#define ISP1301_I2C_INTERRUPT_FALLING	0xC
+#define ISP1301_I2C_INTERRUPT_RISING	0xE
+
+#define INT_VBUS_VLD			(1 << 0)
+#define INT_SESS_VLD			(1 << 1)
+#define INT_DP_HI			(1 << 2)
+#define INT_ID_GND			(1 << 3)
+#define INT_DM_HI			(1 << 4)
+#define INT_ID_FLOAT			(1 << 5)
+#define INT_BDIS_ACON			(1 << 6)
+#define INT_CR_INT			(1 << 7)
+
+#define ISP1301_I2C_REG_CLEAR_ADDR	1	/* Register Address Modifier */
+
+struct i2c_client *isp1301_get_client(struct device_node *node);
+
+#endif /* __LINUX_USB_ISP1301_H */
diff --git a/include/linux/usb/langwell_udc.h b/include/linux/usb/langwell_udc.h
deleted file mode 100644
index 2d2d1bb..0000000
--- a/include/linux/usb/langwell_udc.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Intel Langwell USB Device Controller driver
- * Copyright (C) 2008-2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef __LANGWELL_UDC_H
-#define __LANGWELL_UDC_H
-
-
-/* MACRO defines */
-#define	CAP_REG_OFFSET		0x0
-#define	OP_REG_OFFSET		0x28
-
-#define	DMA_ADDR_INVALID	(~(dma_addr_t)0)
-
-#define	DQH_ALIGNMENT		2048
-#define	DTD_ALIGNMENT		64
-#define	DMA_BOUNDARY		4096
-
-#define	EP0_MAX_PKT_SIZE	64
-#define EP_DIR_IN		1
-#define EP_DIR_OUT		0
-
-#define FLUSH_TIMEOUT		1000
-#define RESET_TIMEOUT		1000
-#define SETUPSTAT_TIMEOUT	100
-#define PRIME_TIMEOUT		100
-
-
-/* device memory space registers */
-
-/* Capability Registers, BAR0 + CAP_REG_OFFSET */
-struct langwell_cap_regs {
-	/* offset: 0x0 */
-	u8	caplength;	/* offset of Operational Register */
-	u8	_reserved3;
-	u16	hciversion;	/* H: BCD encoding of host version */
-	u32	hcsparams;	/* H: host port steering logic capability */
-	u32	hccparams;	/* H: host multiple mode control capability */
-#define	HCC_LEN	BIT(17)		/* Link power management (LPM) capability */
-	u8	_reserved4[0x20-0xc];
-	/* offset: 0x20 */
-	u16	dciversion;	/* BCD encoding of device version */
-	u8	_reserved5[0x24-0x22];
-	u32	dccparams;	/* overall device controller capability */
-#define	HOSTCAP	BIT(8)		/* host capable */
-#define	DEVCAP	BIT(7)		/* device capable */
-#define DEN(d)	\
-	(((d)>>0)&0x1f)		/* bits 4:0, device endpoint number */
-} __attribute__ ((packed));
-
-
-/* Operational Registers, BAR0 + OP_REG_OFFSET */
-struct langwell_op_regs {
-	/* offset: 0x28 */
-	u32	extsts;
-#define	EXTS_TI1	BIT(4)	/* general purpose timer interrupt 1 */
-#define	EXTS_TI1TI0	BIT(3)	/* general purpose timer interrupt 0 */
-#define	EXTS_TI1UPI	BIT(2)	/* USB host periodic interrupt */
-#define	EXTS_TI1UAI	BIT(1)	/* USB host asynchronous interrupt */
-#define	EXTS_TI1NAKI	BIT(0)	/* NAK interrupt */
-	u32	extintr;
-#define	EXTI_TIE1	BIT(4)	/* general purpose timer interrupt enable 1 */
-#define	EXTI_TIE0	BIT(3)	/* general purpose timer interrupt enable 0 */
-#define	EXTI_UPIE	BIT(2)	/* USB host periodic interrupt enable */
-#define	EXTI_UAIE	BIT(1)	/* USB host asynchronous interrupt enable */
-#define	EXTI_NAKE	BIT(0)	/* NAK interrupt enable */
-	/* offset: 0x30 */
-	u32	usbcmd;
-#define	CMD_HIRD(u)	\
-	(((u)>>24)&0xf)		/* bits 27:24, host init resume duration */
-#define	CMD_ITC(u)	\
-	(((u)>>16)&0xff)	/* bits 23:16, interrupt threshold control */
-#define	CMD_PPE		BIT(15)	/* per-port change events enable */
-#define	CMD_ATDTW	BIT(14)	/* add dTD tripwire */
-#define	CMD_SUTW	BIT(13)	/* setup tripwire */
-#define	CMD_ASPE	BIT(11) /* asynchronous schedule park mode enable */
-#define	CMD_FS2		BIT(10)	/* frame list size */
-#define	CMD_ASP1	BIT(9)	/* asynchronous schedule park mode count */
-#define	CMD_ASP0	BIT(8)
-#define	CMD_LR		BIT(7)	/* light host/device controller reset */
-#define	CMD_IAA		BIT(6)	/* interrupt on async advance doorbell */
-#define	CMD_ASE		BIT(5)	/* asynchronous schedule enable */
-#define	CMD_PSE		BIT(4)	/* periodic schedule enable */
-#define	CMD_FS1		BIT(3)
-#define	CMD_FS0		BIT(2)
-#define	CMD_RST		BIT(1)	/* controller reset */
-#define	CMD_RUNSTOP	BIT(0)	/* run/stop */
-	u32	usbsts;
-#define	STS_PPCI(u)	\
-	(((u)>>16)&0xffff)	/* bits 31:16, port-n change detect */
-#define	STS_AS		BIT(15)	/* asynchronous schedule status */
-#define	STS_PS		BIT(14)	/* periodic schedule status */
-#define	STS_RCL		BIT(13)	/* reclamation */
-#define	STS_HCH		BIT(12)	/* HC halted */
-#define	STS_ULPII	BIT(10)	/* ULPI interrupt */
-#define	STS_SLI		BIT(8)	/* DC suspend */
-#define	STS_SRI		BIT(7)	/* SOF received */
-#define	STS_URI		BIT(6)	/* USB reset received */
-#define	STS_AAI		BIT(5)	/* interrupt on async advance */
-#define	STS_SEI		BIT(4)	/* system error */
-#define	STS_FRI		BIT(3)	/* frame list rollover */
-#define	STS_PCI		BIT(2)	/* port change detect */
-#define	STS_UEI		BIT(1)	/* USB error interrupt */
-#define	STS_UI		BIT(0)	/* USB interrupt */
-	u32	usbintr;
-/* bits 31:16, per-port interrupt enable */
-#define	INTR_PPCE(u)	(((u)>>16)&0xffff)
-#define	INTR_ULPIE	BIT(10)	/* ULPI enable */
-#define	INTR_SLE	BIT(8)	/* DC sleep/suspend enable */
-#define	INTR_SRE	BIT(7)	/* SOF received enable */
-#define	INTR_URE	BIT(6)	/* USB reset enable */
-#define	INTR_AAE	BIT(5)	/* interrupt on async advance enable */
-#define	INTR_SEE	BIT(4)	/* system error enable */
-#define	INTR_FRE	BIT(3)	/* frame list rollover enable */
-#define	INTR_PCE	BIT(2)	/* port change detect enable */
-#define	INTR_UEE	BIT(1)	/* USB error interrupt enable */
-#define	INTR_UE		BIT(0)	/* USB interrupt enable */
-	u32	frindex;	/* frame index */
-#define	FRINDEX_MASK	(0x3fff << 0)
-	u32	ctrldssegment;	/* not used */
-	u32	deviceaddr;
-#define USBADR_SHIFT	25
-#define	USBADR(d)	\
-	(((d)>>25)&0x7f)	/* bits 31:25, device address */
-#define USBADR_MASK	(0x7f << 25)
-#define	USBADRA		BIT(24)	/* device address advance */
-	u32	endpointlistaddr;/* endpoint list top memory address */
-/* bits 31:11, endpoint list pointer */
-#define	EPBASE(d)	(((d)>>11)&0x1fffff)
-#define	ENDPOINTLISTADDR_MASK	(0x1fffff << 11)
-	u32	ttctrl;		/* H: TT operatin, not used */
-	/* offset: 0x50 */
-	u32	burstsize;	/* burst size of data movement */
-#define	TXPBURST(b)	\
-	(((b)>>8)&0xff)		/* bits 15:8, TX burst length */
-#define	RXPBURST(b)	\
-	(((b)>>0)&0xff)		/* bits 7:0, RX burst length */
-	u32	txfilltuning;	/* TX tuning */
-	u32	txttfilltuning;	/* H: TX TT tuning */
-	u32	ic_usb;		/* control the IC_USB FS/LS transceiver */
-	/* offset: 0x60 */
-	u32	ulpi_viewport;	/* indirect access to ULPI PHY */
-#define	ULPIWU		BIT(31)	/* ULPI wakeup */
-#define	ULPIRUN		BIT(30)	/* ULPI read/write run */
-#define	ULPIRW		BIT(29)	/* ULPI read/write control */
-#define	ULPISS		BIT(27)	/* ULPI sync state */
-#define	ULPIPORT(u)	\
-	(((u)>>24)&7)		/* bits 26:24, ULPI port number */
-#define	ULPIADDR(u)	\
-	(((u)>>16)&0xff)	/* bits 23:16, ULPI data address */
-#define	ULPIDATRD(u)	\
-	(((u)>>8)&0xff)		/* bits 15:8, ULPI data read */
-#define	ULPIDATWR(u)	\
-	(((u)>>0)&0xff)		/* bits 7:0, ULPI date write */
-	u8	_reserved6[0x70-0x64];
-	/* offset: 0x70 */
-	u32	configflag;	/* H: not used */
-	u32	portsc1;	/* port status */
-#define	DA(p)	\
-	(((p)>>25)&0x7f)	/* bits 31:25, device address */
-#define	PORTS_SSTS	(BIT(24) | BIT(23))	/* suspend status */
-#define	PORTS_WKOC	BIT(22)	/* wake on over-current enable */
-#define	PORTS_WKDS	BIT(21)	/* wake on disconnect enable */
-#define	PORTS_WKCN	BIT(20)	/* wake on connect enable */
-#define	PORTS_PTC(p)	(((p)>>16)&0xf)	/* bits 19:16, port test control */
-#define	PORTS_PIC	(BIT(15) | BIT(14))	/* port indicator control */
-#define	PORTS_PO	BIT(13)	/* port owner */
-#define	PORTS_PP	BIT(12)	/* port power */
-#define	PORTS_LS	(BIT(11) | BIT(10))	/* line status */
-#define	PORTS_SLP	BIT(9)	/* suspend using L1 */
-#define	PORTS_PR	BIT(8)	/* port reset */
-#define	PORTS_SUSP	BIT(7)	/* suspend */
-#define	PORTS_FPR	BIT(6)	/* force port resume */
-#define	PORTS_OCC	BIT(5)	/* over-current change */
-#define	PORTS_OCA	BIT(4)	/* over-current active */
-#define	PORTS_PEC	BIT(3)	/* port enable/disable change */
-#define	PORTS_PE	BIT(2)	/* port enable/disable */
-#define	PORTS_CSC	BIT(1)	/* connect status change */
-#define	PORTS_CCS	BIT(0)	/* current connect status */
-	u8	_reserved7[0xb4-0x78];
-	/* offset: 0xb4 */
-	u32	devlc;		/* control LPM and each USB port behavior */
-/* bits 31:29, parallel transceiver select */
-#define	LPM_PTS(d)	(((d)>>29)&7)
-#define	LPM_STS		BIT(28)	/* serial transceiver select */
-#define	LPM_PTW		BIT(27)	/* parallel transceiver width */
-#define	LPM_PSPD(d)	(((d)>>25)&3)	/* bits 26:25, port speed */
-#define LPM_PSPD_MASK	(BIT(26) | BIT(25))
-#define LPM_SPEED_FULL	0
-#define LPM_SPEED_LOW	1
-#define LPM_SPEED_HIGH	2
-#define	LPM_SRT		BIT(24)	/* shorten reset time */
-#define	LPM_PFSC	BIT(23)	/* port force full speed connect */
-#define	LPM_PHCD	BIT(22) /* PHY low power suspend clock disable */
-#define	LPM_STL		BIT(16)	/* STALL reply to LPM token */
-#define	LPM_BA(d)	\
-	(((d)>>1)&0x7ff)	/* bits 11:1, BmAttributes */
-#define	LPM_NYT_ACK	BIT(0)	/* NYET/ACK reply to LPM token */
-	u8	_reserved8[0xf4-0xb8];
-	/* offset: 0xf4 */
-	u32	otgsc;		/* On-The-Go status and control */
-#define	OTGSC_DPIE	BIT(30)	/* data pulse interrupt enable */
-#define	OTGSC_MSE	BIT(29)	/* 1 ms timer interrupt enable */
-#define	OTGSC_BSEIE	BIT(28)	/* B session end interrupt enable */
-#define	OTGSC_BSVIE	BIT(27)	/* B session valid interrupt enable */
-#define	OTGSC_ASVIE	BIT(26)	/* A session valid interrupt enable */
-#define	OTGSC_AVVIE	BIT(25)	/* A VBUS valid interrupt enable */
-#define	OTGSC_IDIE	BIT(24)	/* USB ID interrupt enable */
-#define	OTGSC_DPIS	BIT(22)	/* data pulse interrupt status */
-#define	OTGSC_MSS	BIT(21)	/* 1 ms timer interrupt status */
-#define	OTGSC_BSEIS	BIT(20)	/* B session end interrupt status */
-#define	OTGSC_BSVIS	BIT(19)	/* B session valid interrupt status */
-#define	OTGSC_ASVIS	BIT(18)	/* A session valid interrupt status */
-#define	OTGSC_AVVIS	BIT(17)	/* A VBUS valid interrupt status */
-#define	OTGSC_IDIS	BIT(16)	/* USB ID interrupt status */
-#define	OTGSC_DPS	BIT(14)	/* data bus pulsing status */
-#define	OTGSC_MST	BIT(13)	/* 1 ms timer toggle */
-#define	OTGSC_BSE	BIT(12)	/* B session end */
-#define	OTGSC_BSV	BIT(11)	/* B session valid */
-#define	OTGSC_ASV	BIT(10)	/* A session valid */
-#define	OTGSC_AVV	BIT(9)	/* A VBUS valid */
-#define	OTGSC_USBID	BIT(8)	/* USB ID */
-#define	OTGSC_HABA	BIT(7)	/* hw assist B-disconnect to A-connect */
-#define	OTGSC_HADP	BIT(6)	/* hw assist data pulse */
-#define	OTGSC_IDPU	BIT(5)	/* ID pullup */
-#define	OTGSC_DP	BIT(4)	/* data pulsing */
-#define	OTGSC_OT	BIT(3)	/* OTG termination */
-#define	OTGSC_HAAR	BIT(2)	/* hw assist auto reset */
-#define	OTGSC_VC	BIT(1)	/* VBUS charge */
-#define	OTGSC_VD	BIT(0)	/* VBUS discharge */
-	u32	usbmode;
-#define	MODE_VBPS	BIT(5)	/* R/W VBUS power select */
-#define	MODE_SDIS	BIT(4)	/* R/W stream disable mode */
-#define	MODE_SLOM	BIT(3)	/* R/W setup lockout mode */
-#define	MODE_ENSE	BIT(2)	/* endian select */
-#define	MODE_CM(u)	(((u)>>0)&3)	/* bits 1:0, controller mode */
-#define	MODE_IDLE	0
-#define	MODE_DEVICE	2
-#define	MODE_HOST	3
-	u8	_reserved9[0x100-0xfc];
-	/* offset: 0x100 */
-	u32	endptnak;
-#define	EPTN(e)		\
-	(((e)>>16)&0xffff)	/* bits 31:16, TX endpoint NAK */
-#define	EPRN(e)		\
-	(((e)>>0)&0xffff)	/* bits 15:0, RX endpoint NAK */
-	u32	endptnaken;
-#define	EPTNE(e)	\
-	(((e)>>16)&0xffff)	/* bits 31:16, TX endpoint NAK enable */
-#define	EPRNE(e)	\
-	(((e)>>0)&0xffff)	/* bits 15:0, RX endpoint NAK enable */
-	u32	endptsetupstat;
-#define	SETUPSTAT_MASK		(0xffff << 0)	/* bits 15:0 */
-#define EP0SETUPSTAT_MASK	1
-	u32	endptprime;
-/* bits 31:16, prime endpoint transmit buffer */
-#define	PETB(e)		(((e)>>16)&0xffff)
-/* bits 15:0, prime endpoint receive buffer */
-#define	PERB(e)		(((e)>>0)&0xffff)
-	/* offset: 0x110 */
-	u32	endptflush;
-/* bits 31:16, flush endpoint transmit buffer */
-#define	FETB(e)		(((e)>>16)&0xffff)
-/* bits 15:0, flush endpoint receive buffer */
-#define	FERB(e)		(((e)>>0)&0xffff)
-	u32	endptstat;
-/* bits 31:16, endpoint transmit buffer ready */
-#define	ETBR(e)		(((e)>>16)&0xffff)
-/* bits 15:0, endpoint receive buffer ready */
-#define	ERBR(e)		(((e)>>0)&0xffff)
-	u32	endptcomplete;
-/* bits 31:16, endpoint transmit complete event */
-#define	ETCE(e)		(((e)>>16)&0xffff)
-/* bits 15:0, endpoint receive complete event */
-#define	ERCE(e)		(((e)>>0)&0xffff)
-	/* offset: 0x11c */
-	u32	endptctrl[16];
-#define	EPCTRL_TXE	BIT(23)	/* TX endpoint enable */
-#define	EPCTRL_TXR	BIT(22)	/* TX data toggle reset */
-#define	EPCTRL_TXI	BIT(21)	/* TX data toggle inhibit */
-#define	EPCTRL_TXT(e)	(((e)>>18)&3)	/* bits 19:18, TX endpoint type */
-#define	EPCTRL_TXT_SHIFT	18
-#define	EPCTRL_TXD	BIT(17)	/* TX endpoint data source */
-#define	EPCTRL_TXS	BIT(16)	/* TX endpoint STALL */
-#define	EPCTRL_RXE	BIT(7)	/* RX endpoint enable */
-#define	EPCTRL_RXR	BIT(6)	/* RX data toggle reset */
-#define	EPCTRL_RXI	BIT(5)	/* RX data toggle inhibit */
-#define	EPCTRL_RXT(e)	(((e)>>2)&3)	/* bits 3:2, RX endpoint type */
-#define	EPCTRL_RXT_SHIFT	2	/* bits 19:18, TX endpoint type */
-#define	EPCTRL_RXD	BIT(1)	/* RX endpoint data sink */
-#define	EPCTRL_RXS	BIT(0)	/* RX endpoint STALL */
-} __attribute__ ((packed));
-
-#endif /* __LANGWELL_UDC_H */
-
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 4742838..86c0b45 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter stuff
  *
- *	Copyright (C) 1999 - 2005
+ *	Copyright (C) 1999 - 2012
  *	    Greg Kroah-Hartman (greg@kroah.com)
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -249,6 +249,7 @@
 
 	int (*suspend)(struct usb_serial *serial, pm_message_t message);
 	int (*resume)(struct usb_serial *serial);
+	int (*reset_resume)(struct usb_serial *serial);
 
 	/* serial function calls */
 	/* Called by console and by the tty layer */
@@ -292,16 +293,11 @@
 #define to_usb_serial_driver(d) \
 	container_of(d, struct usb_serial_driver, driver)
 
-extern int usb_serial_register_drivers(struct usb_driver *udriver,
-		struct usb_serial_driver * const serial_drivers[]);
-extern void usb_serial_deregister_drivers(struct usb_driver *udriver,
-		struct usb_serial_driver * const serial_drivers[]);
+extern int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
+		const char *name, const struct usb_device_id *id_table);
+extern void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[]);
 extern void usb_serial_port_softint(struct usb_serial_port *port);
 
-extern int usb_serial_probe(struct usb_interface *iface,
-			    const struct usb_device_id *id);
-extern void usb_serial_disconnect(struct usb_interface *iface);
-
 extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t message);
 extern int usb_serial_resume(struct usb_interface *intf);
 
@@ -400,8 +396,8 @@
 
 /*
  * module_usb_serial_driver() - Helper macro for registering a USB Serial driver
- * @__usb_driver: usb_driver struct to register
  * @__serial_drivers: list of usb_serial drivers to register
+ * @__ids: all device ids that @__serial_drivers bind to
  *
  * Helper macro for USB serial drivers which do not do anything special
  * in module init/exit. This eliminates a lot of boilerplate. Each
@@ -409,9 +405,21 @@
  * module_init() and module_exit()
  *
  */
-#define module_usb_serial_driver(__usb_driver, __serial_drivers)	\
-	module_driver(__usb_driver, usb_serial_register_drivers,	\
-		       usb_serial_deregister_drivers, __serial_drivers)
+#define usb_serial_module_driver(__name, __serial_drivers, __ids)	\
+static int __init usb_serial_module_init(void)				\
+{									\
+	return usb_serial_register_drivers(__serial_drivers,		\
+					   __name, __ids);		\
+}									\
+module_init(usb_serial_module_init);					\
+static void __exit usb_serial_module_exit(void)				\
+{									\
+	usb_serial_deregister_drivers(__serial_drivers);		\
+}									\
+module_exit(usb_serial_module_exit);
+
+#define module_usb_serial_driver(__serial_drivers, __ids)		\
+	usb_serial_module_driver(KBUILD_MODNAME, __serial_drivers, __ids)
 
 #endif /* __LINUX_USB_SERIAL_H */
 
diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c
index 4b107b5..8674b9e 100644
--- a/tools/usb/ffs-test.c
+++ b/tools/usb/ffs-test.c
@@ -297,7 +297,7 @@
 
 		ret = t->in(t, t->buf, t->buf_size);
 		if (ret > 0) {
-			ret = t->out(t, t->buf, t->buf_size);
+			ret = t->out(t, t->buf, ret);
 			name = out_name;
 			op = "write";
 		} else {
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c
index 6e0f567..82d7c59 100644
--- a/tools/usb/testusb.c
+++ b/tools/usb/testusb.c
@@ -358,6 +358,7 @@
 {
 	static char usbfs_path_0[] = "/dev/usb/devices";
 	static char usbfs_path_1[] = "/proc/bus/usb/devices";
+	static char udev_usb_path[] = "/dev/bus/usb";
 
 	static char *const usbfs_paths[] = {
 		usbfs_path_0, usbfs_path_1
@@ -376,6 +377,10 @@
 		}
 	} while (++it != end);
 
+	/* real device-nodes managed by udev */
+	if (access(udev_usb_path, F_OK) == 0)
+		return udev_usb_path;
+
 	return NULL;
 }