diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index 864637f25bee49a616865901ed6b0d4daa1791c8..3a4abfc44f5e0d8a9e358626c1ca8251d756003d 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -1,3 +1,23 @@
+What:		/sys/bus/usb/devices/INTERFACE/authorized
+Date:		August 2015
+Description:
+		This allows to authorize (1) or deauthorize (0)
+		individual interfaces instead a whole device
+		in contrast to the device authorization.
+		If a deauthorized interface will be authorized
+		so the driver probing must be triggered manually
+		by writing INTERFACE to /sys/bus/usb/drivers_probe
+		This allows to avoid side-effects with drivers
+		that need multiple interfaces.
+		A deauthorized interface cannot be probed or claimed.
+
+What:		/sys/bus/usb/devices/usbX/interface_authorized_default
+Date:		August 2015
+Description:
+		This is used as value that determines if interfaces
+		would be authorized by default.
+		The value can be 1 or 0. It's by default 1.
+
 What:		/sys/bus/usb/device/.../authorized
 Date:		July 2008
 KernelVersion:	2.6.26
diff --git a/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt b/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
new file mode 100644
index 0000000000000000000000000000000000000000..761c4bc24a9b4612f15f58dd7d24da82a5838802
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
@@ -0,0 +1,47 @@
+Broadcom Cygnus PCIe PHY
+
+Required properties:
+- compatible: must be "brcm,cygnus-pcie-phy"
+- reg: base address and length of the PCIe PHY block
+- #address-cells: must be 1
+- #size-cells: must be 0
+
+Each PCIe PHY should be represented by a child node
+
+Required properties For the child node:
+- reg: the PHY ID
+0 - PCIe RC 0
+1 - PCIe RC 1
+- #phy-cells: must be 0
+
+Example:
+	pcie_phy: phy@0301d0a0 {
+		compatible = "brcm,cygnus-pcie-phy";
+		reg = <0x0301d0a0 0x14>;
+
+		pcie0_phy: phy@0 {
+			reg = <0>;
+			#phy-cells = <0>;
+		};
+
+		pcie1_phy: phy@1 {
+			reg = <1>;
+			#phy-cells = <0>;
+		};
+	};
+
+	/* users of the PCIe phy */
+
+	pcie0: pcie@18012000 {
+		...
+		...
+		phys = <&pcie0_phy>;
+		phy-names = "pcie-phy";
+	};
+
+	pcie1: pcie@18013000 {
+		...
+		...
+		phys = <pcie1_phy>;
+		phy-names = "pcie-phy";
+	};
diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
new file mode 100644
index 0000000000000000000000000000000000000000..00100cf3e037aa7f7bceb932518550769010b78a
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
@@ -0,0 +1,68 @@
+mt65xx USB3.0 PHY binding
+--------------------------
+
+This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC.
+
+Required properties (controller (parent) node):
+ - compatible	: should be "mediatek,mt8173-u3phy"
+ - reg		: offset and length of register for phy, exclude port's
+		  register.
+ - clocks	: a list of phandle + clock-specifier pairs, one for each
+		  entry in clock-names
+ - clock-names	: must contain
+		  "u3phya_ref": for reference clock of usb3.0 analog phy.
+
+Required nodes	: a sub-node is required for each port the controller
+		  provides. Address range information including the usual
+		  'reg' property is used inside these nodes to describe
+		  the controller's topology.
+
+Required properties (port (child) node):
+- reg		: address and length of the register set for the port.
+- #phy-cells	: should be 1 (See second example)
+		  cell after port phandle is phy type from:
+			- PHY_TYPE_USB2
+			- PHY_TYPE_USB3
+
+Example:
+
+u3phy: usb-phy@11290000 {
+	compatible = "mediatek,mt8173-u3phy";
+	reg = <0 0x11290000 0 0x800>;
+	clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+	clock-names = "u3phya_ref";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+	status = "okay";
+
+	phy_port0: port@11290800 {
+		reg = <0 0x11290800 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+
+	phy_port1: port@11291000 {
+		reg = <0 0x11291000 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+};
+
+Specifying phy control of devices
+---------------------------------
+
+Device nodes should specify the configuration required in their "phys"
+property, containing a phandle to the phy port node and a device type;
+phy-names for each port are optional.
+
+Example:
+
+#include <dt-bindings/phy/phy.h>
+
+usb30: usb@11270000 {
+	...
+	phys = <&phy_port0 PHY_TYPE_USB3>;
+	phy-names = "usb3-0";
+	...
+};
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 60c6f2a633e02d7b7179ec45c7b31bcda378f802..0289d3b07853e73f494106aca13780899a508abc 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -44,6 +44,9 @@ Required properties:
 	- the "ref" clock is used to get the rate of the clock provided to the
 	  PHY module
 
+Optional properties:
+- vbus-supply: power-supply phandle for vbus power source
+
 The first phandle argument in the PHY specifier identifies the PHY, its
 meaning is compatible dependent. For the currently supported SoCs (Exynos 4210
 and Exynos 4212) it is as follows:
diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index a057b75ba4b5f2d39b51f55c85b814b95f165820..781296bfbe4faacc951feb2756fb4232a0f8027c 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -27,10 +27,6 @@ Optional properties:
 - vbus-supply: reference to the VBUS regulator
 - maximum-speed: limit the maximum connection speed to "full-speed".
 - tpl-support: TPL (Targeted Peripheral List) feature for targeted hosts
-- fsl,usbmisc: (FSL only) phandler of non-core register device, with one
-  argument that indicate usb controller index
-- disable-over-current: (FSL only) disable over current detect
-- external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
 - itc-setting: interrupt threshold control register control, the setting
   should be aligned with ITC bits at register USBCMD.
 - ahb-burst-config: it is vendor dependent, the required value should be
@@ -41,11 +37,28 @@ Optional properties:
 - tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
   (4 bytes), This register represents the maximum length of a the burst
   in 32-bit words while moving data from system memory to the USB
-  bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
+  bus, the value of this property will only take effect if property
+  "ahb-burst-config" is set to 0, if this property is missing the reset
+  default of the hardware implementation will be used.
 - rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
   (4 bytes), This register represents the maximum length of a the burst
   in 32-bit words while moving data from the USB bus to system memory,
-  changing this value takes effect only the SBUSCFG.AHBBRST is 0.
+  the value of this property will only take effect if property
+  "ahb-burst-config" is set to 0, if this property is missing the reset
+  default of the hardware implementation will be used.
+- extcon: phandles to external connector devices. First phandle should point to
+  external connector, which provide "USB" cable events, the second should point
+  to external connector device, which provide "USB-HOST" cable events. If one
+  of the external connector devices is not required, empty <0> phandle should
+  be specified.
+- phy-clkgate-delay-us: the delay time (us) between putting the PHY into
+  low power mode and gating the PHY clock.
+
+i.mx specific properties
+- fsl,usbmisc: phandler of non-core register device, with one
+  argument that indicate usb controller index
+- disable-over-current: disable over current detect
+- external-vbus-divider: enables off-chip resistor divider for Vbus
 
 Example:
 
@@ -62,4 +75,6 @@ Example:
 		ahb-burst-config = <0x0>;
 		tx-burst-size-dword = <0x10>; /* 64 bytes */
 		rx-burst-size-dword = <0x10>;
+		extcon = <0>, <&usb_id>;
+		phy-clkgate-delay-us = <400>;
 	};
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 0815eac5b18511152135f87defe856595de2889c..9ff48e0defb4651743c25916ed6c7a9d88853042 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -35,11 +35,16 @@ Optional properties:
 			LTSSM during USB3 Compliance mode.
  - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy.
  - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy.
+ - snps,dis_enblslpm_quirk: when set clears the enblslpm in GUSB2PHYCFG,
+			disabling the suspend signal to the PHY.
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
 			utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
  - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
    UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
+ - snps,quirk-frame-length-adjustment: Value for GFLADJ_30MHZ field of GFLADJ
+	register for post-silicon frame length adjustment when the
+	fladj_30mhz_sdbnd signal is invalid or incorrect.
 
 This is usually a subnode to DWC3 glue to which it is connected.
 
diff --git a/Documentation/usb/authorization.txt b/Documentation/usb/authorization.txt
index c069b6884c779ffc855133f634cf6b640a81da00..c7e985f05d8f9f1ecd433ffe41fec1e199e8b898 100644
--- a/Documentation/usb/authorization.txt
+++ b/Documentation/usb/authorization.txt
@@ -90,3 +90,34 @@ etc, but you get the idea. Anybody with access to a device gadget kit
 can fake descriptors and device info. Don't trust that. You are
 welcome.
 
+
+Interface authorization
+-----------------------
+There is a similar approach to allow or deny specific USB interfaces.
+That allows to block only a subset of an USB device.
+
+Authorize an interface:
+$ echo 1 > /sys/bus/usb/devices/INTERFACE/authorized
+
+Deauthorize an interface:
+$ echo 0 > /sys/bus/usb/devices/INTERFACE/authorized
+
+The default value for new interfaces
+on a particular USB bus can be changed, too.
+
+Allow interfaces per default:
+$ echo 1 > /sys/bus/usb/devices/usbX/interface_authorized_default
+
+Deny interfaces per default:
+$ echo 0 > /sys/bus/usb/devices/usbX/interface_authorized_default
+
+Per default the interface_authorized_default bit is 1.
+So all interfaces would authorized per default.
+
+Note:
+If a deauthorized interface will be authorized so the driver probing must
+be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe
+
+For drivers that need multiple interfaces all needed interfaces should be
+authroized first. After that the drivers should be probed.
+This avoids side effects.
diff --git a/MAINTAINERS b/MAINTAINERS
index ed6dccf2bfa075ba02225b5b848c1dbaa9d6b1e0..94a97bc8a073a170098e49939b9c92f9af241e88 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1300,6 +1300,13 @@ F:	arch/arm/mach-mediatek/
 N:	mtk
 K:	mediatek
 
+ARM/Mediatek USB3 PHY DRIVER
+M:	Chunfeng Yun <chunfeng.yun@mediatek.com>
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	drivers/phy/phy-mt65xx-usb3.c
+
 ARM/MICREL KS8695 ARCHITECTURE
 M:	Greg Ungerer <gerg@uclinux.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 65c426bc45f72eb530df0736493d4e4a373904cd..14bd9ae3f476a2f8c9dd8672e5e21ed9125b9ad4 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -809,7 +809,7 @@ static const struct gpio_led_platform_data gpio_leds_pdata = {
 	.num_leds = ARRAY_SIZE(gpio_leds),
 };
 
-static struct s3c_hsotg_plat crag6410_hsotg_pdata;
+static struct dwc2_hsotg_plat crag6410_hsotg_pdata;
 
 static void __init crag6410_machine_init(void)
 {
@@ -835,7 +835,7 @@ static void __init crag6410_machine_init(void)
 	s3c_i2c0_set_platdata(&i2c0_pdata);
 	s3c_i2c1_set_platdata(&i2c1_pdata);
 	s3c_fb_set_platdata(&crag6410_lcd_pdata);
-	s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
+	dwc2_hsotg_set_platdata(&crag6410_hsotg_pdata);
 
 	i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
 	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index b3d13537a7f0b2a0ce1fb3adfcd28efce08f7c3b..719843dca510d5900a8560bacee9706650f5b2e6 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -189,7 +189,7 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
 	},
 };
 
-static struct s3c_hsotg_plat smartq_hsotg_pdata;
+static struct dwc2_hsotg_plat smartq_hsotg_pdata;
 
 static int __init smartq_lcd_setup_gpio(void)
 {
@@ -382,7 +382,7 @@ void __init smartq_map_io(void)
 void __init smartq_machine_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
-	s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
+	dwc2_hsotg_set_platdata(&smartq_hsotg_pdata);
 	s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
 	s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
 	s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d590b88bd8a83a8863c0cbdf5548654ba4b99776..286c9bd676e1796154f65d08f85a899fb40f06c5 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -628,7 +628,7 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
 	.enable_gpio = -1,
 };
 
-static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+static struct dwc2_hsotg_plat smdk6410_hsotg_pdata;
 
 static void __init smdk6410_map_io(void)
 {
@@ -659,7 +659,7 @@ static void __init smdk6410_machine_init(void)
 	s3c_i2c0_set_platdata(NULL);
 	s3c_i2c1_set_platdata(NULL);
 	s3c_fb_set_platdata(&smdk6410_lcd_pdata);
-	s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
+	dwc2_hsotg_set_platdata(&smdk6410_hsotg_pdata);
 
 	samsung_keypad_set_platdata(&smdk6410_keypad_data);
 
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 83c7d154bde0971a3b9abeadeb6fb8bfaa93143a..82074625de5cebfc7681f72c931c90d1b7e951ac 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1042,11 +1042,11 @@ struct platform_device s3c_device_usb_hsotg = {
 	},
 };
 
-void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
+void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd)
 {
-	struct s3c_hsotg_plat *npd;
+	struct dwc2_hsotg_plat *npd;
 
-	npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
+	npd = s3c_set_platdata(pd, sizeof(struct dwc2_hsotg_plat),
 			&s3c_device_usb_hsotg);
 
 	if (!npd->phy_init)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 47da573d0babd8bb9805c8cdb9a9d40323567bf8..7eb5859dd035fefabea842f40722580cfcdfe64a 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -206,6 +206,15 @@ config PHY_HIX5HD2_SATA
 	help
 	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
 
+config PHY_MT65XX_USB3
+	tristate "Mediatek USB3.0 PHY Driver"
+	depends on ARCH_MEDIATEK && OF
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver
+	  for mt65xx SoCs. it supports two usb2.0 ports and
+	  one usb3.0 port.
+
 config PHY_SUN4I_USB
 	tristate "Allwinner sunxi SoC USB PHY driver"
 	depends on ARCH_SUNXI && HAS_IOMEM && OF
@@ -371,4 +380,13 @@ config PHY_BRCMSTB_SATA
 	  Enable this to support the SATA3 PHY on 28nm Broadcom STB SoCs.
 	  Likely useful only with CONFIG_SATA_BRCMSTB enabled.
 
+config PHY_CYGNUS_PCIE
+	tristate "Broadcom Cygnus PCIe PHY driver"
+	depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
+	select GENERIC_PHY
+	default ARCH_BCM_CYGNUS
+	help
+	  Enable this to support the Broadcom Cygnus PCIe PHY.
+	  If unsure, say N.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index a5b18c18fc12d78fce9c19021a0847f49ece504b..075db1a81aa5c30b5c786b3dd3ae4d63f4cd69ab 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
 obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
+obj-$(CONFIG_PHY_MT65XX_USB3)		+= phy-mt65xx-usb3.o
 obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
 obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
@@ -46,3 +47,4 @@ obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-14nm.o
 obj-$(CONFIG_PHY_TUSB1210)		+= phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCMSTB_SATA)		+= phy-brcmstb-sata.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
+obj-$(CONFIG_PHY_CYGNUS_PCIE)		+= phy-bcm-cygnus-pcie.o
diff --git a/drivers/phy/phy-bcm-cygnus-pcie.c b/drivers/phy/phy-bcm-cygnus-pcie.c
new file mode 100644
index 0000000000000000000000000000000000000000..7ad72b7d2b981b6ff4ae59011fdd5e6c5538ef51
--- /dev/null
+++ b/drivers/phy/phy-bcm-cygnus-pcie.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#define PCIE_CFG_OFFSET         0x00
+#define PCIE1_PHY_IDDQ_SHIFT    10
+#define PCIE0_PHY_IDDQ_SHIFT    2
+
+enum cygnus_pcie_phy_id {
+	CYGNUS_PHY_PCIE0 = 0,
+	CYGNUS_PHY_PCIE1,
+	MAX_NUM_PHYS,
+};
+
+struct cygnus_pcie_phy_core;
+
+/**
+ * struct cygnus_pcie_phy - Cygnus PCIe PHY device
+ * @core: pointer to the Cygnus PCIe PHY core control
+ * @id: internal ID to identify the Cygnus PCIe PHY
+ * @phy: pointer to the kernel PHY device
+ */
+struct cygnus_pcie_phy {
+	struct cygnus_pcie_phy_core *core;
+	enum cygnus_pcie_phy_id id;
+	struct phy *phy;
+};
+
+/**
+ * struct cygnus_pcie_phy_core - Cygnus PCIe PHY core control
+ * @dev: pointer to device
+ * @base: base register
+ * @lock: mutex to protect access to individual PHYs
+ * @phys: pointer to Cygnus PHY device
+ */
+struct cygnus_pcie_phy_core {
+	struct device *dev;
+	void __iomem *base;
+	struct mutex lock;
+	struct cygnus_pcie_phy phys[MAX_NUM_PHYS];
+};
+
+static int cygnus_pcie_power_config(struct cygnus_pcie_phy *phy, bool enable)
+{
+	struct cygnus_pcie_phy_core *core = phy->core;
+	unsigned shift;
+	u32 val;
+
+	mutex_lock(&core->lock);
+
+	switch (phy->id) {
+	case CYGNUS_PHY_PCIE0:
+		shift = PCIE0_PHY_IDDQ_SHIFT;
+		break;
+
+	case CYGNUS_PHY_PCIE1:
+		shift = PCIE1_PHY_IDDQ_SHIFT;
+		break;
+
+	default:
+		mutex_unlock(&core->lock);
+		dev_err(core->dev, "PCIe PHY %d invalid\n", phy->id);
+		return -EINVAL;
+	}
+
+	if (enable) {
+		val = readl(core->base + PCIE_CFG_OFFSET);
+		val &= ~BIT(shift);
+		writel(val, core->base + PCIE_CFG_OFFSET);
+		/*
+		 * Wait 50 ms for the PCIe Serdes to stabilize after the analog
+		 * front end is brought up
+		 */
+		msleep(50);
+	} else {
+		val = readl(core->base + PCIE_CFG_OFFSET);
+		val |= BIT(shift);
+		writel(val, core->base + PCIE_CFG_OFFSET);
+	}
+
+	mutex_unlock(&core->lock);
+	dev_dbg(core->dev, "PCIe PHY %d %s\n", phy->id,
+		enable ? "enabled" : "disabled");
+	return 0;
+}
+
+static int cygnus_pcie_phy_power_on(struct phy *p)
+{
+	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);
+
+	return cygnus_pcie_power_config(phy, true);
+}
+
+static int cygnus_pcie_phy_power_off(struct phy *p)
+{
+	struct cygnus_pcie_phy *phy = phy_get_drvdata(p);
+
+	return cygnus_pcie_power_config(phy, false);
+}
+
+static struct phy_ops cygnus_pcie_phy_ops = {
+	.power_on = cygnus_pcie_phy_power_on,
+	.power_off = cygnus_pcie_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int cygnus_pcie_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node, *child;
+	struct cygnus_pcie_phy_core *core;
+	struct phy_provider *provider;
+	struct resource *res;
+	unsigned cnt = 0;
+
+	if (of_get_child_count(node) == 0) {
+		dev_err(dev, "PHY no child node\n");
+		return -ENODEV;
+	}
+
+	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	core->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(core->base))
+		return PTR_ERR(core->base);
+
+	mutex_init(&core->lock);
+
+	for_each_available_child_of_node(node, child) {
+		unsigned int id;
+		struct cygnus_pcie_phy *p;
+
+		if (of_property_read_u32(child, "reg", &id)) {
+			dev_err(dev, "missing reg property for %s\n",
+				child->name);
+			return -EINVAL;
+		}
+
+		if (id >= MAX_NUM_PHYS) {
+			dev_err(dev, "invalid PHY id: %u\n", id);
+			return -EINVAL;
+		}
+
+		if (core->phys[id].phy) {
+			dev_err(dev, "duplicated PHY id: %u\n", id);
+			return -EINVAL;
+		}
+
+		p = &core->phys[id];
+		p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
+		if (IS_ERR(p->phy)) {
+			dev_err(dev, "failed to create PHY\n");
+			return PTR_ERR(p->phy);
+		}
+
+		p->core = core;
+		p->id = id;
+		phy_set_drvdata(p->phy, p);
+		cnt++;
+	}
+
+	dev_set_drvdata(dev, core);
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider)) {
+		dev_err(dev, "failed to register PHY provider\n");
+		return PTR_ERR(provider);
+	}
+
+	dev_dbg(dev, "registered %u PCIe PHY(s)\n", cnt);
+
+	return 0;
+}
+
+static const struct of_device_id cygnus_pcie_phy_match_table[] = {
+	{ .compatible = "brcm,cygnus-pcie-phy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, cygnus_pcie_phy_match_table);
+
+static struct platform_driver cygnus_pcie_phy_driver = {
+	.driver = {
+		.name = "cygnus-pcie-phy",
+		.of_match_table = cygnus_pcie_phy_match_table,
+	},
+	.probe = cygnus_pcie_phy_probe,
+};
+module_platform_driver(cygnus_pcie_phy_driver);
+
+MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom Cygnus PCIe PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
new file mode 100644
index 0000000000000000000000000000000000000000..f30b28bd41fe7b11a8cce95e889ae894fef20518
--- /dev/null
+++ b/drivers/phy/phy-mt65xx-usb3.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.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 <dt-bindings/phy/phy.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/*
+ * for sifslv2 register, but exclude port's;
+ * relative to USB3_SIF2_BASE base address
+ */
+#define SSUSB_SIFSLV_SPLLC		0x0000
+
+/* offsets of sub-segment in each port registers */
+#define SSUSB_SIFSLV_U2PHY_COM_BASE	0x0000
+#define SSUSB_SIFSLV_U3PHYD_BASE	0x0100
+#define SSUSB_USB30_PHYA_SIV_B_BASE	0x0300
+#define SSUSB_SIFSLV_U3PHYA_DA_BASE	0x0400
+
+#define U3P_USBPHYACR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0000)
+#define PA0_RG_U2PLL_FORCE_ON		BIT(15)
+
+#define U3P_USBPHYACR2		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0008)
+#define PA2_RG_SIF_U2PLL_FORCE_EN	BIT(18)
+
+#define U3P_USBPHYACR5		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0014)
+#define PA5_RG_U2_HSTX_SRCTRL		GENMASK(14, 12)
+#define PA5_RG_U2_HSTX_SRCTRL_VAL(x)	((0x7 & (x)) << 12)
+#define PA5_RG_U2_HS_100U_U3_EN	BIT(11)
+
+#define U3P_USBPHYACR6		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0018)
+#define PA6_RG_U2_ISO_EN		BIT(31)
+#define PA6_RG_U2_BC11_SW_EN		BIT(23)
+#define PA6_RG_U2_OTG_VBUSCMP_EN	BIT(20)
+
+#define U3P_U2PHYACR4		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0020)
+#define P2C_RG_USB20_GPIO_CTL		BIT(9)
+#define P2C_USB20_GPIO_MODE		BIT(8)
+#define P2C_U2_GPIO_CTR_MSK	(P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
+
+#define U3D_U2PHYDCR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0060)
+#define P2C_RG_SIF_U2PLL_FORCE_ON	BIT(24)
+
+#define U3P_U2PHYDTM0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0068)
+#define P2C_FORCE_UART_EN		BIT(26)
+#define P2C_FORCE_DATAIN		BIT(23)
+#define P2C_FORCE_DM_PULLDOWN		BIT(21)
+#define P2C_FORCE_DP_PULLDOWN		BIT(20)
+#define P2C_FORCE_XCVRSEL		BIT(19)
+#define P2C_FORCE_SUSPENDM		BIT(18)
+#define P2C_FORCE_TERMSEL		BIT(17)
+#define P2C_RG_DATAIN			GENMASK(13, 10)
+#define P2C_RG_DATAIN_VAL(x)		((0xf & (x)) << 10)
+#define P2C_RG_DMPULLDOWN		BIT(7)
+#define P2C_RG_DPPULLDOWN		BIT(6)
+#define P2C_RG_XCVRSEL			GENMASK(5, 4)
+#define P2C_RG_XCVRSEL_VAL(x)		((0x3 & (x)) << 4)
+#define P2C_RG_SUSPENDM			BIT(3)
+#define P2C_RG_TERMSEL			BIT(2)
+#define P2C_DTM0_PART_MASK \
+		(P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
+		P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
+		P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
+		P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
+
+#define U3P_U2PHYDTM1		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x006C)
+#define P2C_RG_UART_EN			BIT(16)
+#define P2C_RG_VBUSVALID		BIT(5)
+#define P2C_RG_SESSEND			BIT(4)
+#define P2C_RG_AVALID			BIT(2)
+
+#define U3P_U3_PHYA_REG0	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0000)
+#define P3A_RG_U3_VUSB10_ON		BIT(5)
+
+#define U3P_U3_PHYA_REG6	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0018)
+#define P3A_RG_TX_EIDLE_CM		GENMASK(31, 28)
+#define P3A_RG_TX_EIDLE_CM_VAL(x)	((0xf & (x)) << 28)
+
+#define U3P_U3_PHYA_REG9	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0024)
+#define P3A_RG_RX_DAC_MUX		GENMASK(5, 1)
+#define P3A_RG_RX_DAC_MUX_VAL(x)	((0x1f & (x)) << 1)
+
+#define U3P_U3PHYA_DA_REG0	(SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0000)
+#define P3A_RG_XTAL_EXT_EN_U3		GENMASK(11, 10)
+#define P3A_RG_XTAL_EXT_EN_U3_VAL(x)	((0x3 & (x)) << 10)
+
+#define U3P_PHYD_CDR1		(SSUSB_SIFSLV_U3PHYD_BASE + 0x005c)
+#define P3D_RG_CDR_BIR_LTD1		GENMASK(28, 24)
+#define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
+#define P3D_RG_CDR_BIR_LTD0		GENMASK(12, 8)
+#define P3D_RG_CDR_BIR_LTD0_VAL(x)	((0x1f & (x)) << 8)
+
+#define U3P_XTALCTL3		(SSUSB_SIFSLV_SPLLC + 0x0018)
+#define XC3_RG_U3_XTAL_RX_PWD		BIT(9)
+#define XC3_RG_U3_FRC_XTAL_RX_PWD	BIT(8)
+
+struct mt65xx_phy_instance {
+	struct phy *phy;
+	void __iomem *port_base;
+	u32 index;
+	u8 type;
+};
+
+struct mt65xx_u3phy {
+	struct device *dev;
+	void __iomem *sif_base;	/* include sif2, but exclude port's */
+	struct clk *u3phya_ref;	/* reference clock of usb3 anolog phy */
+	struct mt65xx_phy_instance **phys;
+	int nphys;
+};
+
+static void phy_instance_init(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	/* switch to USB function. (system register, force ip into usb mode) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_FORCE_UART_EN;
+	tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~P2C_RG_UART_EN;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U2PHYACR4);
+		tmp &= ~P2C_U2_GPIO_CTR_MSK;
+		writel(tmp, port_base + U3P_U2PHYACR4);
+
+		tmp = readl(port_base + U3P_USBPHYACR2);
+		tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
+		writel(tmp, port_base + U3P_USBPHYACR2);
+
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+	} else {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+
+		tmp = readl(port_base + U3P_U2PHYDTM0);
+		tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
+		writel(tmp, port_base + U3P_U2PHYDTM0);
+	}
+
+	/* DP/DM BC1.1 path Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_BC11_SW_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	tmp = readl(port_base + U3P_U3PHYA_DA_REG0);
+	tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
+	tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
+	writel(tmp, port_base + U3P_U3PHYA_DA_REG0);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG9);
+	tmp &= ~P3A_RG_RX_DAC_MUX;
+	tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
+	writel(tmp, port_base + U3P_U3_PHYA_REG9);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG6);
+	tmp &= ~P3A_RG_TX_EIDLE_CM;
+	tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
+	writel(tmp, port_base + U3P_U3_PHYA_REG6);
+
+	tmp = readl(port_base + U3P_PHYD_CDR1);
+	tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
+	tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
+	writel(tmp, port_base + U3P_PHYD_CDR1);
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	if (!index) {
+		/* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp |= P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	}
+
+	/* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
+	tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Enable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	if (!index) {
+		tmp = readl(u3phy->sif_base + U3P_XTALCTL3);
+		tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
+		writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
+
+		/* [mt8173]disable Change 100uA current from SSUSB */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
+	tmp &= ~P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	/* USB 2.0 slew rate calibration */
+	tmp = readl(port_base + U3P_USBPHYACR5);
+	tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
+	tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
+	writel(tmp, port_base + U3P_USBPHYACR5);
+
+	if (index) {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+
+		tmp = readl(port_base + U3P_U2PHYDTM0);
+		tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
+		writel(tmp, port_base + U3P_U2PHYDTM0);
+	}
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
+	tmp |= P2C_FORCE_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	if (!index) {
+		/* (also disable)Change 100uA current switch to USB2.0 */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+
+	/* let suspendm=0, set utmi into analog power down */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_RG_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+	udelay(1);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
+	tmp |= P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp &= ~P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	} else {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+	}
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	if (index) {
+		tmp = readl(port_base + U3D_U2PHYDCR0);
+		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
+		writel(tmp, port_base + U3D_U2PHYDCR0);
+
+		tmp = readl(port_base + U3P_U2PHYDTM0);
+		tmp &= ~P2C_FORCE_SUSPENDM;
+		writel(tmp, port_base + U3P_U2PHYDTM0);
+	}
+}
+
+static int mt65xx_phy_init(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+	int ret;
+
+	ret = clk_prepare_enable(u3phy->u3phya_ref);
+	if (ret) {
+		dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
+		return ret;
+	}
+
+	phy_instance_init(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_on(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_on(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_off(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_off(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_exit(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_exit(u3phy, instance);
+	clk_disable_unprepare(u3phy->u3phya_ref);
+	return 0;
+}
+
+static struct phy *mt65xx_phy_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
+	struct mt65xx_phy_instance *instance = NULL;
+	struct device_node *phy_np = args->np;
+	int index;
+
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	for (index = 0; index < u3phy->nphys; index++)
+		if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
+			instance = u3phy->phys[index];
+			break;
+		}
+
+	if (!instance) {
+		dev_err(dev, "failed to find appropriate phy\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	instance->type = args->args[0];
+
+	if (!(instance->type == PHY_TYPE_USB2 ||
+	      instance->type == PHY_TYPE_USB3)) {
+		dev_err(dev, "unsupported device type: %d\n", instance->type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return instance->phy;
+}
+
+static struct phy_ops mt65xx_u3phy_ops = {
+	.init		= mt65xx_phy_init,
+	.exit		= mt65xx_phy_exit,
+	.power_on	= mt65xx_phy_power_on,
+	.power_off	= mt65xx_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int mt65xx_u3phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child_np;
+	struct phy_provider *provider;
+	struct resource *sif_res;
+	struct mt65xx_u3phy *u3phy;
+	struct resource res;
+	int port;
+
+	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
+	if (!u3phy)
+		return -ENOMEM;
+
+	u3phy->nphys = of_get_child_count(np);
+	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
+				       sizeof(*u3phy->phys), GFP_KERNEL);
+	if (!u3phy->phys)
+		return -ENOMEM;
+
+	u3phy->dev = dev;
+	platform_set_drvdata(pdev, u3phy);
+
+	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
+	if (IS_ERR(u3phy->sif_base)) {
+		dev_err(dev, "failed to remap sif regs\n");
+		return PTR_ERR(u3phy->sif_base);
+	}
+
+	u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
+	if (IS_ERR(u3phy->u3phya_ref)) {
+		dev_err(dev, "error to get u3phya_ref\n");
+		return PTR_ERR(u3phy->u3phya_ref);
+	}
+
+	port = 0;
+	for_each_child_of_node(np, child_np) {
+		struct mt65xx_phy_instance *instance;
+		struct phy *phy;
+		int retval;
+
+		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+		if (!instance)
+			return -ENOMEM;
+
+		u3phy->phys[port] = instance;
+
+		phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create phy\n");
+			return PTR_ERR(phy);
+		}
+
+		retval = of_address_to_resource(child_np, 0, &res);
+		if (retval) {
+			dev_err(dev, "failed to get address resource(id-%d)\n",
+				port);
+			return retval;
+		}
+
+		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		if (IS_ERR(instance->port_base)) {
+			dev_err(dev, "failed to remap phy regs\n");
+			return PTR_ERR(instance->port_base);
+		}
+
+		instance->phy = phy;
+		instance->index = port;
+		phy_set_drvdata(phy, instance);
+		port++;
+	}
+
+	provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
+
+	return PTR_ERR_OR_ZERO(provider);
+}
+
+static const struct of_device_id mt65xx_u3phy_id_table[] = {
+	{ .compatible = "mediatek,mt8173-u3phy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
+
+static struct platform_driver mt65xx_u3phy_driver = {
+	.probe		= mt65xx_u3phy_probe,
+	.driver		= {
+		.name	= "mt65xx-u3phy",
+		.of_match_table = mt65xx_u3phy_id_table,
+	},
+};
+
+module_platform_driver(mt65xx_u3phy_driver);
+
+MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
+MODULE_DESCRIPTION("mt65xx USB PHY driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c
index f278a9c547e199c6228081f3445133dcdd9cda46..1d22d93b552d759df577a26228f0e7c7464c83c9 100644
--- a/drivers/phy/phy-samsung-usb2.c
+++ b/drivers/phy/phy-samsung-usb2.c
@@ -27,6 +27,13 @@ static int samsung_usb2_phy_power_on(struct phy *phy)
 
 	dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n",
 		inst->cfg->label);
+
+	if (drv->vbus) {
+		ret = regulator_enable(drv->vbus);
+		if (ret)
+			goto err_regulator;
+	}
+
 	ret = clk_prepare_enable(drv->clk);
 	if (ret)
 		goto err_main_clk;
@@ -48,6 +55,9 @@ static int samsung_usb2_phy_power_on(struct phy *phy)
 err_instance_clk:
 	clk_disable_unprepare(drv->clk);
 err_main_clk:
+	if (drv->vbus)
+		regulator_disable(drv->vbus);
+err_regulator:
 	return ret;
 }
 
@@ -55,7 +65,7 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
 {
 	struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy);
 	struct samsung_usb2_phy_driver *drv = inst->drv;
-	int ret;
+	int ret = 0;
 
 	dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n",
 		inst->cfg->label);
@@ -68,7 +78,10 @@ static int samsung_usb2_phy_power_off(struct phy *phy)
 	}
 	clk_disable_unprepare(drv->ref_clk);
 	clk_disable_unprepare(drv->clk);
-	return 0;
+	if (drv->vbus)
+		ret = regulator_disable(drv->vbus);
+
+	return ret;
 }
 
 static const struct phy_ops samsung_usb2_phy_ops = {
@@ -203,6 +216,14 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	drv->vbus = devm_regulator_get(dev, "vbus");
+	if (IS_ERR(drv->vbus)) {
+		ret = PTR_ERR(drv->vbus);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		drv->vbus = NULL;
+	}
+
 	for (i = 0; i < drv->cfg->num_phys; i++) {
 		char *label = drv->cfg->phys[i].label;
 		struct samsung_usb2_phy_instance *p = &drv->instances[i];
diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h
index 44bead9b8f34bb426440431217fa989a0f839734..6563e7ca0ac444824f4185277a33c1a5fee6a1bd 100644
--- a/drivers/phy/phy-samsung-usb2.h
+++ b/drivers/phy/phy-samsung-usb2.h
@@ -17,6 +17,7 @@
 #include <linux/device.h>
 #include <linux/regmap.h>
 #include <linux/spinlock.h>
+#include <linux/regulator/consumer.h>
 
 #define KHZ 1000
 #define MHZ (KHZ * KHZ)
@@ -37,6 +38,7 @@ struct samsung_usb2_phy_driver {
 	const struct samsung_usb2_phy_config *cfg;
 	struct clk *clk;
 	struct clk *ref_clk;
+	struct regulator *vbus;
 	unsigned long ref_rate;
 	u32 ref_reg_val;
 	struct device *dev;
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 731b395d6e6a1621ee7fc36055b6c1a5f7367780..b12964b70625f6753997a1f529fb4c5f4c96b4d3 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -551,19 +551,15 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(data->base))
 		return PTR_ERR(data->base);
 
-	data->id_det_gpio = devm_gpiod_get(dev, "usb0_id_det", GPIOD_IN);
-	if (IS_ERR(data->id_det_gpio)) {
-		if (PTR_ERR(data->id_det_gpio) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-		data->id_det_gpio = NULL;
-	}
-
-	data->vbus_det_gpio = devm_gpiod_get(dev, "usb0_vbus_det", GPIOD_IN);
-	if (IS_ERR(data->vbus_det_gpio)) {
-		if (PTR_ERR(data->vbus_det_gpio) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-		data->vbus_det_gpio = NULL;
-	}
+	data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
+						    GPIOD_IN);
+	if (IS_ERR(data->id_det_gpio))
+		return PTR_ERR(data->id_det_gpio);
+
+	data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
+						      GPIOD_IN);
+	if (IS_ERR(data->vbus_det_gpio))
+		return PTR_ERR(data->vbus_det_gpio);
 
 	if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
 		data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index d8926c6cd2a8ea4a374aef845522f40fdcba1cb7..d5c57f1e98fddfffb39c948159558ca4ea09b0f3 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_USB_R8A66597_HCD)	+= host/
 obj-$(CONFIG_USB_HWA_HCD)	+= host/
 obj-$(CONFIG_USB_IMX21_HCD)	+= host/
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= host/
-obj-$(CONFIG_USB_FUSBH200_HCD)	+= host/
 obj-$(CONFIG_USB_FOTG210_HCD)	+= host/
 obj-$(CONFIG_USB_MAX3421_HCD)	+= host/
 
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig
index 5ce3f1d6a6ed340d8cf4db1a01c7fca3e6a6139a..5619b8ca3bf3f4d4e0b0651385a88c286a012967 100644
--- a/drivers/usb/chipidea/Kconfig
+++ b/drivers/usb/chipidea/Kconfig
@@ -1,6 +1,7 @@
 config USB_CHIPIDEA
 	tristate "ChipIdea Highspeed Dual Role Controller"
 	depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA
+	select EXTCON
 	help
 	  Say Y here if your system has a dual role high speed USB
 	  controller based on ChipIdea silicon IP. Currently, only the
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index dcc50c878159e5aa7e3bb5e7c79051e483e655ac..6ccbf60cdd5c1204f77072a396d9791c6bfdcc2a 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -56,12 +56,23 @@ static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
 		CI_HDRC_DISABLE_HOST_STREAMING,
 };
 
+static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
+	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
+		CI_HDRC_TURN_VBUS_EARLY_ON,
+};
+
+static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
+	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
+};
+
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
 	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
 	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
 	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
 	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
+	{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
+	{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c
index 773d150512fa4da6af83e5df10b069cc0276914c..b59195edf63634a3be94bcd3dc9ede6d87699185 100644
--- a/drivers/usb/chipidea/ci_hdrc_pci.c
+++ b/drivers/usb/chipidea/ci_hdrc_pci.c
@@ -142,16 +142,16 @@ static const struct pci_device_id ci_hdrc_pci_id_table[] = {
 		.driver_data = (kernel_ulong_t)&pci_platdata,
 	},
 	{
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811),
+		PCI_VDEVICE(INTEL, 0x0811),
 		.driver_data = (kernel_ulong_t)&langwell_pci_platdata,
 	},
 	{
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829),
+		PCI_VDEVICE(INTEL, 0x0829),
 		.driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 	},
 	{
 		/* Intel Clovertrail */
-		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006),
+		PCI_VDEVICE(INTEL, 0xe006),
 		.driver_data = (kernel_ulong_t)&penwell_pci_platdata,
 	},
 	{ 0 } /* end: all zeroes */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 3feebf7f31f09259249c76fa121f747a2380ff9e..965d0e240dcb27674151e2073b984c89c90eb7ed 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -47,6 +47,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/extcon.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
@@ -602,16 +603,52 @@ static irqreturn_t ci_irq(int irq, void *data)
 	return ret;
 }
 
+static int ci_vbus_notifier(struct notifier_block *nb, unsigned long event,
+			    void *ptr)
+{
+	struct ci_hdrc_cable *vbus = container_of(nb, struct ci_hdrc_cable, nb);
+	struct ci_hdrc *ci = vbus->ci;
+
+	if (event)
+		vbus->state = true;
+	else
+		vbus->state = false;
+
+	vbus->changed = true;
+
+	ci_irq(ci->irq, ci);
+	return NOTIFY_DONE;
+}
+
+static int ci_id_notifier(struct notifier_block *nb, unsigned long event,
+			  void *ptr)
+{
+	struct ci_hdrc_cable *id = container_of(nb, struct ci_hdrc_cable, nb);
+	struct ci_hdrc *ci = id->ci;
+
+	if (event)
+		id->state = false;
+	else
+		id->state = true;
+
+	id->changed = true;
+
+	ci_irq(ci->irq, ci);
+	return NOTIFY_DONE;
+}
+
 static int ci_get_platdata(struct device *dev,
 		struct ci_hdrc_platform_data *platdata)
 {
+	struct extcon_dev *ext_vbus, *ext_id;
+	struct ci_hdrc_cable *cable;
 	int ret;
 
 	if (!platdata->phy_mode)
 		platdata->phy_mode = of_usb_get_phy_mode(dev->of_node);
 
 	if (!platdata->dr_mode)
-		platdata->dr_mode = of_usb_get_dr_mode(dev->of_node);
+		platdata->dr_mode = usb_get_dr_mode(dev);
 
 	if (platdata->dr_mode == USB_DR_MODE_UNKNOWN)
 		platdata->dr_mode = USB_DR_MODE_OTG;
@@ -648,9 +685,13 @@ static int ci_get_platdata(struct device *dev,
 			return ret;
 	}
 
-	if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL)
+	if (usb_get_maximum_speed(dev) == USB_SPEED_FULL)
 		platdata->flags |= CI_HDRC_FORCE_FULLSPEED;
 
+	if (of_find_property(dev->of_node, "phy-clkgate-delay-us", NULL))
+		of_property_read_u32(dev->of_node, "phy-clkgate-delay-us",
+				     &platdata->phy_clkgate_delay_us);
+
 	platdata->itc_setting = 1;
 	if (of_find_property(dev->of_node, "itc-setting", NULL)) {
 		ret = of_property_read_u32(dev->of_node, "itc-setting",
@@ -695,9 +736,91 @@ static int ci_get_platdata(struct device *dev,
 		platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
 	}
 
+	ext_id = ERR_PTR(-ENODEV);
+	ext_vbus = ERR_PTR(-ENODEV);
+	if (of_property_read_bool(dev->of_node, "extcon")) {
+		/* Each one of them is not mandatory */
+		ext_vbus = extcon_get_edev_by_phandle(dev, 0);
+		if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV)
+			return PTR_ERR(ext_vbus);
+
+		ext_id = extcon_get_edev_by_phandle(dev, 1);
+		if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV)
+			return PTR_ERR(ext_id);
+	}
+
+	cable = &platdata->vbus_extcon;
+	cable->nb.notifier_call = ci_vbus_notifier;
+	cable->edev = ext_vbus;
+
+	if (!IS_ERR(ext_vbus)) {
+		ret = extcon_get_cable_state_(cable->edev, EXTCON_USB);
+		if (ret)
+			cable->state = true;
+		else
+			cable->state = false;
+	}
+
+	cable = &platdata->id_extcon;
+	cable->nb.notifier_call = ci_id_notifier;
+	cable->edev = ext_id;
+
+	if (!IS_ERR(ext_id)) {
+		ret = extcon_get_cable_state_(cable->edev, EXTCON_USB_HOST);
+		if (ret)
+			cable->state = false;
+		else
+			cable->state = true;
+	}
+	return 0;
+}
+
+static int ci_extcon_register(struct ci_hdrc *ci)
+{
+	struct ci_hdrc_cable *id, *vbus;
+	int ret;
+
+	id = &ci->platdata->id_extcon;
+	id->ci = ci;
+	if (!IS_ERR(id->edev)) {
+		ret = extcon_register_notifier(id->edev, EXTCON_USB_HOST,
+					       &id->nb);
+		if (ret < 0) {
+			dev_err(ci->dev, "register ID failed\n");
+			return ret;
+		}
+	}
+
+	vbus = &ci->platdata->vbus_extcon;
+	vbus->ci = ci;
+	if (!IS_ERR(vbus->edev)) {
+		ret = extcon_register_notifier(vbus->edev, EXTCON_USB,
+					       &vbus->nb);
+		if (ret < 0) {
+			extcon_unregister_notifier(id->edev, EXTCON_USB_HOST,
+						   &id->nb);
+			dev_err(ci->dev, "register VBUS failed\n");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
+static void ci_extcon_unregister(struct ci_hdrc *ci)
+{
+	struct ci_hdrc_cable *cable;
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev))
+		extcon_unregister_notifier(cable->edev, EXTCON_USB_HOST,
+					   &cable->nb);
+
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev))
+		extcon_unregister_notifier(cable->edev, EXTCON_USB, &cable->nb);
+}
+
 static DEFINE_IDA(ci_ida);
 
 struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -921,6 +1044,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	if (ret)
 		goto stop;
 
+	ret = ci_extcon_register(ci);
+	if (ret)
+		goto stop;
+
 	if (ci->supports_runtime_pm) {
 		pm_runtime_set_active(&pdev->dev);
 		pm_runtime_enable(&pdev->dev);
@@ -938,6 +1065,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
 	if (!ret)
 		return 0;
 
+	ci_extcon_unregister(ci);
 stop:
 	ci_role_destroy(ci);
 deinit_phy:
@@ -957,6 +1085,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 	}
 
 	dbg_remove_files(ci);
+	ci_extcon_unregister(ci);
 	ci_role_destroy(ci);
 	ci_hdrc_enter_lpm(ci, true);
 	ci_usb_phy_exit(ci);
@@ -996,6 +1125,9 @@ static void ci_controller_suspend(struct ci_hdrc *ci)
 {
 	disable_irq(ci->irq);
 	ci_hdrc_enter_lpm(ci, true);
+	if (ci->platdata->phy_clkgate_delay_us)
+		usleep_range(ci->platdata->phy_clkgate_delay_us,
+			     ci->platdata->phy_clkgate_delay_us + 50);
 	usb_phy_set_suspend(ci->usb_phy, 1);
 	ci->in_lpm = true;
 	enable_irq(ci->irq);
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index ad6c87a4653c2e4331eeb3b48787f525687e0c8a..45f86da1d6d37b4650ddfaf216879195ca9c6542 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -30,7 +30,44 @@
  */
 u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
 {
-	return hw_read(ci, OP_OTGSC, mask);
+	struct ci_hdrc_cable *cable;
+	u32 val = hw_read(ci, OP_OTGSC, mask);
+
+	/*
+	 * If using extcon framework for VBUS and/or ID signal
+	 * detection overwrite OTGSC register value
+	 */
+	cable = &ci->platdata->vbus_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (cable->changed)
+			val |= OTGSC_BSVIS;
+		else
+			val &= ~OTGSC_BSVIS;
+
+		cable->changed = false;
+
+		if (cable->state)
+			val |= OTGSC_BSV;
+		else
+			val &= ~OTGSC_BSV;
+	}
+
+	cable = &ci->platdata->id_extcon;
+	if (!IS_ERR(cable->edev)) {
+		if (cable->changed)
+			val |= OTGSC_IDIS;
+		else
+			val &= ~OTGSC_IDIS;
+
+		cable->changed = false;
+
+		if (cable->state)
+			val |= OTGSC_ID;
+		else
+			val &= ~OTGSC_ID;
+	}
+
+	return val;
 }
 
 /**
@@ -77,9 +114,12 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
 			ci_role(ci)->name, ci->roles[role]->name);
 
 		ci_role_stop(ci);
-		/* wait vbus lower than OTGSC_BSV */
-		hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
-				CI_VBUS_STABLE_TIMEOUT_MS);
+
+		if (role == CI_ROLE_GADGET)
+			/* wait vbus lower than OTGSC_BSV */
+			hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0,
+					CI_VBUS_STABLE_TIMEOUT_MS);
+
 		ci_role_start(ci, role);
 	}
 }
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 5ddab30ee240937d15d54cda0ad6642ea02247b5..fcea4eb36eeedbceac777ecd8d676e5ede74cba6 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -72,6 +72,14 @@
 
 #define VF610_OVER_CUR_DIS		BIT(7)
 
+#define MX7D_USBNC_USB_CTRL2		0x4
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK	0x3
+#define MX7D_USB_VBUS_WAKEUP_SOURCE(v)		(v << 0)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS	MX7D_USB_VBUS_WAKEUP_SOURCE(0)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(1)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID	MX7D_USB_VBUS_WAKEUP_SOURCE(2)
+#define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END	MX7D_USB_VBUS_WAKEUP_SOURCE(3)
+
 struct usbmisc_ops {
 	/* It's called once when probe a usb device */
 	int (*init)(struct imx_usbmisc_data *data);
@@ -324,6 +332,55 @@ static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
 	return 0;
 }
 
+static int usbmisc_imx7d_set_wakeup
+	(struct imx_usbmisc_data *data, bool enabled)
+{
+	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+	unsigned long flags;
+	u32 val;
+	u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE |
+		MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP);
+
+	spin_lock_irqsave(&usbmisc->lock, flags);
+	val = readl(usbmisc->base);
+	if (enabled) {
+		writel(val | wakeup_setting, usbmisc->base);
+	} else {
+		if (val & MX6_BM_WAKEUP_INTR)
+			dev_dbg(data->dev, "wakeup int\n");
+		writel(val & ~wakeup_setting, usbmisc->base);
+	}
+	spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+	return 0;
+}
+
+static int usbmisc_imx7d_init(struct imx_usbmisc_data *data)
+{
+	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
+	unsigned long flags;
+	u32 reg;
+
+	if (data->index >= 1)
+		return -EINVAL;
+
+	spin_lock_irqsave(&usbmisc->lock, flags);
+	if (data->disable_oc) {
+		reg = readl(usbmisc->base);
+		writel(reg | MX6_BM_OVER_CUR_DIS, usbmisc->base);
+	}
+
+	reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2);
+	reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK;
+	writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID,
+		 usbmisc->base + MX7D_USBNC_USB_CTRL2);
+	spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+	usbmisc_imx7d_set_wakeup(data, false);
+
+	return 0;
+}
+
 static const struct usbmisc_ops imx25_usbmisc_ops = {
 	.init = usbmisc_imx25_init,
 	.post = usbmisc_imx25_post,
@@ -351,6 +408,11 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = {
 	.init = usbmisc_imx6sx_init,
 };
 
+static const struct usbmisc_ops imx7d_usbmisc_ops = {
+	.init = usbmisc_imx7d_init,
+	.set_wakeup = usbmisc_imx7d_set_wakeup,
+};
+
 int imx_usbmisc_init(struct imx_usbmisc_data *data)
 {
 	struct imx_usbmisc *usbmisc;
@@ -426,6 +488,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
 		.compatible = "fsl,imx6sx-usbmisc",
 		.data = &imx6sx_usbmisc_ops,
 	},
+	{
+		.compatible = "fsl,imx6ul-usbmisc",
+		.data = &imx6sx_usbmisc_ops,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index 9e39286a4e5a1df458339cfbfd3076a3d08125ad..673d53038ed221c3b2e0c7c0d78d9309d307420a 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -60,6 +60,24 @@ const char *usb_speed_string(enum usb_device_speed speed)
 }
 EXPORT_SYMBOL_GPL(usb_speed_string);
 
+enum usb_device_speed usb_get_maximum_speed(struct device *dev)
+{
+	const char *maximum_speed;
+	int err;
+	int i;
+
+	err = device_property_read_string(dev, "maximum-speed", &maximum_speed);
+	if (err < 0)
+		return USB_SPEED_UNKNOWN;
+
+	for (i = 0; i < ARRAY_SIZE(speed_names); i++)
+		if (strcmp(maximum_speed, speed_names[i]) == 0)
+			return i;
+
+	return USB_SPEED_UNKNOWN;
+}
+EXPORT_SYMBOL_GPL(usb_get_maximum_speed);
+
 const char *usb_state_string(enum usb_device_state state)
 {
 	static const char *const names[] = {
@@ -81,7 +99,6 @@ const char *usb_state_string(enum usb_device_state state)
 }
 EXPORT_SYMBOL_GPL(usb_state_string);
 
-#ifdef CONFIG_OF
 static const char *const usb_dr_modes[] = {
 	[USB_DR_MODE_UNKNOWN]		= "",
 	[USB_DR_MODE_HOST]		= "host",
@@ -89,19 +106,12 @@ static const char *const usb_dr_modes[] = {
 	[USB_DR_MODE_OTG]		= "otg",
 };
 
-/**
- * of_usb_get_dr_mode - Get dual role mode for given device_node
- * @np:	Pointer to the given device_node
- *
- * The function gets phy interface string from property 'dr_mode',
- * and returns the correspondig enum usb_dr_mode
- */
-enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
+enum usb_dr_mode usb_get_dr_mode(struct device *dev)
 {
 	const char *dr_mode;
 	int err, i;
 
-	err = of_property_read_string(np, "dr_mode", &dr_mode);
+	err = device_property_read_string(dev, "dr_mode", &dr_mode);
 	if (err < 0)
 		return USB_DR_MODE_UNKNOWN;
 
@@ -111,34 +121,9 @@ enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
 
 	return USB_DR_MODE_UNKNOWN;
 }
-EXPORT_SYMBOL_GPL(of_usb_get_dr_mode);
-
-/**
- * of_usb_get_maximum_speed - Get maximum requested speed for a given USB
- * controller.
- * @np: Pointer to the given device_node
- *
- * The function gets the maximum speed string from property "maximum-speed",
- * and returns the corresponding enum usb_device_speed.
- */
-enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np)
-{
-	const char *maximum_speed;
-	int err;
-	int i;
-
-	err = of_property_read_string(np, "maximum-speed", &maximum_speed);
-	if (err < 0)
-		return USB_SPEED_UNKNOWN;
-
-	for (i = 0; i < ARRAY_SIZE(speed_names); i++)
-		if (strcmp(maximum_speed, speed_names[i]) == 0)
-			return i;
-
-	return USB_SPEED_UNKNOWN;
-}
-EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed);
+EXPORT_SYMBOL_GPL(usb_get_dr_mode);
 
+#ifdef CONFIG_OF
 /**
  * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
  * for given targeted hosts (non-PC hosts)
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index b9ddf0c1ffe5993893d5bd0d4f3ffe3f313ed435..7caff020106e23f26f9c3bb9c34585885064848d 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -853,6 +853,10 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 			dev->bos->ss_cap =
 				(struct usb_ss_cap_descriptor *)buffer;
 			break;
+		case USB_SSP_CAP_TYPE:
+			dev->bos->ssp_cap =
+				(struct usb_ssp_cap_descriptor *)buffer;
+			break;
 		case CONTAINER_ID_TYPE:
 			dev->bos->ss_id =
 				(struct usb_ss_container_id_descriptor *)buffer;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 6b5063e7943fac720a266478d79b04a352d51e41..56593a9a87268cc0f6d8181cb5f8021c252b457b 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -296,6 +296,10 @@ static int usb_probe_interface(struct device *dev)
 	if (udev->authorized == 0) {
 		dev_err(&intf->dev, "Device is not authorized for usage\n");
 		return error;
+	} else if (intf->authorized == 0) {
+		dev_err(&intf->dev, "Interface %d is not authorized for usage\n",
+				intf->altsetting->desc.bInterfaceNumber);
+		return error;
 	}
 
 	id = usb_match_dynamic_id(intf, driver);
@@ -417,12 +421,10 @@ static int usb_unbind_interface(struct device *dev)
 		if (ep->streams == 0)
 			continue;
 		if (j == 0) {
-			eps = kmalloc(USB_MAXENDPOINTS * sizeof(void *),
+			eps = kmalloc_array(USB_MAXENDPOINTS, sizeof(void *),
 				      GFP_KERNEL);
-			if (!eps) {
-				dev_warn(dev, "oom, leaking streams\n");
+			if (!eps)
 				break;
-			}
 		}
 		eps[j++] = ep;
 	}
@@ -508,6 +510,10 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 	if (dev->driver)
 		return -EBUSY;
 
+	/* reject claim if interface is not authorized */
+	if (!iface->authorized)
+		return -ENODEV;
+
 	udev = interface_to_usbdev(iface);
 
 	dev->driver = &driver->drvwrap.driver;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 4d64e5c499e194d3c364543fca9f9e76442684b2..1c102d60cd9f4afe861a6933e9495662d74de4f5 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -131,7 +131,7 @@ static inline int is_root_hub(struct usb_device *udev)
 /* usb 3.0 root hub device descriptor */
 static const u8 usb3_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x00, 0x03, /*  __le16 bcdUSB; v3.0 */
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -152,7 +152,7 @@ static const u8 usb3_rh_dev_descriptor[18] = {
 /* usb 2.5 (wireless USB 1.0) root hub device descriptor */
 static const u8 usb25_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x50, 0x02, /*  __le16 bcdUSB; v2.5 */
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -173,7 +173,7 @@ static const u8 usb25_rh_dev_descriptor[18] = {
 /* usb 2.0 root hub device descriptor */
 static const u8 usb2_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x00, 0x02, /*  __le16 bcdUSB; v2.0 */
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -196,7 +196,7 @@ static const u8 usb2_rh_dev_descriptor[18] = {
 /* usb 1.1 root hub device descriptor */
 static const u8 usb11_rh_dev_descriptor[18] = {
 	0x12,       /*  __u8  bLength; */
-	0x01,       /*  __u8  bDescriptorType; Device */
+	USB_DT_DEVICE, /* __u8 bDescriptorType; Device */
 	0x10, 0x01, /*  __le16 bcdUSB; v1.1 */
 
 	0x09,	    /*  __u8  bDeviceClass; HUB_CLASSCODE */
@@ -223,7 +223,7 @@ static const u8 fs_rh_config_descriptor[] = {
 
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
-	0x02,       /*  __u8  bDescriptorType; Configuration */
+	USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */
 	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
@@ -248,7 +248,7 @@ static const u8 fs_rh_config_descriptor[] = {
 
 	/* one interface */
 	0x09,       /*  __u8  if_bLength; */
-	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	USB_DT_INTERFACE,  /* __u8 if_bDescriptorType; Interface */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
@@ -259,7 +259,7 @@ static const u8 fs_rh_config_descriptor[] = {
 
 	/* one endpoint (status change endpoint) */
 	0x07,       /*  __u8  ep_bLength; */
-	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 	0x02, 0x00, /*  __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
@@ -270,7 +270,7 @@ static const u8 hs_rh_config_descriptor[] = {
 
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
-	0x02,       /*  __u8  bDescriptorType; Configuration */
+	USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */
 	0x19, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
@@ -295,7 +295,7 @@ static const u8 hs_rh_config_descriptor[] = {
 
 	/* one interface */
 	0x09,       /*  __u8  if_bLength; */
-	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
@@ -306,7 +306,7 @@ static const u8 hs_rh_config_descriptor[] = {
 
 	/* one endpoint (status change endpoint) */
 	0x07,       /*  __u8  ep_bLength; */
-	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
@@ -318,7 +318,7 @@ static const u8 hs_rh_config_descriptor[] = {
 static const u8 ss_rh_config_descriptor[] = {
 	/* one configuration */
 	0x09,       /*  __u8  bLength; */
-	0x02,       /*  __u8  bDescriptorType; Configuration */
+	USB_DT_CONFIG, /* __u8 bDescriptorType; Configuration */
 	0x1f, 0x00, /*  __le16 wTotalLength; */
 	0x01,       /*  __u8  bNumInterfaces; (1) */
 	0x01,       /*  __u8  bConfigurationValue; */
@@ -332,7 +332,7 @@ static const u8 ss_rh_config_descriptor[] = {
 
 	/* one interface */
 	0x09,       /*  __u8  if_bLength; */
-	0x04,       /*  __u8  if_bDescriptorType; Interface */
+	USB_DT_INTERFACE, /* __u8 if_bDescriptorType; Interface */
 	0x00,       /*  __u8  if_bInterfaceNumber; */
 	0x00,       /*  __u8  if_bAlternateSetting; */
 	0x01,       /*  __u8  if_bNumEndpoints; */
@@ -343,7 +343,7 @@ static const u8 ss_rh_config_descriptor[] = {
 
 	/* one endpoint (status change endpoint) */
 	0x07,       /*  __u8  ep_bLength; */
-	0x05,       /*  __u8  ep_bDescriptorType; Endpoint */
+	USB_DT_ENDPOINT, /* __u8 ep_bDescriptorType; Endpoint */
 	0x81,       /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
 	0x03,       /*  __u8  ep_bmAttributes; Interrupt */
 		    /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
@@ -353,7 +353,8 @@ static const u8 ss_rh_config_descriptor[] = {
 
 	/* one SuperSpeed endpoint companion descriptor */
 	0x06,        /* __u8 ss_bLength */
-	0x30,        /* __u8 ss_bDescriptorType; SuperSpeed EP Companion */
+	USB_DT_SS_ENDPOINT_COMP, /* __u8 ss_bDescriptorType; SuperSpeed EP */
+		     /* Companion */
 	0x00,        /* __u8 ss_bMaxBurst; allows 1 TX between ACKs */
 	0x00,        /* __u8 ss_bmAttributes; 1 packet per service interval */
 	0x02, 0x00   /* __le16 ss_wBytesPerInterval; 15 bits for max 15 ports */
@@ -555,6 +556,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
 		switch (wValue & 0xff00) {
 		case USB_DT_DEVICE << 8:
 			switch (hcd->speed) {
+			case HCD_USB31:
 			case HCD_USB3:
 				bufp = usb3_rh_dev_descriptor;
 				break;
@@ -576,6 +578,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
 			break;
 		case USB_DT_CONFIG << 8:
 			switch (hcd->speed) {
+			case HCD_USB31:
 			case HCD_USB3:
 				bufp = ss_rh_config_descriptor;
 				len = sizeof ss_rh_config_descriptor;
@@ -854,10 +857,10 @@ static ssize_t authorized_default_show(struct device *dev,
 {
 	struct usb_device *rh_usb_dev = to_usb_device(dev);
 	struct usb_bus *usb_bus = rh_usb_dev->bus;
-	struct usb_hcd *usb_hcd;
+	struct usb_hcd *hcd;
 
-	usb_hcd = bus_to_hcd(usb_bus);
-	return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default);
+	hcd = bus_to_hcd(usb_bus);
+	return snprintf(buf, PAGE_SIZE, "%u\n", !!HCD_DEV_AUTHORIZED(hcd));
 }
 
 static ssize_t authorized_default_store(struct device *dev,
@@ -868,12 +871,16 @@ static ssize_t authorized_default_store(struct device *dev,
 	unsigned val;
 	struct usb_device *rh_usb_dev = to_usb_device(dev);
 	struct usb_bus *usb_bus = rh_usb_dev->bus;
-	struct usb_hcd *usb_hcd;
+	struct usb_hcd *hcd;
 
-	usb_hcd = bus_to_hcd(usb_bus);
+	hcd = bus_to_hcd(usb_bus);
 	result = sscanf(buf, "%u\n", &val);
 	if (result == 1) {
-		usb_hcd->authorized_default = val ? 1 : 0;
+		if (val)
+			set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+		else
+			clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+
 		result = size;
 	} else {
 		result = -EINVAL;
@@ -882,9 +889,53 @@ static ssize_t authorized_default_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(authorized_default);
 
+/*
+ * interface_authorized_default_show - show default authorization status
+ * for USB interfaces
+ *
+ * note: interface_authorized_default is the default value
+ *       for initializing the authorized attribute of interfaces
+ */
+static ssize_t interface_authorized_default_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct usb_device *usb_dev = to_usb_device(dev);
+	struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+
+	return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
+}
+
+/*
+ * interface_authorized_default_store - store default authorization status
+ * for USB interfaces
+ *
+ * note: interface_authorized_default is the default value
+ *       for initializing the authorized attribute of interfaces
+ */
+static ssize_t interface_authorized_default_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct usb_device *usb_dev = to_usb_device(dev);
+	struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
+	int rc = count;
+	bool val;
+
+	if (strtobool(buf, &val) != 0)
+		return -EINVAL;
+
+	if (val)
+		set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+	else
+		clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+
+	return rc;
+}
+static DEVICE_ATTR_RW(interface_authorized_default);
+
 /* Group all the USB bus attributes */
 static struct attribute *usb_bus_attrs[] = {
 		&dev_attr_authorized_default.attr,
+		&dev_attr_interface_authorized_default.attr,
 		NULL,
 };
 
@@ -2676,12 +2727,22 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 
 	/* Keep old behaviour if authorized_default is not in [0, 1]. */
-	if (authorized_default < 0 || authorized_default > 1)
-		hcd->authorized_default = hcd->wireless ? 0 : 1;
-	else
-		hcd->authorized_default = authorized_default;
+	if (authorized_default < 0 || authorized_default > 1) {
+		if (hcd->wireless)
+			clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+		else
+			set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+	} else {
+		if (authorized_default)
+			set_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+		else
+			clear_bit(HCD_FLAG_DEV_AUTHORIZED, &hcd->flags);
+	}
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
+	/* per default all interfaces are authorized */
+	set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
+
 	/* HC is in reset state, but accessible.  Now do the one-time init,
 	 * bottom up so that hcds can customize the root hubs before hub_wq
 	 * starts talking to them.  (Note, bus id is assigned early too.)
@@ -2717,6 +2778,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 		rhdev->speed = USB_SPEED_WIRELESS;
 		break;
 	case HCD_USB3:
+	case HCD_USB31:
 		rhdev->speed = USB_SPEED_SUPER;
 		break;
 	default:
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 431839bd291f0b2ab2d66b0019c16f04421efc3e..bdeadc112d29f9b4545bf3ab82645b52982f5cfd 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1070,7 +1070,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 		 * for HUB_POST_RESET, but it's easier not to.
 		 */
 		if (type == HUB_INIT) {
-			unsigned delay = hub_power_on_good_delay(hub);
+			delay = hub_power_on_good_delay(hub);
 
 			hub_power_on(hub, false);
 			INIT_DELAYED_WORK(&hub->init_work, hub_init_func2);
@@ -1404,7 +1404,6 @@ static int hub_configure(struct usb_hub *hub,
 	/* FIXME for USB 3.0, skip for now */
 	if ((wHubCharacteristics & HUB_CHAR_COMPOUND) &&
 			!(hub_is_superspeed(hdev))) {
-		int	i;
 		char	portstr[USB_MAXCHILDREN + 1];
 
 		for (i = 0; i < maxchild; i++)
@@ -2240,39 +2239,49 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
 			&& udev->parent == udev->bus->root_hub) {
 		struct usb_otg_descriptor	*desc = NULL;
 		struct usb_bus			*bus = udev->bus;
+		unsigned			port1 = udev->portnum;
 
 		/* descriptor may appear anywhere in config */
-		if (__usb_get_extra_descriptor(udev->rawdescriptors[0],
-					le16_to_cpu(udev->config[0].desc.wTotalLength),
-					USB_DT_OTG, (void **) &desc) == 0) {
-			if (desc->bmAttributes & USB_OTG_HNP) {
-				unsigned		port1 = udev->portnum;
+		err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
+				le16_to_cpu(udev->config[0].desc.wTotalLength),
+				USB_DT_OTG, (void **) &desc);
+		if (err || !(desc->bmAttributes & USB_OTG_HNP))
+			return 0;
 
-				dev_info(&udev->dev,
-					"Dual-Role OTG device on %sHNP port\n",
-					(port1 == bus->otg_port)
-						? "" : "non-");
-
-				/* enable HNP before suspend, it's simpler */
-				if (port1 == bus->otg_port)
-					bus->b_hnp_enable = 1;
-				err = usb_control_msg(udev,
-					usb_sndctrlpipe(udev, 0),
-					USB_REQ_SET_FEATURE, 0,
-					bus->b_hnp_enable
-						? USB_DEVICE_B_HNP_ENABLE
-						: USB_DEVICE_A_ALT_HNP_SUPPORT,
-					0, NULL, 0, USB_CTRL_SET_TIMEOUT);
-				if (err < 0) {
-					/* OTG MESSAGE: report errors here,
-					 * customize to match your product.
-					 */
-					dev_info(&udev->dev,
-						"can't set HNP mode: %d\n",
-						err);
-					bus->b_hnp_enable = 0;
-				}
+		dev_info(&udev->dev, "Dual-Role OTG device on %sHNP port\n",
+					(port1 == bus->otg_port) ? "" : "non-");
+
+		/* enable HNP before suspend, it's simpler */
+		if (port1 == bus->otg_port) {
+			bus->b_hnp_enable = 1;
+			err = usb_control_msg(udev,
+				usb_sndctrlpipe(udev, 0),
+				USB_REQ_SET_FEATURE, 0,
+				USB_DEVICE_B_HNP_ENABLE,
+				0, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
+			if (err < 0) {
+				/*
+				 * OTG MESSAGE: report errors here,
+				 * customize to match your product.
+				 */
+				dev_err(&udev->dev, "can't set HNP mode: %d\n",
+									err);
+				bus->b_hnp_enable = 0;
 			}
+		} else if (desc->bLength == sizeof
+				(struct usb_otg_descriptor)) {
+			/* Set a_alt_hnp_support for legacy otg device */
+			err = usb_control_msg(udev,
+				usb_sndctrlpipe(udev, 0),
+				USB_REQ_SET_FEATURE, 0,
+				USB_DEVICE_A_ALT_HNP_SUPPORT,
+				0, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
+			if (err < 0)
+				dev_err(&udev->dev,
+					"set a_alt_hnp_support failed: %d\n",
+					err);
 		}
 	}
 #endif
@@ -4222,7 +4231,7 @@ static int hub_enable_device(struct usb_device *udev)
  * but it is still necessary to lock the port.
  */
 static int
-hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
+hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
 		int retry_counter)
 {
 	struct usb_device	*hdev = hub->hdev;
@@ -4526,7 +4535,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
 }
 
 static void
-check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
+check_highspeed(struct usb_hub *hub, struct usb_device *udev, int port1)
 {
 	struct usb_qualifier_descriptor	*qual;
 	int				status;
@@ -4534,11 +4543,11 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
 	if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
 		return;
 
-	qual = kmalloc (sizeof *qual, GFP_KERNEL);
+	qual = kmalloc(sizeof *qual, GFP_KERNEL);
 	if (qual == NULL)
 		return;
 
-	status = usb_get_descriptor (udev, USB_DT_DEVICE_QUALIFIER, 0,
+	status = usb_get_descriptor(udev, USB_DT_DEVICE_QUALIFIER, 0,
 			qual, sizeof *qual);
 	if (status == sizeof *qual) {
 		dev_info(&udev->dev, "not running at top speed; "
@@ -4554,7 +4563,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
 }
 
 static unsigned
-hub_power_remaining (struct usb_hub *hub)
+hub_power_remaining(struct usb_hub *hub)
 {
 	struct usb_device *hdev = hub->hdev;
 	int remaining;
@@ -4741,7 +4750,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
 		if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0200
 				&& udev->speed == USB_SPEED_FULL
 				&& highspeed_hubs != 0)
-			check_highspeed (hub, udev, port1);
+			check_highspeed(hub, udev, port1);
 
 		/* Store the parent's children[] pointer.  At this point
 		 * udev becomes globally accessible, although presumably
@@ -5115,7 +5124,7 @@ static const struct usb_device_id hub_id_table[] = {
     { }						/* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, hub_id_table);
+MODULE_DEVICE_TABLE(usb, hub_id_table);
 
 static struct usb_driver hub_driver = {
 	.name =		"hub",
@@ -5227,7 +5236,7 @@ static int descriptors_changed(struct usb_device *udev,
 			changed = 1;
 			break;
 		}
-		if (memcmp (buf, udev->rawdescriptors[index], old_length)
+		if (memcmp(buf, udev->rawdescriptors[index], old_length)
 				!= 0) {
 			dev_dbg(&udev->dev, "config index %d changed (#%d)\n",
 				index,
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index f368d2053da534ca975804dfad2bd8ddc77d5fba..8e641b5893edb7a6195c34e43248540fbff39aa6 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1387,8 +1387,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 	 * new altsetting.
 	 */
 	if (manual) {
-		int i;
-
 		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
 			epaddr = alt->endpoint[i].desc.bEndpointAddress;
 			pipe = __create_pipe(dev,
@@ -1555,6 +1553,44 @@ static void usb_release_interface(struct device *dev)
 	kfree(intf);
 }
 
+/*
+ * usb_deauthorize_interface - deauthorize an USB interface
+ *
+ * @intf: USB interface structure
+ */
+void usb_deauthorize_interface(struct usb_interface *intf)
+{
+	struct device *dev = &intf->dev;
+
+	device_lock(dev->parent);
+
+	if (intf->authorized) {
+		device_lock(dev);
+		intf->authorized = 0;
+		device_unlock(dev);
+
+		usb_forced_unbind_intf(intf);
+	}
+
+	device_unlock(dev->parent);
+}
+
+/*
+ * usb_authorize_interface - authorize an USB interface
+ *
+ * @intf: USB interface structure
+ */
+void usb_authorize_interface(struct usb_interface *intf)
+{
+	struct device *dev = &intf->dev;
+
+	if (!intf->authorized) {
+		device_lock(dev);
+		intf->authorized = 1; /* authorize interface */
+		device_unlock(dev);
+	}
+}
+
 static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct usb_device *usb_dev;
@@ -1807,6 +1843,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
 		intfc = cp->intf_cache[i];
 		intf->altsetting = intfc->altsetting;
 		intf->num_altsetting = intfc->num_altsetting;
+		intf->authorized = !!HCD_INTF_AUTHORIZED(hcd);
 		kref_get(&intfc->ref);
 
 		alt = usb_altnum_to_altsetting(intf, 0);
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index cfc68c11c3f565d27bfb9898a9e0d18e7a5d58e6..d9ec2de6c4cf8dd38bb7afb85399448f88992961 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -957,6 +957,41 @@ static ssize_t supports_autosuspend_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(supports_autosuspend);
 
+/*
+ * interface_authorized_show - show authorization status of an USB interface
+ * 1 is authorized, 0 is deauthorized
+ */
+static ssize_t interface_authorized_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+
+	return sprintf(buf, "%u\n", intf->authorized);
+}
+
+/*
+ * interface_authorized_store - authorize or deauthorize an USB interface
+ */
+static ssize_t interface_authorized_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	bool val;
+
+	if (strtobool(buf, &val) != 0)
+		return -EINVAL;
+
+	if (val)
+		usb_authorize_interface(intf);
+	else
+		usb_deauthorize_interface(intf);
+
+	return count;
+}
+static struct device_attribute dev_attr_interface_authorized =
+		__ATTR(authorized, S_IRUGO | S_IWUSR,
+		interface_authorized_show, interface_authorized_store);
+
 static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bAlternateSetting.attr,
@@ -966,6 +1001,7 @@ static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceProtocol.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_supports_autosuspend.attr,
+	&dev_attr_interface_authorized.attr,
 	NULL,
 };
 static struct attribute_group intf_attr_grp = {
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c9e8ee81b6b747f72fe91085e8e9621f4ad1b0c3..3d274778caaf8f9f473aacc89b1be6c20de19ab2 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -129,9 +129,8 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
 	list_add_tail(&urb->anchor_list, &anchor->urb_list);
 	urb->anchor = anchor;
 
-	if (unlikely(anchor->poisoned)) {
+	if (unlikely(anchor->poisoned))
 		atomic_inc(&urb->reject);
-	}
 
 	spin_unlock_irqrestore(&anchor->lock, flags);
 }
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 8d5b2f4113cd563004acbabb459f4e4212361138..f8bbd0b6d9fe44cb0077a200588c1ea054914580 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -510,7 +510,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 	if (root_hub)	/* Root hub always ok [and always wired] */
 		dev->authorized = 1;
 	else {
-		dev->authorized = usb_hcd->authorized_default;
+		dev->authorized = !!HCD_DEV_AUTHORIZED(usb_hcd);
 		dev->wusb = usb_bus_is_wusb(bus) ? 1 : 0;
 	}
 	return dev;
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 457255a3306a3c2837674d22aa9560bf30842220..05b5e17abf92fc158530d13f3e2ae8edf9923c5a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -27,6 +27,8 @@ extern void usb_release_interface_cache(struct kref *ref);
 extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
 extern int usb_deauthorize_device(struct usb_device *);
 extern int usb_authorize_device(struct usb_device *);
+extern void usb_deauthorize_interface(struct usb_interface *);
+extern void usb_authorize_interface(struct usb_interface *);
 extern void usb_detect_quirks(struct usb_device *udev);
 extern void usb_detect_interface_quirks(struct usb_device *udev);
 extern int usb_remove_device(struct usb_device *udev);
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index b00fe95391841f6c0cb968e7563eb65c0e83ac6f..ef73e498e98fc85501ff65cbeeaa20cd13ec9c4c 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -73,13 +73,13 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
 
 	/* Backup Host regs */
 	hr = &hsotg->hr_backup;
-	hr->hcfg = readl(hsotg->regs + HCFG);
-	hr->haintmsk = readl(hsotg->regs + HAINTMSK);
+	hr->hcfg = dwc2_readl(hsotg->regs + HCFG);
+	hr->haintmsk = dwc2_readl(hsotg->regs + HAINTMSK);
 	for (i = 0; i < hsotg->core_params->host_channels; ++i)
-		hr->hcintmsk[i] = readl(hsotg->regs + HCINTMSK(i));
+		hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i));
 
-	hr->hprt0 = readl(hsotg->regs + HPRT0);
-	hr->hfir = readl(hsotg->regs + HFIR);
+	hr->hprt0 = dwc2_read_hprt0(hsotg);
+	hr->hfir = dwc2_readl(hsotg->regs + HFIR);
 	hr->valid = true;
 
 	return 0;
@@ -108,14 +108,15 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
 	}
 	hr->valid = false;
 
-	writel(hr->hcfg, hsotg->regs + HCFG);
-	writel(hr->haintmsk, hsotg->regs + HAINTMSK);
+	dwc2_writel(hr->hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hr->haintmsk, hsotg->regs + HAINTMSK);
 
 	for (i = 0; i < hsotg->core_params->host_channels; ++i)
-		writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i));
+		dwc2_writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i));
 
-	writel(hr->hprt0, hsotg->regs + HPRT0);
-	writel(hr->hfir, hsotg->regs + HFIR);
+	dwc2_writel(hr->hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hr->hfir, hsotg->regs + HFIR);
+	hsotg->frame_number = 0;
 
 	return 0;
 }
@@ -146,15 +147,15 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 	/* Backup dev regs */
 	dr = &hsotg->dr_backup;
 
-	dr->dcfg = readl(hsotg->regs + DCFG);
-	dr->dctl = readl(hsotg->regs + DCTL);
-	dr->daintmsk = readl(hsotg->regs + DAINTMSK);
-	dr->diepmsk = readl(hsotg->regs + DIEPMSK);
-	dr->doepmsk = readl(hsotg->regs + DOEPMSK);
+	dr->dcfg = dwc2_readl(hsotg->regs + DCFG);
+	dr->dctl = dwc2_readl(hsotg->regs + DCTL);
+	dr->daintmsk = dwc2_readl(hsotg->regs + DAINTMSK);
+	dr->diepmsk = dwc2_readl(hsotg->regs + DIEPMSK);
+	dr->doepmsk = dwc2_readl(hsotg->regs + DOEPMSK);
 
 	for (i = 0; i < hsotg->num_of_eps; i++) {
 		/* Backup IN EPs */
-		dr->diepctl[i] = readl(hsotg->regs + DIEPCTL(i));
+		dr->diepctl[i] = dwc2_readl(hsotg->regs + DIEPCTL(i));
 
 		/* Ensure DATA PID is correctly configured */
 		if (dr->diepctl[i] & DXEPCTL_DPID)
@@ -162,11 +163,11 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 		else
 			dr->diepctl[i] |= DXEPCTL_SETD0PID;
 
-		dr->dieptsiz[i] = readl(hsotg->regs + DIEPTSIZ(i));
-		dr->diepdma[i] = readl(hsotg->regs + DIEPDMA(i));
+		dr->dieptsiz[i] = dwc2_readl(hsotg->regs + DIEPTSIZ(i));
+		dr->diepdma[i] = dwc2_readl(hsotg->regs + DIEPDMA(i));
 
 		/* Backup OUT EPs */
-		dr->doepctl[i] = readl(hsotg->regs + DOEPCTL(i));
+		dr->doepctl[i] = dwc2_readl(hsotg->regs + DOEPCTL(i));
 
 		/* Ensure DATA PID is correctly configured */
 		if (dr->doepctl[i] & DXEPCTL_DPID)
@@ -174,8 +175,8 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
 		else
 			dr->doepctl[i] |= DXEPCTL_SETD0PID;
 
-		dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i));
-		dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i));
+		dr->doeptsiz[i] = dwc2_readl(hsotg->regs + DOEPTSIZ(i));
+		dr->doepdma[i] = dwc2_readl(hsotg->regs + DOEPDMA(i));
 	}
 	dr->valid = true;
 	return 0;
@@ -205,28 +206,28 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
 	}
 	dr->valid = false;
 
-	writel(dr->dcfg, hsotg->regs + DCFG);
-	writel(dr->dctl, hsotg->regs + DCTL);
-	writel(dr->daintmsk, hsotg->regs + DAINTMSK);
-	writel(dr->diepmsk, hsotg->regs + DIEPMSK);
-	writel(dr->doepmsk, hsotg->regs + DOEPMSK);
+	dwc2_writel(dr->dcfg, hsotg->regs + DCFG);
+	dwc2_writel(dr->dctl, hsotg->regs + DCTL);
+	dwc2_writel(dr->daintmsk, hsotg->regs + DAINTMSK);
+	dwc2_writel(dr->diepmsk, hsotg->regs + DIEPMSK);
+	dwc2_writel(dr->doepmsk, hsotg->regs + DOEPMSK);
 
 	for (i = 0; i < hsotg->num_of_eps; i++) {
 		/* Restore IN EPs */
-		writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i));
-		writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i));
-		writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i));
+		dwc2_writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i));
+		dwc2_writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i));
+		dwc2_writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i));
 
 		/* Restore OUT EPs */
-		writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i));
-		writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i));
-		writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i));
+		dwc2_writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i));
+		dwc2_writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i));
+		dwc2_writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i));
 	}
 
 	/* Set the Power-On Programming done bit */
-	dctl = readl(hsotg->regs + DCTL);
+	dctl = dwc2_readl(hsotg->regs + DCTL);
 	dctl |= DCTL_PWRONPRGDONE;
-	writel(dctl, hsotg->regs + DCTL);
+	dwc2_writel(dctl, hsotg->regs + DCTL);
 
 	return 0;
 }
@@ -253,16 +254,16 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
 	/* Backup global regs */
 	gr = &hsotg->gr_backup;
 
-	gr->gotgctl = readl(hsotg->regs + GOTGCTL);
-	gr->gintmsk = readl(hsotg->regs + GINTMSK);
-	gr->gahbcfg = readl(hsotg->regs + GAHBCFG);
-	gr->gusbcfg = readl(hsotg->regs + GUSBCFG);
-	gr->grxfsiz = readl(hsotg->regs + GRXFSIZ);
-	gr->gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ);
-	gr->hptxfsiz = readl(hsotg->regs + HPTXFSIZ);
-	gr->gdfifocfg = readl(hsotg->regs + GDFIFOCFG);
+	gr->gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
+	gr->gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
+	gr->gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
+	gr->gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+	gr->grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
+	gr->gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
+	gr->hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
+	gr->gdfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG);
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
-		gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i));
+		gr->dtxfsiz[i] = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
 
 	gr->valid = true;
 	return 0;
@@ -291,17 +292,17 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
 	}
 	gr->valid = false;
 
-	writel(0xffffffff, hsotg->regs + GINTSTS);
-	writel(gr->gotgctl, hsotg->regs + GOTGCTL);
-	writel(gr->gintmsk, hsotg->regs + GINTMSK);
-	writel(gr->gusbcfg, hsotg->regs + GUSBCFG);
-	writel(gr->gahbcfg, hsotg->regs + GAHBCFG);
-	writel(gr->grxfsiz, hsotg->regs + GRXFSIZ);
-	writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ);
-	writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ);
-	writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG);
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
+	dwc2_writel(gr->gotgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(gr->gintmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(gr->gusbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(gr->gahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(gr->grxfsiz, hsotg->regs + GRXFSIZ);
+	dwc2_writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ);
+	dwc2_writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ);
+	dwc2_writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG);
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
-		writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i));
+		dwc2_writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i));
 
 	return 0;
 }
@@ -320,17 +321,17 @@ int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore)
 	if (!hsotg->core_params->hibernation)
 		return -ENOTSUPP;
 
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 	pcgcctl &= ~PCGCTL_STOPPCLK;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 	pcgcctl &= ~PCGCTL_PWRCLMP;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 	pcgcctl &= ~PCGCTL_RSTPDWNMODULE;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
 	udelay(100);
 	if (restore) {
@@ -397,19 +398,25 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg)
 		}
 	}
 
+	/*
+	 * Clear any pending interrupts since dwc2 will not be able to
+	 * clear them after entering hibernation.
+	 */
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
+
 	/* Put the controller in low power state */
-	pcgcctl = readl(hsotg->regs + PCGCTL);
+	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 
 	pcgcctl |= PCGCTL_PWRCLMP;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 	ndelay(20);
 
 	pcgcctl |= PCGCTL_RSTPDWNMODULE;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 	ndelay(20);
 
 	pcgcctl |= PCGCTL_STOPPCLK;
-	writel(pcgcctl, hsotg->regs + PCGCTL);
+	dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 
 	return ret;
 }
@@ -425,10 +432,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg)
 	u32 intmsk;
 
 	/* Clear any pending OTG Interrupts */
-	writel(0xffffffff, hsotg->regs + GOTGINT);
+	dwc2_writel(0xffffffff, hsotg->regs + GOTGINT);
 
 	/* Clear any pending interrupts */
-	writel(0xffffffff, hsotg->regs + GINTSTS);
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
 
 	/* Enable the interrupts in the GINTMSK */
 	intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT;
@@ -441,7 +448,7 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg)
 	intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP |
 		  GINTSTS_SESSREQINT;
 
-	writel(intmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 }
 
 /*
@@ -464,10 +471,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
 	}
 
 	dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val);
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 	hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT;
-	writel(hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hcfg, hsotg->regs + HCFG);
 }
 
 /*
@@ -485,7 +492,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 	/* Wait for AHB master IDLE state */
 	do {
 		usleep_range(20000, 40000);
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 50) {
 			dev_warn(hsotg->dev,
 				 "%s() HANG! AHB Idle GRSTCTL=%0x\n",
@@ -497,10 +504,10 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 	/* Core Soft Reset */
 	count = 0;
 	greset |= GRSTCTL_CSFTRST;
-	writel(greset, hsotg->regs + GRSTCTL);
+	dwc2_writel(greset, hsotg->regs + GRSTCTL);
 	do {
 		usleep_range(20000, 40000);
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 50) {
 			dev_warn(hsotg->dev,
 				 "%s() HANG! Soft Reset GRSTCTL=%0x\n",
@@ -510,20 +517,20 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg)
 	} while (greset & GRSTCTL_CSFTRST);
 
 	if (hsotg->dr_mode == USB_DR_MODE_HOST) {
-		gusbcfg = readl(hsotg->regs + GUSBCFG);
+		gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
 		gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-		writel(gusbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	} else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
-		gusbcfg = readl(hsotg->regs + GUSBCFG);
+		gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 		gusbcfg |= GUSBCFG_FORCEDEVMODE;
-		writel(gusbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	} else if (hsotg->dr_mode == USB_DR_MODE_OTG) {
-		gusbcfg = readl(hsotg->regs + GUSBCFG);
+		gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
 		gusbcfg &= ~GUSBCFG_FORCEDEVMODE;
-		writel(gusbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	}
 
 	/*
@@ -546,9 +553,9 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 	 */
 	if (select_phy) {
 		dev_dbg(hsotg->dev, "FS PHY selected\n");
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg |= GUSBCFG_PHYSEL;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 		/* Reset after a PHY select */
 		retval = dwc2_core_reset(hsotg);
@@ -571,18 +578,18 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 		dev_dbg(hsotg->dev, "FS PHY enabling I2C\n");
 
 		/* Program GUSBCFG.OtgUtmiFsSel to I2C */
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 		/* Program GI2CCTL.I2CEn */
-		i2cctl = readl(hsotg->regs + GI2CCTL);
+		i2cctl = dwc2_readl(hsotg->regs + GI2CCTL);
 		i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK;
 		i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT;
 		i2cctl &= ~GI2CCTL_I2CEN;
-		writel(i2cctl, hsotg->regs + GI2CCTL);
+		dwc2_writel(i2cctl, hsotg->regs + GI2CCTL);
 		i2cctl |= GI2CCTL_I2CEN;
-		writel(i2cctl, hsotg->regs + GI2CCTL);
+		dwc2_writel(i2cctl, hsotg->regs + GI2CCTL);
 	}
 
 	return retval;
@@ -596,7 +603,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 	if (!select_phy)
 		return 0;
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 
 	/*
 	 * HS PHY parameters. These parameters are preserved during soft reset
@@ -624,7 +631,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 		break;
 	}
 
-	writel(usbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 	/* Reset after setting the PHY parameters */
 	retval = dwc2_core_reset(hsotg);
@@ -659,15 +666,15 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 	    hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED &&
 	    hsotg->core_params->ulpi_fs_ls > 0) {
 		dev_dbg(hsotg->dev, "Setting ULPI FSLS\n");
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg |= GUSBCFG_ULPI_FS_LS;
 		usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 	} else {
-		usbcfg = readl(hsotg->regs + GUSBCFG);
+		usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 		usbcfg &= ~GUSBCFG_ULPI_FS_LS;
 		usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M;
-		writel(usbcfg, hsotg->regs + GUSBCFG);
+		dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 	}
 
 	return retval;
@@ -675,7 +682,7 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 
 static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 {
-	u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+	u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 	switch (hsotg->hw_params.arch) {
 	case GHWCFG2_EXT_DMA_ARCH:
@@ -714,7 +721,7 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg)
 	if (hsotg->core_params->dma_enable > 0)
 		ahbcfg |= GAHBCFG_DMA_EN;
 
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
 
 	return 0;
 }
@@ -723,7 +730,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
 {
 	u32 usbcfg;
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP);
 
 	switch (hsotg->hw_params.op_mode) {
@@ -751,7 +758,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg)
 		break;
 	}
 
-	writel(usbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 }
 
 /**
@@ -769,7 +776,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 
 	dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 
 	/* Set ULPI External VBUS bit if needed */
 	usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV;
@@ -782,7 +789,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 	if (hsotg->core_params->ts_dline > 0)
 		usbcfg |= GUSBCFG_TERMSELDLPULSE;
 
-	writel(usbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
 	/* Reset the Controller */
 	retval = dwc2_core_reset(hsotg);
@@ -808,11 +815,11 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 	dwc2_gusbcfg_init(hsotg);
 
 	/* Program the GOTGCTL register */
-	otgctl = readl(hsotg->regs + GOTGCTL);
+	otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	otgctl &= ~GOTGCTL_OTGVER;
 	if (hsotg->core_params->otg_ver > 0)
 		otgctl |= GOTGCTL_OTGVER;
-	writel(otgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
 	dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver);
 
 	/* Clear the SRP success bit for FS-I2c */
@@ -848,16 +855,16 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "%s()\n", __func__);
 
 	/* Disable all interrupts */
-	writel(0, hsotg->regs + GINTMSK);
-	writel(0, hsotg->regs + HAINTMSK);
+	dwc2_writel(0, hsotg->regs + GINTMSK);
+	dwc2_writel(0, hsotg->regs + HAINTMSK);
 
 	/* Enable the common interrupts */
 	dwc2_enable_common_interrupts(hsotg);
 
 	/* Enable host mode interrupts without disturbing common interrupts */
-	intmsk = readl(hsotg->regs + GINTMSK);
+	intmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT;
-	writel(intmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 }
 
 /**
@@ -867,12 +874,12 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg)
  */
 void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
 {
-	u32 intmsk = readl(hsotg->regs + GINTMSK);
+	u32 intmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 	/* Disable host mode interrupts without disturbing common interrupts */
 	intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT |
-		    GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP);
-	writel(intmsk, hsotg->regs + GINTMSK);
+		    GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP | GINTSTS_DISCONNINT);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 }
 
 /*
@@ -952,36 +959,37 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
 	dwc2_calculate_dynamic_fifo(hsotg);
 
 	/* Rx FIFO */
-	grxfsiz = readl(hsotg->regs + GRXFSIZ);
+	grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
 	dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);
 	grxfsiz &= ~GRXFSIZ_DEPTH_MASK;
 	grxfsiz |= params->host_rx_fifo_size <<
 		   GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK;
-	writel(grxfsiz, hsotg->regs + GRXFSIZ);
-	dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", readl(hsotg->regs + GRXFSIZ));
+	dwc2_writel(grxfsiz, hsotg->regs + GRXFSIZ);
+	dev_dbg(hsotg->dev, "new grxfsiz=%08x\n",
+		dwc2_readl(hsotg->regs + GRXFSIZ));
 
 	/* Non-periodic Tx FIFO */
 	dev_dbg(hsotg->dev, "initial gnptxfsiz=%08x\n",
-		readl(hsotg->regs + GNPTXFSIZ));
+		dwc2_readl(hsotg->regs + GNPTXFSIZ));
 	nptxfsiz = params->host_nperio_tx_fifo_size <<
 		   FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK;
 	nptxfsiz |= params->host_rx_fifo_size <<
 		    FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK;
-	writel(nptxfsiz, hsotg->regs + GNPTXFSIZ);
+	dwc2_writel(nptxfsiz, hsotg->regs + GNPTXFSIZ);
 	dev_dbg(hsotg->dev, "new gnptxfsiz=%08x\n",
-		readl(hsotg->regs + GNPTXFSIZ));
+		dwc2_readl(hsotg->regs + GNPTXFSIZ));
 
 	/* Periodic Tx FIFO */
 	dev_dbg(hsotg->dev, "initial hptxfsiz=%08x\n",
-		readl(hsotg->regs + HPTXFSIZ));
+		dwc2_readl(hsotg->regs + HPTXFSIZ));
 	hptxfsiz = params->host_perio_tx_fifo_size <<
 		   FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK;
 	hptxfsiz |= (params->host_rx_fifo_size +
 		     params->host_nperio_tx_fifo_size) <<
 		    FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK;
-	writel(hptxfsiz, hsotg->regs + HPTXFSIZ);
+	dwc2_writel(hptxfsiz, hsotg->regs + HPTXFSIZ);
 	dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n",
-		readl(hsotg->regs + HPTXFSIZ));
+		dwc2_readl(hsotg->regs + HPTXFSIZ));
 
 	if (hsotg->core_params->en_multiple_tx_fifo > 0 &&
 	    hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) {
@@ -989,14 +997,14 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
 		 * Global DFIFOCFG calculation for Host mode -
 		 * include RxFIFO, NPTXFIFO and HPTXFIFO
 		 */
-		dfifocfg = readl(hsotg->regs + GDFIFOCFG);
+		dfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG);
 		dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK;
 		dfifocfg |= (params->host_rx_fifo_size +
 			     params->host_nperio_tx_fifo_size +
 			     params->host_perio_tx_fifo_size) <<
 			    GDFIFOCFG_EPINFOBASE_SHIFT &
 			    GDFIFOCFG_EPINFOBASE_MASK;
-		writel(dfifocfg, hsotg->regs + GDFIFOCFG);
+		dwc2_writel(dfifocfg, hsotg->regs + GDFIFOCFG);
 	}
 }
 
@@ -1017,14 +1025,14 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 
 	/* Restart the Phy Clock */
-	writel(0, hsotg->regs + PCGCTL);
+	dwc2_writel(0, hsotg->regs + PCGCTL);
 
 	/* Initialize Host Configuration Register */
 	dwc2_init_fs_ls_pclk_sel(hsotg);
 	if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) {
-		hcfg = readl(hsotg->regs + HCFG);
+		hcfg = dwc2_readl(hsotg->regs + HCFG);
 		hcfg |= HCFG_FSLSSUPP;
-		writel(hcfg, hsotg->regs + HCFG);
+		dwc2_writel(hcfg, hsotg->regs + HCFG);
 	}
 
 	/*
@@ -1033,9 +1041,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 	 * and its value must not be changed during runtime.
 	 */
 	if (hsotg->core_params->reload_ctl > 0) {
-		hfir = readl(hsotg->regs + HFIR);
+		hfir = dwc2_readl(hsotg->regs + HFIR);
 		hfir |= HFIR_RLDCTRL;
-		writel(hfir, hsotg->regs + HFIR);
+		dwc2_writel(hfir, hsotg->regs + HFIR);
 	}
 
 	if (hsotg->core_params->dma_desc_enable > 0) {
@@ -1051,9 +1059,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 				"falling back to buffer DMA mode.\n");
 			hsotg->core_params->dma_desc_enable = 0;
 		} else {
-			hcfg = readl(hsotg->regs + HCFG);
+			hcfg = dwc2_readl(hsotg->regs + HCFG);
 			hcfg |= HCFG_DESCDMA;
-			writel(hcfg, hsotg->regs + HCFG);
+			dwc2_writel(hcfg, hsotg->regs + HCFG);
 		}
 	}
 
@@ -1062,18 +1070,18 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 
 	/* TODO - check this */
 	/* Clear Host Set HNP Enable in the OTG Control Register */
-	otgctl = readl(hsotg->regs + GOTGCTL);
+	otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	otgctl &= ~GOTGCTL_HSTSETHNPEN;
-	writel(otgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
 
 	/* Make sure the FIFOs are flushed */
 	dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */);
 	dwc2_flush_rx_fifo(hsotg);
 
 	/* Clear Host Set HNP Enable in the OTG Control Register */
-	otgctl = readl(hsotg->regs + GOTGCTL);
+	otgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	otgctl &= ~GOTGCTL_HSTSETHNPEN;
-	writel(otgctl, hsotg->regs + GOTGCTL);
+	dwc2_writel(otgctl, hsotg->regs + GOTGCTL);
 
 	if (hsotg->core_params->dma_desc_enable <= 0) {
 		int num_channels, i;
@@ -1082,25 +1090,25 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 		/* Flush out any leftover queued requests */
 		num_channels = hsotg->core_params->host_channels;
 		for (i = 0; i < num_channels; i++) {
-			hcchar = readl(hsotg->regs + HCCHAR(i));
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 			hcchar &= ~HCCHAR_CHENA;
 			hcchar |= HCCHAR_CHDIS;
 			hcchar &= ~HCCHAR_EPDIR;
-			writel(hcchar, hsotg->regs + HCCHAR(i));
+			dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 		}
 
 		/* Halt all channels to put them into a known state */
 		for (i = 0; i < num_channels; i++) {
 			int count = 0;
 
-			hcchar = readl(hsotg->regs + HCCHAR(i));
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 			hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
 			hcchar &= ~HCCHAR_EPDIR;
-			writel(hcchar, hsotg->regs + HCCHAR(i));
+			dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 			dev_dbg(hsotg->dev, "%s: Halt channel %d\n",
 				__func__, i);
 			do {
-				hcchar = readl(hsotg->regs + HCCHAR(i));
+				hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 				if (++count > 1000) {
 					dev_err(hsotg->dev,
 						"Unable to clear enable on channel %d\n",
@@ -1121,7 +1129,7 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 			!!(hprt0 & HPRT0_PWR));
 		if (!(hprt0 & HPRT0_PWR)) {
 			hprt0 |= HPRT0_PWR;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 		}
 	}
 
@@ -1201,7 +1209,7 @@ static void dwc2_hc_enable_slave_ints(struct dwc2_hsotg *hsotg,
 		break;
 	}
 
-	writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk);
 }
@@ -1238,7 +1246,7 @@ static void dwc2_hc_enable_dma_ints(struct dwc2_hsotg *hsotg,
 		}
 	}
 
-	writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk);
 }
@@ -1259,16 +1267,16 @@ static void dwc2_hc_enable_ints(struct dwc2_hsotg *hsotg,
 	}
 
 	/* Enable the top level host channel interrupt */
-	intmsk = readl(hsotg->regs + HAINTMSK);
+	intmsk = dwc2_readl(hsotg->regs + HAINTMSK);
 	intmsk |= 1 << chan->hc_num;
-	writel(intmsk, hsotg->regs + HAINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + HAINTMSK);
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk);
 
 	/* Make sure host channel interrupts are enabled */
-	intmsk = readl(hsotg->regs + GINTMSK);
+	intmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	intmsk |= GINTSTS_HCHINT;
-	writel(intmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk);
 }
@@ -1297,7 +1305,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 	/* Clear old interrupt conditions for this host channel */
 	hcintmsk = 0xffffffff;
 	hcintmsk &= ~HCINTMSK_RESERVED14_31;
-	writel(hcintmsk, hsotg->regs + HCINT(hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINT(hc_num));
 
 	/* Enable channel interrupts required for this transfer */
 	dwc2_hc_enable_ints(hsotg, chan);
@@ -1314,7 +1322,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 		hcchar |= HCCHAR_LSPDDEV;
 	hcchar |= chan->ep_type << HCCHAR_EPTYPE_SHIFT & HCCHAR_EPTYPE_MASK;
 	hcchar |= chan->max_packet << HCCHAR_MPS_SHIFT & HCCHAR_MPS_MASK;
-	writel(hcchar, hsotg->regs + HCCHAR(hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(hc_num));
 	if (dbg_hc(chan)) {
 		dev_vdbg(hsotg->dev, "set HCCHAR(%d) to %08x\n",
 			 hc_num, hcchar);
@@ -1368,7 +1376,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 		}
 	}
 
-	writel(hcsplt, hsotg->regs + HCSPLT(hc_num));
+	dwc2_writel(hcsplt, hsotg->regs + HCSPLT(hc_num));
 }
 
 /**
@@ -1420,14 +1428,14 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		u32 hcintmsk = HCINTMSK_CHHLTD;
 
 		dev_vdbg(hsotg->dev, "dequeue/error\n");
-		writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
+		dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num));
 
 		/*
 		 * Make sure no other interrupts besides halt are currently
 		 * pending. Handling another interrupt could cause a crash due
 		 * to the QTD and QH state.
 		 */
-		writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num));
+		dwc2_writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num));
 
 		/*
 		 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
@@ -1436,7 +1444,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		 */
 		chan->halt_status = halt_status;
 
-		hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+		hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 		if (!(hcchar & HCCHAR_CHENA)) {
 			/*
 			 * The channel is either already halted or it hasn't
@@ -1464,7 +1472,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		return;
 	}
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 
 	/* No need to set the bit in DDMA for disabling the channel */
 	/* TODO check it everywhere channel is disabled */
@@ -1487,7 +1495,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL ||
 		    chan->ep_type == USB_ENDPOINT_XFER_BULK) {
 			dev_vdbg(hsotg->dev, "control/bulk\n");
-			nptxsts = readl(hsotg->regs + GNPTXSTS);
+			nptxsts = dwc2_readl(hsotg->regs + GNPTXSTS);
 			if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) {
 				dev_vdbg(hsotg->dev, "Disabling channel\n");
 				hcchar &= ~HCCHAR_CHENA;
@@ -1495,7 +1503,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 		} else {
 			if (dbg_perio())
 				dev_vdbg(hsotg->dev, "isoc/intr\n");
-			hptxsts = readl(hsotg->regs + HPTXSTS);
+			hptxsts = dwc2_readl(hsotg->regs + HPTXSTS);
 			if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 ||
 			    hsotg->queuing_high_bandwidth) {
 				if (dbg_perio())
@@ -1508,7 +1516,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
 			dev_vdbg(hsotg->dev, "DMA enabled\n");
 	}
 
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 	chan->halt_status = halt_status;
 
 	if (hcchar & HCCHAR_CHENA) {
@@ -1555,10 +1563,10 @@ void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 	 * Clear channel interrupt enables and any unhandled channel interrupt
 	 * conditions
 	 */
-	writel(0, hsotg->regs + HCINTMSK(chan->hc_num));
+	dwc2_writel(0, hsotg->regs + HCINTMSK(chan->hc_num));
 	hcintmsk = 0xffffffff;
 	hcintmsk &= ~HCINTMSK_RESERVED14_31;
-	writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num));
+	dwc2_writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num));
 }
 
 /**
@@ -1644,13 +1652,13 @@ static void dwc2_hc_write_packet(struct dwc2_hsotg *hsotg,
 	if (((unsigned long)data_buf & 0x3) == 0) {
 		/* xfer_buf is DWORD aligned */
 		for (i = 0; i < dword_count; i++, data_buf++)
-			writel(*data_buf, data_fifo);
+			dwc2_writel(*data_buf, data_fifo);
 	} else {
 		/* xfer_buf is not DWORD aligned */
 		for (i = 0; i < dword_count; i++, data_buf++) {
 			u32 data = data_buf[0] | data_buf[1] << 8 |
 				   data_buf[2] << 16 | data_buf[3] << 24;
-			writel(data, data_fifo);
+			dwc2_writel(data, data_fifo);
 		}
 	}
 
@@ -1803,7 +1811,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 	hctsiz |= num_packets << TSIZ_PKTCNT_SHIFT & TSIZ_PKTCNT_MASK;
 	hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT &
 		  TSIZ_SC_MC_PID_MASK;
-	writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
+	dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
 	if (dbg_hc(chan)) {
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCTSIZ(%d)\n",
 			 hctsiz, chan->hc_num);
@@ -1831,7 +1839,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 		} else {
 			dma_addr = chan->xfer_dma;
 		}
-		writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
+		dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num));
 		if (dbg_hc(chan))
 			dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n",
 				 (unsigned long)dma_addr, chan->hc_num);
@@ -1839,13 +1847,13 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 
 	/* Start the split */
 	if (chan->do_split) {
-		u32 hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num));
+		u32 hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num));
 
 		hcsplt |= HCSPLT_SPLTENA;
-		writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num));
+		dwc2_writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num));
 	}
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 	hcchar &= ~HCCHAR_MULTICNT_MASK;
 	hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT &
 		  HCCHAR_MULTICNT_MASK;
@@ -1865,7 +1873,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg,
 			 (hcchar & HCCHAR_MULTICNT_MASK) >>
 			 HCCHAR_MULTICNT_SHIFT);
 
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
 			 chan->hc_num);
@@ -1924,18 +1932,18 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg,
 		dev_vdbg(hsotg->dev, "	 NTD: %d\n", chan->ntd - 1);
 	}
 
-	writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
+	dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
 
 	hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK;
 
 	/* Always start from first descriptor */
 	hc_dma &= ~HCDMA_CTD_MASK;
-	writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num));
+	dwc2_writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num));
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCDMA(%d)\n",
 			 hc_dma, chan->hc_num);
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 	hcchar &= ~HCCHAR_MULTICNT_MASK;
 	hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT &
 		  HCCHAR_MULTICNT_MASK;
@@ -1954,7 +1962,7 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg,
 			 (hcchar & HCCHAR_MULTICNT_MASK) >>
 			 HCCHAR_MULTICNT_SHIFT);
 
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 	if (dbg_hc(chan))
 		dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar,
 			 chan->hc_num);
@@ -2011,7 +2019,7 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg,
 		 * transfer completes, the extra requests for the channel will
 		 * be flushed.
 		 */
-		u32 hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+		u32 hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 
 		dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar);
 		hcchar |= HCCHAR_CHENA;
@@ -2019,7 +2027,7 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg,
 		if (dbg_hc(chan))
 			dev_vdbg(hsotg->dev, "	 IN xfer: hcchar = 0x%08x\n",
 				 hcchar);
-		writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+		dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 		chan->requests++;
 		return 1;
 	}
@@ -2029,8 +2037,8 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg,
 	if (chan->xfer_count < chan->xfer_len) {
 		if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
 		    chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
-			u32 hcchar = readl(hsotg->regs +
-					   HCCHAR(chan->hc_num));
+			u32 hcchar = dwc2_readl(hsotg->regs +
+						HCCHAR(chan->hc_num));
 
 			dwc2_hc_set_even_odd_frame(hsotg, chan,
 						   &hcchar);
@@ -2066,12 +2074,12 @@ void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan)
 
 	hctsiz = TSIZ_DOPNG;
 	hctsiz |= 1 << TSIZ_PKTCNT_SHIFT;
-	writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
+	dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num));
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
 	hcchar |= HCCHAR_CHENA;
 	hcchar &= ~HCCHAR_CHDIS;
-	writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
+	dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num));
 }
 
 /**
@@ -2090,8 +2098,8 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg)
 	u32 hprt0;
 	int clock = 60;	/* default value */
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
-	hprt0 = readl(hsotg->regs + HPRT0);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+	hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 
 	if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) &&
 	    !(usbcfg & GUSBCFG_PHYIF16))
@@ -2147,7 +2155,7 @@ void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes)
 	dev_vdbg(hsotg->dev, "%s(%p,%p,%d)\n", __func__, hsotg, dest, bytes);
 
 	for (i = 0; i < word_count; i++, data_buf++)
-		*data_buf = readl(fifo);
+		*data_buf = dwc2_readl(fifo);
 }
 
 /**
@@ -2167,56 +2175,56 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "Host Global Registers\n");
 	addr = hsotg->regs + HCFG;
 	dev_dbg(hsotg->dev, "HCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HFIR;
 	dev_dbg(hsotg->dev, "HFIR	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HFNUM;
 	dev_dbg(hsotg->dev, "HFNUM	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HPTXSTS;
 	dev_dbg(hsotg->dev, "HPTXSTS	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HAINT;
 	dev_dbg(hsotg->dev, "HAINT	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HAINTMSK;
 	dev_dbg(hsotg->dev, "HAINTMSK	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	if (hsotg->core_params->dma_desc_enable > 0) {
 		addr = hsotg->regs + HFLBADDR;
 		dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 	}
 
 	addr = hsotg->regs + HPRT0;
 	dev_dbg(hsotg->dev, "HPRT0	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 
 	for (i = 0; i < hsotg->core_params->host_channels; i++) {
 		dev_dbg(hsotg->dev, "Host Channel %d Specific Registers\n", i);
 		addr = hsotg->regs + HCCHAR(i);
 		dev_dbg(hsotg->dev, "HCCHAR	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCSPLT(i);
 		dev_dbg(hsotg->dev, "HCSPLT	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCINT(i);
 		dev_dbg(hsotg->dev, "HCINT	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCINTMSK(i);
 		dev_dbg(hsotg->dev, "HCINTMSK	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCTSIZ(i);
 		dev_dbg(hsotg->dev, "HCTSIZ	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		addr = hsotg->regs + HCDMA(i);
 		dev_dbg(hsotg->dev, "HCDMA	 @0x%08lX : 0x%08X\n",
-			(unsigned long)addr, readl(addr));
+			(unsigned long)addr, dwc2_readl(addr));
 		if (hsotg->core_params->dma_desc_enable > 0) {
 			addr = hsotg->regs + HCDMAB(i);
 			dev_dbg(hsotg->dev, "HCDMAB	 @0x%08lX : 0x%08X\n",
-				(unsigned long)addr, readl(addr));
+				(unsigned long)addr, dwc2_readl(addr));
 		}
 	}
 #endif
@@ -2238,80 +2246,80 @@ void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "Core Global Registers\n");
 	addr = hsotg->regs + GOTGCTL;
 	dev_dbg(hsotg->dev, "GOTGCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GOTGINT;
 	dev_dbg(hsotg->dev, "GOTGINT	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GAHBCFG;
 	dev_dbg(hsotg->dev, "GAHBCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GUSBCFG;
 	dev_dbg(hsotg->dev, "GUSBCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GRSTCTL;
 	dev_dbg(hsotg->dev, "GRSTCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GINTSTS;
 	dev_dbg(hsotg->dev, "GINTSTS	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GINTMSK;
 	dev_dbg(hsotg->dev, "GINTMSK	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GRXSTSR;
 	dev_dbg(hsotg->dev, "GRXSTSR	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GRXFSIZ;
 	dev_dbg(hsotg->dev, "GRXFSIZ	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GNPTXFSIZ;
 	dev_dbg(hsotg->dev, "GNPTXFSIZ	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GNPTXSTS;
 	dev_dbg(hsotg->dev, "GNPTXSTS	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GI2CCTL;
 	dev_dbg(hsotg->dev, "GI2CCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GPVNDCTL;
 	dev_dbg(hsotg->dev, "GPVNDCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GGPIO;
 	dev_dbg(hsotg->dev, "GGPIO	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GUID;
 	dev_dbg(hsotg->dev, "GUID	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GSNPSID;
 	dev_dbg(hsotg->dev, "GSNPSID	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG1;
 	dev_dbg(hsotg->dev, "GHWCFG1	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG2;
 	dev_dbg(hsotg->dev, "GHWCFG2	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG3;
 	dev_dbg(hsotg->dev, "GHWCFG3	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GHWCFG4;
 	dev_dbg(hsotg->dev, "GHWCFG4	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GLPMCFG;
 	dev_dbg(hsotg->dev, "GLPMCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GPWRDN;
 	dev_dbg(hsotg->dev, "GPWRDN	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + GDFIFOCFG;
 	dev_dbg(hsotg->dev, "GDFIFOCFG	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 	addr = hsotg->regs + HPTXFSIZ;
 	dev_dbg(hsotg->dev, "HPTXFSIZ	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 
 	addr = hsotg->regs + PCGCTL;
 	dev_dbg(hsotg->dev, "PCGCTL	 @0x%08lX : 0x%08X\n",
-		(unsigned long)addr, readl(addr));
+		(unsigned long)addr, dwc2_readl(addr));
 #endif
 }
 
@@ -2330,15 +2338,15 @@ void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num)
 
 	greset = GRSTCTL_TXFFLSH;
 	greset |= num << GRSTCTL_TXFNUM_SHIFT & GRSTCTL_TXFNUM_MASK;
-	writel(greset, hsotg->regs + GRSTCTL);
+	dwc2_writel(greset, hsotg->regs + GRSTCTL);
 
 	do {
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 10000) {
 			dev_warn(hsotg->dev,
 				 "%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
 				 __func__, greset,
-				 readl(hsotg->regs + GNPTXSTS));
+				 dwc2_readl(hsotg->regs + GNPTXSTS));
 			break;
 		}
 		udelay(1);
@@ -2361,10 +2369,10 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg)
 	dev_vdbg(hsotg->dev, "%s()\n", __func__);
 
 	greset = GRSTCTL_RXFFLSH;
-	writel(greset, hsotg->regs + GRSTCTL);
+	dwc2_writel(greset, hsotg->regs + GRSTCTL);
 
 	do {
-		greset = readl(hsotg->regs + GRSTCTL);
+		greset = dwc2_readl(hsotg->regs + GRSTCTL);
 		if (++count > 10000) {
 			dev_warn(hsotg->dev, "%s() HANG! GRSTCTL=%0x\n",
 				 __func__, greset);
@@ -3062,7 +3070,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 	 * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3",
 	 * as in "OTG version 2.xx" or "OTG version 3.xx".
 	 */
-	hw->snpsid = readl(hsotg->regs + GSNPSID);
+	hw->snpsid = dwc2_readl(hsotg->regs + GSNPSID);
 	if ((hw->snpsid & 0xfffff000) != 0x4f542000 &&
 	    (hw->snpsid & 0xfffff000) != 0x4f543000) {
 		dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n",
@@ -3074,11 +3082,11 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 		hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf,
 		hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid);
 
-	hwcfg1 = readl(hsotg->regs + GHWCFG1);
-	hwcfg2 = readl(hsotg->regs + GHWCFG2);
-	hwcfg3 = readl(hsotg->regs + GHWCFG3);
-	hwcfg4 = readl(hsotg->regs + GHWCFG4);
-	grxfsiz = readl(hsotg->regs + GRXFSIZ);
+	hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1);
+	hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2);
+	hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3);
+	hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
+	grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ);
 
 	dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1);
 	dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2);
@@ -3087,18 +3095,18 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz);
 
 	/* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */
-	gusbcfg = readl(hsotg->regs + GUSBCFG);
+	gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	gusbcfg |= GUSBCFG_FORCEHOSTMODE;
-	writel(gusbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	usleep_range(100000, 150000);
 
-	gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ);
-	hptxfsiz = readl(hsotg->regs + HPTXFSIZ);
+	gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ);
+	hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ);
 	dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz);
 	dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz);
-	gusbcfg = readl(hsotg->regs + GUSBCFG);
+	gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	gusbcfg &= ~GUSBCFG_FORCEHOSTMODE;
-	writel(gusbcfg, hsotg->regs + GUSBCFG);
+	dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG);
 	usleep_range(100000, 150000);
 
 	/* hwcfg2 */
@@ -3233,7 +3241,7 @@ u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg)
 
 bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
 {
-	if (readl(hsotg->regs + GSNPSID) == 0xffffffff)
+	if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff)
 		return false;
 	else
 		return true;
@@ -3247,10 +3255,10 @@ bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg)
  */
 void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg)
 {
-	u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+	u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 	ahbcfg |= GAHBCFG_GLBL_INTR_EN;
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
 }
 
 /**
@@ -3261,10 +3269,10 @@ void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg)
  */
 void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg)
 {
-	u32 ahbcfg = readl(hsotg->regs + GAHBCFG);
+	u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 	ahbcfg &= ~GAHBCFG_GLBL_INTR_EN;
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
 }
 
 MODULE_DESCRIPTION("DESIGNWARE HS OTG Core");
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 0ed87620941b5606b83f7e628439266ca7831e18..a66d3cb62b65980fe670bc51bb5f4401a58d9df3 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -44,22 +44,38 @@
 #include <linux/usb/phy.h>
 #include "hw.h"
 
-#ifdef DWC2_LOG_WRITES
-static inline void do_write(u32 value, void *addr)
+static inline u32 dwc2_readl(const void __iomem *addr)
 {
-	writel(value, addr);
-	pr_info("INFO:: wrote %08x to %p\n", value, addr);
+	u32 value = __raw_readl(addr);
+
+	/* In order to preserve endianness __raw_* operation is used. Therefore
+	 * a barrier is needed to ensure IO access is not re-ordered across
+	 * reads or writes
+	 */
+	mb();
+	return value;
 }
 
-#undef writel
-#define writel(v, a)	do_write(v, a)
+static inline void dwc2_writel(u32 value, void __iomem *addr)
+{
+	__raw_writel(value, addr);
+
+	/*
+	 * In order to preserve endianness __raw_* operation is used. Therefore
+	 * a barrier is needed to ensure IO access is not re-ordered across
+	 * reads or writes
+	 */
+	mb();
+#ifdef DWC2_LOG_WRITES
+	pr_info("INFO:: wrote %08x to %p\n", value, addr);
 #endif
+}
 
 /* Maximum number of Endpoints/HostChannels */
 #define MAX_EPS_CHANNELS	16
 
-/* s3c-hsotg declarations */
-static const char * const s3c_hsotg_supply_names[] = {
+/* dwc2-hsotg declarations */
+static const char * const dwc2_hsotg_supply_names[] = {
 	"vusb_d",               /* digital USB supply, 1.2V */
 	"vusb_a",               /* analog USB supply, 1.1V */
 };
@@ -85,10 +101,10 @@ static const char * const s3c_hsotg_supply_names[] = {
 #define EP0_MPS_LIMIT   64
 
 struct dwc2_hsotg;
-struct s3c_hsotg_req;
+struct dwc2_hsotg_req;
 
 /**
- * struct s3c_hsotg_ep - driver endpoint definition.
+ * struct dwc2_hsotg_ep - driver endpoint definition.
  * @ep: The gadget layer representation of the endpoint.
  * @name: The driver generated name for the endpoint.
  * @queue: Queue of requests for this endpoint.
@@ -127,11 +143,11 @@ struct s3c_hsotg_req;
  * as in shared-fifo mode periodic in acts like a single-frame packet
  * buffer than a fifo)
  */
-struct s3c_hsotg_ep {
+struct dwc2_hsotg_ep {
 	struct usb_ep           ep;
 	struct list_head        queue;
 	struct dwc2_hsotg       *parent;
-	struct s3c_hsotg_req    *req;
+	struct dwc2_hsotg_req    *req;
 	struct dentry           *debugfs;
 
 	unsigned long           total_data;
@@ -150,17 +166,18 @@ struct s3c_hsotg_ep {
 	unsigned int            periodic:1;
 	unsigned int            isochronous:1;
 	unsigned int            send_zlp:1;
+	unsigned int            has_correct_parity:1;
 
 	char                    name[10];
 };
 
 /**
- * struct s3c_hsotg_req - data transfer request
+ * struct dwc2_hsotg_req - data transfer request
  * @req: The USB gadget request
  * @queue: The list of requests for the endpoint this is queued for.
  * @saved_req_buf: variable to save req.buf when bounce buffers are used.
  */
-struct s3c_hsotg_req {
+struct dwc2_hsotg_req {
 	struct usb_request      req;
 	struct list_head        queue;
 	void *saved_req_buf;
@@ -562,6 +579,15 @@ struct dwc2_hregs_backup {
  *                      - USB_DR_MODE_PERIPHERAL
  *                      - USB_DR_MODE_HOST
  *                      - USB_DR_MODE_OTG
+ * @hcd_enabled		Host mode sub-driver initialization indicator.
+ * @gadget_enabled	Peripheral mode sub-driver initialization indicator.
+ * @ll_hw_enabled	Status of low-level hardware resources.
+ * @phy:                The otg phy transceiver structure for phy control.
+ * @uphy:               The otg phy transceiver structure for old USB phy control.
+ * @plat:               The platform specific configuration data. This can be removed once
+ *                      all SoCs support usb transceiver.
+ * @supplies:           Definition of USB power supplies
+ * @phyif:              PHY interface width
  * @lock:		Spinlock that protects all the driver data structures
  * @priv:		Stores a pointer to the struct usb_hcd
  * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth
@@ -654,12 +680,6 @@ struct dwc2_hregs_backup {
  * These are for peripheral mode:
  *
  * @driver:             USB gadget driver
- * @phy:                The otg phy transceiver structure for phy control.
- * @uphy:               The otg phy transceiver structure for old USB phy control.
- * @plat:               The platform specific configuration data. This can be removed once
- *                      all SoCs support usb transceiver.
- * @supplies:           Definition of USB power supplies
- * @phyif:              PHY interface width
  * @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.
@@ -672,7 +692,6 @@ struct dwc2_hregs_backup {
  * @ctrl_req:           Request for EP0 control packets.
  * @ep0_state:          EP0 control transfers state
  * @test_mode:          USB test mode requested by the host
- * @last_rst:           Time of last reset
  * @eps:                The endpoints being supplied to the gadget framework
  * @g_using_dma:          Indicate if dma usage is enabled
  * @g_rx_fifo_sz:         Contains rx fifo size value
@@ -690,13 +709,15 @@ struct dwc2_hsotg {
 	enum usb_dr_mode dr_mode;
 	unsigned int hcd_enabled:1;
 	unsigned int gadget_enabled:1;
+	unsigned int ll_hw_enabled:1;
 
 	struct phy *phy;
 	struct usb_phy *uphy;
-	struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)];
+	struct dwc2_hsotg_plat *plat;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)];
+	u32 phyif;
 
 	spinlock_t lock;
-	struct mutex init_mutex;
 	void *priv;
 	int     irq;
 	struct clk *clk;
@@ -748,6 +769,7 @@ struct dwc2_hsotg {
 	u16 frame_usecs[8];
 	u16 frame_number;
 	u16 periodic_qh_count;
+	bool bus_suspended;
 
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
 #define FRAME_NUM_ARRAY_SIZE 1000
@@ -796,9 +818,6 @@ struct dwc2_hsotg {
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
 	/* Gadget structures */
 	struct usb_gadget_driver *driver;
-	struct s3c_hsotg_plat *plat;
-
-	u32 phyif;
 	int fifo_mem;
 	unsigned int dedicated_fifos:1;
 	unsigned char num_of_eps;
@@ -814,9 +833,8 @@ struct dwc2_hsotg {
 	struct usb_gadget gadget;
 	unsigned int enabled:1;
 	unsigned int connected:1;
-	unsigned long last_rst;
-	struct s3c_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
-	struct s3c_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
+	struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS];
+	struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS];
 	u32 g_using_dma;
 	u32 g_rx_fifo_sz;
 	u32 g_np_g_tx_fifo_sz;
@@ -1088,7 +1106,8 @@ extern void dwc2_set_all_params(struct dwc2_core_params *params, int value);
 
 extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg);
 
-
+extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg);
+extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg);
 
 /*
  * Dump core registers and SPRAM
@@ -1104,30 +1123,30 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg);
 
 /* Gadget defines */
 #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE)
-extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg);
-extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2);
-extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2);
+extern int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg);
+extern int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2);
+extern int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2);
 extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
-extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
+extern void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
 		bool reset);
-extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg);
-extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2);
-extern int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
+extern void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg);
+extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2);
+extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode);
 #define dwc2_is_device_connected(hsotg) (hsotg->connected)
 #else
-static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2)
+static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2)
 { return 0; }
-static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2)
+static inline int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2)
 { return 0; }
-static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2)
+static inline int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2)
 { return 0; }
 static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 { return 0; }
-static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
+static inline void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
 		bool reset) {}
-static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
-static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
-static inline int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
+static inline void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
+static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg,
 							int testmode)
 { return 0; }
 #define dwc2_is_device_connected(hsotg) (0)
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 927be1e8b3dc93951cb78ac7665eb0aa0bedfcf8..27daa42788b1a4ab2ac74200d15d8b1a6f212f38 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -80,15 +80,15 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg)
  */
 static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg)
 {
-	u32 hprt0 = readl(hsotg->regs + HPRT0);
+	u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 
 	if (hprt0 & HPRT0_ENACHG) {
 		hprt0 &= ~HPRT0_ENA;
-		writel(hprt0, hsotg->regs + HPRT0);
+		dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	}
 
 	/* Clear interrupt */
-	writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS);
 }
 
 /**
@@ -102,7 +102,7 @@ static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg)
 		 dwc2_is_host_mode(hsotg) ? "Host" : "Device");
 
 	/* Clear interrupt */
-	writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS);
 }
 
 /**
@@ -117,8 +117,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 	u32 gotgctl;
 	u32 gintmsk;
 
-	gotgint = readl(hsotg->regs + GOTGINT);
-	gotgctl = readl(hsotg->regs + GOTGCTL);
+	gotgint = dwc2_readl(hsotg->regs + GOTGINT);
+	gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint,
 		dwc2_op_state_str(hsotg));
 
@@ -126,10 +126,10 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 		dev_dbg(hsotg->dev,
 			" ++OTG Interrupt: Session End Detected++ (%s)\n",
 			dwc2_op_state_str(hsotg));
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 
 		if (dwc2_is_device_mode(hsotg))
-			s3c_hsotg_disconnect(hsotg);
+			dwc2_hsotg_disconnect(hsotg);
 
 		if (hsotg->op_state == OTG_STATE_B_HOST) {
 			hsotg->op_state = OTG_STATE_B_PERIPHERAL;
@@ -152,15 +152,15 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 			hsotg->lx_state = DWC2_L0;
 		}
 
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		gotgctl &= ~GOTGCTL_DEVHNPEN;
-		writel(gotgctl, hsotg->regs + GOTGCTL);
+		dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 	}
 
 	if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) {
 		dev_dbg(hsotg->dev,
 			" ++OTG Interrupt: Session Request Success Status Change++\n");
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		if (gotgctl & GOTGCTL_SESREQSCS) {
 			if (hsotg->core_params->phy_type ==
 					DWC2_PHY_TYPE_PARAM_FS
@@ -168,9 +168,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 				hsotg->srp_success = 1;
 			} else {
 				/* Clear Session Request */
-				gotgctl = readl(hsotg->regs + GOTGCTL);
+				gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 				gotgctl &= ~GOTGCTL_SESREQ;
-				writel(gotgctl, hsotg->regs + GOTGCTL);
+				dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 			}
 		}
 	}
@@ -180,7 +180,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 		 * Print statements during the HNP interrupt handling
 		 * can cause it to fail
 		 */
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		/*
 		 * WA for 3.00a- HW is not setting cur_mode, even sometimes
 		 * this does not help
@@ -200,9 +200,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 				 * interrupt does not get handled and Linux
 				 * complains loudly.
 				 */
-				gintmsk = readl(hsotg->regs + GINTMSK);
+				gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 				gintmsk &= ~GINTSTS_SOF;
-				writel(gintmsk, hsotg->regs + GINTMSK);
+				dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 
 				/*
 				 * Call callback function with spin lock
@@ -216,9 +216,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 				hsotg->op_state = OTG_STATE_B_HOST;
 			}
 		} else {
-			gotgctl = readl(hsotg->regs + GOTGCTL);
+			gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 			gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN);
-			writel(gotgctl, hsotg->regs + GOTGCTL);
+			dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 			dev_dbg(hsotg->dev, "HNP Failed\n");
 			dev_err(hsotg->dev,
 				"Device Not Connected/Responding\n");
@@ -244,9 +244,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 			hsotg->op_state = OTG_STATE_A_PERIPHERAL;
 		} else {
 			/* Need to disable SOF interrupt immediately */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk &= ~GINTSTS_SOF;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 			spin_unlock(&hsotg->lock);
 			dwc2_hcd_start(hsotg);
 			spin_lock(&hsotg->lock);
@@ -261,7 +261,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
 		dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n");
 
 	/* Clear GOTGINT */
-	writel(gotgint, hsotg->regs + GOTGINT);
+	dwc2_writel(gotgint, hsotg->regs + GOTGINT);
 }
 
 /**
@@ -276,11 +276,11 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
  */
 static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
 {
-	u32 gintmsk = readl(hsotg->regs + GINTMSK);
+	u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 	/* Need to disable SOF interrupt immediately */
 	gintmsk &= ~GINTSTS_SOF;
-	writel(gintmsk, hsotg->regs + GINTMSK);
+	dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 
 	dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++  (%s)\n",
 		dwc2_is_host_mode(hsotg) ? "Host" : "Device");
@@ -297,7 +297,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
 	}
 
 	/* Clear interrupt */
-	writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS);
 }
 
 /**
@@ -313,16 +313,28 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
  */
 static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 {
-	dev_dbg(hsotg->dev, "++Session Request Interrupt++\n");
+	int ret;
+
+	dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n",
+							hsotg->lx_state);
 
 	/* Clear interrupt */
-	writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS);
 
-	/*
-	 * Report disconnect if there is any previous session established
-	 */
-	if (dwc2_is_device_mode(hsotg))
-		s3c_hsotg_disconnect(hsotg);
+	if (dwc2_is_device_mode(hsotg)) {
+		if (hsotg->lx_state == DWC2_L2) {
+			ret = dwc2_exit_hibernation(hsotg, true);
+			if (ret && (ret != -ENOTSUPP))
+				dev_err(hsotg->dev,
+					"exit hibernation failed\n");
+		}
+
+		/*
+		 * Report disconnect if there is any previous session
+		 * established
+		 */
+		dwc2_hsotg_disconnect(hsotg);
+	}
 }
 
 /*
@@ -339,13 +351,14 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
 
 	if (dwc2_is_device_mode(hsotg)) {
-		dev_dbg(hsotg->dev, "DSTS=0x%0x\n", readl(hsotg->regs + DSTS));
+		dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
+			dwc2_readl(hsotg->regs + DSTS));
 		if (hsotg->lx_state == DWC2_L2) {
-			u32 dctl = readl(hsotg->regs + DCTL);
+			u32 dctl = dwc2_readl(hsotg->regs + DCTL);
 
 			/* Clear Remote Wakeup Signaling */
 			dctl &= ~DCTL_RMTWKUPSIG;
-			writel(dctl, hsotg->regs + DCTL);
+			dwc2_writel(dctl, hsotg->regs + DCTL);
 			ret = dwc2_exit_hibernation(hsotg, true);
 			if (ret && (ret != -ENOTSUPP))
 				dev_err(hsotg->dev, "exit hibernation failed\n");
@@ -355,12 +368,16 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 		/* Change to L0 state */
 		hsotg->lx_state = DWC2_L0;
 	} else {
+		if (hsotg->core_params->hibernation) {
+			dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
+			return;
+		}
 		if (hsotg->lx_state != DWC2_L1) {
-			u32 pcgcctl = readl(hsotg->regs + PCGCTL);
+			u32 pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
 
 			/* Restart the Phy Clock */
 			pcgcctl &= ~PCGCTL_STOPPCLK;
-			writel(pcgcctl, hsotg->regs + PCGCTL);
+			dwc2_writel(pcgcctl, hsotg->regs + PCGCTL);
 			mod_timer(&hsotg->wkp_timer,
 				  jiffies + msecs_to_jiffies(71));
 		} else {
@@ -370,7 +387,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 	}
 
 	/* Clear interrupt */
-	writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS);
 }
 
 /*
@@ -386,10 +403,7 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg)
 	if (hsotg->op_state == OTG_STATE_A_HOST)
 		dwc2_hcd_disconnect(hsotg);
 
-	/* Change to L3 (OFF) state */
-	hsotg->lx_state = DWC2_L3;
-
-	writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS);
 }
 
 /*
@@ -412,7 +426,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 		 * Check the Device status register to determine if the Suspend
 		 * state is active
 		 */
-		dsts = readl(hsotg->regs + DSTS);
+		dsts = dwc2_readl(hsotg->regs + DSTS);
 		dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts);
 		dev_dbg(hsotg->dev,
 			"DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n",
@@ -465,7 +479,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 
 clear_int:
 	/* Clear interrupt */
-	writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS);
 }
 
 #define GINTMSK_COMMON	(GINTSTS_WKUPINT | GINTSTS_SESSREQINT |		\
@@ -483,9 +497,9 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
 	u32 gahbcfg;
 	u32 gintmsk_common = GINTMSK_COMMON;
 
-	gintsts = readl(hsotg->regs + GINTSTS);
-	gintmsk = readl(hsotg->regs + GINTMSK);
-	gahbcfg = readl(hsotg->regs + GAHBCFG);
+	gintsts = dwc2_readl(hsotg->regs + GINTSTS);
+	gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
+	gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 	/* If any common interrupts set */
 	if (gintsts & gintmsk_common)
diff --git a/drivers/usb/dwc2/debugfs.c b/drivers/usb/dwc2/debugfs.c
index ef2ee3d9a25d2e37a47028f53793ef077b857015..55d91f24f94ab3aefd21c74626d7244fdccd7947 100644
--- a/drivers/usb/dwc2/debugfs.c
+++ b/drivers/usb/dwc2/debugfs.c
@@ -57,7 +57,7 @@ static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t
 		testmode = 0;
 
 	spin_lock_irqsave(&hsotg->lock, flags);
-	s3c_hsotg_set_test_mode(hsotg, testmode);
+	dwc2_hsotg_set_test_mode(hsotg, testmode);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	return count;
 }
@@ -76,7 +76,7 @@ static int testmode_show(struct seq_file *s, void *unused)
 	int dctl;
 
 	spin_lock_irqsave(&hsotg->lock, flags);
-	dctl = readl(hsotg->regs + DCTL);
+	dctl = dwc2_readl(hsotg->regs + DCTL);
 	dctl &= DCTL_TSTCTL_MASK;
 	dctl >>= DCTL_TSTCTL_SHIFT;
 	spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -137,38 +137,38 @@ static int state_show(struct seq_file *seq, void *v)
 	int idx;
 
 	seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n",
-		 readl(regs + DCFG),
-		 readl(regs + DCTL),
-		 readl(regs + DSTS));
+		 dwc2_readl(regs + DCFG),
+		 dwc2_readl(regs + DCTL),
+		 dwc2_readl(regs + DSTS));
 
 	seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n",
-		   readl(regs + DIEPMSK), readl(regs + DOEPMSK));
+		   dwc2_readl(regs + DIEPMSK), dwc2_readl(regs + DOEPMSK));
 
 	seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n",
-		   readl(regs + GINTMSK),
-		   readl(regs + GINTSTS));
+		   dwc2_readl(regs + GINTMSK),
+		   dwc2_readl(regs + GINTSTS));
 
 	seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n",
-		   readl(regs + DAINTMSK),
-		   readl(regs + DAINT));
+		   dwc2_readl(regs + DAINTMSK),
+		   dwc2_readl(regs + DAINT));
 
 	seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n",
-		   readl(regs + GNPTXSTS),
-		   readl(regs + GRXSTSR));
+		   dwc2_readl(regs + GNPTXSTS),
+		   dwc2_readl(regs + GRXSTSR));
 
 	seq_puts(seq, "\nEndpoint status:\n");
 
 	for (idx = 0; idx < hsotg->num_of_eps; idx++) {
 		u32 in, out;
 
-		in = readl(regs + DIEPCTL(idx));
-		out = readl(regs + DOEPCTL(idx));
+		in = dwc2_readl(regs + DIEPCTL(idx));
+		out = dwc2_readl(regs + DOEPCTL(idx));
 
 		seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x",
 			   idx, in, out);
 
-		in = readl(regs + DIEPTSIZ(idx));
-		out = readl(regs + DOEPTSIZ(idx));
+		in = dwc2_readl(regs + DIEPTSIZ(idx));
+		out = dwc2_readl(regs + DOEPTSIZ(idx));
 
 		seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x",
 			   in, out);
@@ -208,9 +208,9 @@ static int fifo_show(struct seq_file *seq, void *v)
 	int idx;
 
 	seq_puts(seq, "Non-periodic FIFOs:\n");
-	seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ));
+	seq_printf(seq, "RXFIFO: Size %d\n", dwc2_readl(regs + GRXFSIZ));
 
-	val = readl(regs + GNPTXFSIZ);
+	val = dwc2_readl(regs + GNPTXFSIZ);
 	seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n",
 		   val >> FIFOSIZE_DEPTH_SHIFT,
 		   val & FIFOSIZE_DEPTH_MASK);
@@ -218,7 +218,7 @@ static int fifo_show(struct seq_file *seq, void *v)
 	seq_puts(seq, "\nPeriodic TXFIFOs:\n");
 
 	for (idx = 1; idx < hsotg->num_of_eps; idx++) {
-		val = readl(regs + DPTXFSIZN(idx));
+		val = dwc2_readl(regs + DPTXFSIZN(idx));
 
 		seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx,
 			   val >> FIFOSIZE_DEPTH_SHIFT,
@@ -256,9 +256,9 @@ static const char *decode_direction(int is_in)
  */
 static int ep_show(struct seq_file *seq, void *v)
 {
-	struct s3c_hsotg_ep *ep = seq->private;
+	struct dwc2_hsotg_ep *ep = seq->private;
 	struct dwc2_hsotg *hsotg = ep->parent;
-	struct s3c_hsotg_req *req;
+	struct dwc2_hsotg_req *req;
 	void __iomem *regs = hsotg->regs;
 	int index = ep->index;
 	int show_limit = 15;
@@ -270,20 +270,20 @@ static int ep_show(struct seq_file *seq, void *v)
 	/* first show the register state */
 
 	seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n",
-		   readl(regs + DIEPCTL(index)),
-		   readl(regs + DOEPCTL(index)));
+		   dwc2_readl(regs + DIEPCTL(index)),
+		   dwc2_readl(regs + DOEPCTL(index)));
 
 	seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n",
-		   readl(regs + DIEPDMA(index)),
-		   readl(regs + DOEPDMA(index)));
+		   dwc2_readl(regs + DIEPDMA(index)),
+		   dwc2_readl(regs + DOEPDMA(index)));
 
 	seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n",
-		   readl(regs + DIEPINT(index)),
-		   readl(regs + DOEPINT(index)));
+		   dwc2_readl(regs + DIEPINT(index)),
+		   dwc2_readl(regs + DOEPINT(index)));
 
 	seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n",
-		   readl(regs + DIEPTSIZ(index)),
-		   readl(regs + DOEPTSIZ(index)));
+		   dwc2_readl(regs + DIEPTSIZ(index)),
+		   dwc2_readl(regs + DOEPTSIZ(index)));
 
 	seq_puts(seq, "\n");
 	seq_printf(seq, "mps %d\n", ep->ep.maxpacket);
@@ -326,7 +326,7 @@ static const struct file_operations ep_fops = {
 };
 
 /**
- * s3c_hsotg_create_debug - create debugfs directory and files
+ * dwc2_hsotg_create_debug - create debugfs directory and files
  * @hsotg: The driver state
  *
  * Create the debugfs files to allow the user to get information
@@ -334,7 +334,7 @@ static const struct file_operations ep_fops = {
  * with the same name as the device itself, in case we end up
  * with multiple blocks in future systems.
  */
-static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 {
 	struct dentry *root;
 	struct dentry *file;
@@ -360,7 +360,7 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 
 	/* Create one file for each out endpoint */
 	for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) {
-		struct s3c_hsotg_ep *ep;
+		struct dwc2_hsotg_ep *ep;
 
 		ep = hsotg->eps_out[epidx];
 		if (ep) {
@@ -373,7 +373,7 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 	}
 	/* Create one file for each in endpoint. EP0 is handled with out eps */
 	for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) {
-		struct s3c_hsotg_ep *ep;
+		struct dwc2_hsotg_ep *ep;
 
 		ep = hsotg->eps_in[epidx];
 		if (ep) {
@@ -386,10 +386,10 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg)
 	}
 }
 #else
-static inline void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) {}
 #endif
 
-/* s3c_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */
+/* dwc2_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */
 
 #define dump_register(nm)	\
 {				\
@@ -737,7 +737,7 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg)
 	}
 
 	/* Add gadget debugfs nodes */
-	s3c_hsotg_create_debug(hsotg);
+	dwc2_hsotg_create_debug(hsotg);
 
 	hsotg->regset = devm_kzalloc(hsotg->dev, sizeof(*hsotg->regset),
 								GFP_KERNEL);
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 3ee5b4c77a1f42eeecf1f222ab63e822b1530c9a..0abf73c91beb0f5eef5f25a4e46b7070ee03fdc2 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -25,28 +25,24 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
 #include <linux/of_platform.h>
-#include <linux/phy/phy.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/phy.h>
-#include <linux/platform_data/s3c-hsotg.h>
 
 #include "core.h"
 #include "hw.h"
 
 /* conversion functions */
-static inline struct s3c_hsotg_req *our_req(struct usb_request *req)
+static inline struct dwc2_hsotg_req *our_req(struct usb_request *req)
 {
-	return container_of(req, struct s3c_hsotg_req, req);
+	return container_of(req, struct dwc2_hsotg_req, req);
 }
 
-static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep)
+static inline struct dwc2_hsotg_ep *our_ep(struct usb_ep *ep)
 {
-	return container_of(ep, struct s3c_hsotg_ep, ep);
+	return container_of(ep, struct dwc2_hsotg_ep, ep);
 }
 
 static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget)
@@ -56,15 +52,15 @@ static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget)
 
 static inline void __orr32(void __iomem *ptr, u32 val)
 {
-	writel(readl(ptr) | val, ptr);
+	dwc2_writel(dwc2_readl(ptr) | val, ptr);
 }
 
 static inline void __bic32(void __iomem *ptr, u32 val)
 {
-	writel(readl(ptr) & ~val, ptr);
+	dwc2_writel(dwc2_readl(ptr) & ~val, ptr);
 }
 
-static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg,
+static inline struct dwc2_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg,
 						u32 ep_index, u32 dir_in)
 {
 	if (dir_in)
@@ -74,7 +70,7 @@ static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg,
 }
 
 /* forward declaration of functions */
-static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg);
+static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg);
 
 /**
  * using_dma - return the DMA status of the driver.
@@ -101,41 +97,41 @@ static inline bool using_dma(struct dwc2_hsotg *hsotg)
 }
 
 /**
- * s3c_hsotg_en_gsint - enable one or more of the general interrupt
+ * dwc2_hsotg_en_gsint - enable one or more of the general interrupt
  * @hsotg: The device state
  * @ints: A bitmask of the interrupts to enable
  */
-static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints)
+static void dwc2_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints)
 {
-	u32 gsintmsk = readl(hsotg->regs + GINTMSK);
+	u32 gsintmsk = dwc2_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 + GINTMSK);
+		dwc2_writel(new_gsintmsk, hsotg->regs + GINTMSK);
 	}
 }
 
 /**
- * s3c_hsotg_disable_gsint - disable one or more of the general interrupt
+ * dwc2_hsotg_disable_gsint - disable one or more of the general interrupt
  * @hsotg: The device state
  * @ints: A bitmask of the interrupts to enable
  */
-static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
+static void dwc2_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
 {
-	u32 gsintmsk = readl(hsotg->regs + GINTMSK);
+	u32 gsintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 	u32 new_gsintmsk;
 
 	new_gsintmsk = gsintmsk & ~ints;
 
 	if (new_gsintmsk != gsintmsk)
-		writel(new_gsintmsk, hsotg->regs + GINTMSK);
+		dwc2_writel(new_gsintmsk, hsotg->regs + GINTMSK);
 }
 
 /**
- * s3c_hsotg_ctrl_epint - enable/disable an endpoint irq
+ * dwc2_hsotg_ctrl_epint - enable/disable an endpoint irq
  * @hsotg: The device state
  * @ep: The endpoint index
  * @dir_in: True if direction is in.
@@ -144,7 +140,7 @@ static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints)
  * Set or clear the mask for an individual endpoint's interrupt
  * request.
  */
-static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
+static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
 				 unsigned int ep, unsigned int dir_in,
 				 unsigned int en)
 {
@@ -156,20 +152,20 @@ static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg,
 		bit <<= 16;
 
 	local_irq_save(flags);
-	daint = readl(hsotg->regs + DAINTMSK);
+	daint = dwc2_readl(hsotg->regs + DAINTMSK);
 	if (en)
 		daint |= bit;
 	else
 		daint &= ~bit;
-	writel(daint, hsotg->regs + DAINTMSK);
+	dwc2_writel(daint, hsotg->regs + DAINTMSK);
 	local_irq_restore(flags);
 }
 
 /**
- * s3c_hsotg_init_fifo - initialise non-periodic FIFOs
+ * dwc2_hsotg_init_fifo - initialise non-periodic FIFOs
  * @hsotg: The device instance.
  */
-static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 {
 	unsigned int ep;
 	unsigned int addr;
@@ -181,8 +177,8 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 	hsotg->fifo_map = 0;
 
 	/* set RX/NPTX FIFO sizes */
-	writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ);
-	writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) |
+	dwc2_writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ);
+	dwc2_writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) |
 		(hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT),
 		hsotg->regs + GNPTXFSIZ);
 
@@ -210,7 +206,7 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 			  "insufficient fifo memory");
 		addr += hsotg->g_tx_fifo_sz[ep];
 
-		writel(val, hsotg->regs + DPTXFSIZN(ep));
+		dwc2_writel(val, hsotg->regs + DPTXFSIZN(ep));
 	}
 
 	/*
@@ -218,13 +214,13 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
 	 * all fifos are flushed before continuing
 	 */
 
-	writel(GRSTCTL_TXFNUM(0x10) | GRSTCTL_TXFFLSH |
+	dwc2_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 + GRSTCTL);
+		val = dwc2_readl(hsotg->regs + GRSTCTL);
 
 		if ((val & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH)) == 0)
 			break;
@@ -248,12 +244,12 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg)
  *
  * Allocate a new USB request structure appropriate for the specified endpoint
  */
-static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep,
+static struct usb_request *dwc2_hsotg_ep_alloc_request(struct usb_ep *ep,
 						      gfp_t flags)
 {
-	struct s3c_hsotg_req *req;
+	struct dwc2_hsotg_req *req;
 
-	req = kzalloc(sizeof(struct s3c_hsotg_req), flags);
+	req = kzalloc(sizeof(struct dwc2_hsotg_req), flags);
 	if (!req)
 		return NULL;
 
@@ -269,23 +265,23 @@ static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep,
  * Returns true if the endpoint is in periodic mode, meaning it is being
  * used for an Interrupt or ISO transfer.
  */
-static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep)
+static inline int is_ep_periodic(struct dwc2_hsotg_ep *hs_ep)
 {
 	return hs_ep->periodic;
 }
 
 /**
- * s3c_hsotg_unmap_dma - unmap the DMA memory being used for the request
+ * dwc2_hsotg_unmap_dma - unmap the DMA memory being used for the request
  * @hsotg: The device state.
  * @hs_ep: The endpoint for the request
  * @hs_req: The request being processed.
  *
- * This is the reverse of s3c_hsotg_map_dma(), called for the completion
+ * This is the reverse of dwc2_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 dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *hs_ep,
-				struct s3c_hsotg_req *hs_req)
+static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *hs_ep,
+				struct dwc2_hsotg_req *hs_req)
 {
 	struct usb_request *req = &hs_req->req;
 
@@ -297,7 +293,7 @@ static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
 }
 
 /**
- * s3c_hsotg_write_fifo - write packet Data to the TxFIFO
+ * dwc2_hsotg_write_fifo - write packet Data to the TxFIFO
  * @hsotg: The controller state.
  * @hs_ep: The endpoint we're going to write for.
  * @hs_req: The request to write data for.
@@ -312,12 +308,12 @@ static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
  *
  * This routine is only needed for PIO
  */
-static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *hs_ep,
-				struct s3c_hsotg_req *hs_req)
+static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *hs_ep,
+				struct dwc2_hsotg_req *hs_req)
 {
 	bool periodic = is_ep_periodic(hs_ep);
-	u32 gnptxsts = readl(hsotg->regs + GNPTXSTS);
+	u32 gnptxsts = dwc2_readl(hsotg->regs + GNPTXSTS);
 	int buf_pos = hs_req->req.actual;
 	int to_write = hs_ep->size_loaded;
 	void *data;
@@ -332,7 +328,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 		return 0;
 
 	if (periodic && !hsotg->dedicated_fifos) {
-		u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
+		u32 epsize = dwc2_readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
 		int size_left;
 		int size_done;
 
@@ -348,7 +344,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 		 * previous data has been completely sent.
 		 */
 		if (hs_ep->fifo_load != 0) {
-			s3c_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
+			dwc2_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
 			return -ENOSPC;
 		}
 
@@ -369,11 +365,11 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 			__func__, can_write);
 
 		if (can_write <= 0) {
-			s3c_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
+			dwc2_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP);
 			return -ENOSPC;
 		}
 	} else if (hsotg->dedicated_fifos && hs_ep->index != 0) {
-		can_write = readl(hsotg->regs + DTXFSTS(hs_ep->index));
+		can_write = dwc2_readl(hsotg->regs + DTXFSTS(hs_ep->index));
 
 		can_write &= 0xffff;
 		can_write *= 4;
@@ -383,7 +379,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 				"%s: no queue slots available (0x%08x)\n",
 				__func__, gnptxsts);
 
-			s3c_hsotg_en_gsint(hsotg, GINTSTS_NPTXFEMP);
+			dwc2_hsotg_en_gsint(hsotg, GINTSTS_NPTXFEMP);
 			return -ENOSPC;
 		}
 
@@ -414,7 +410,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 
 		/* it's needed only when we do not use dedicated fifos */
 		if (!hsotg->dedicated_fifos)
-			s3c_hsotg_en_gsint(hsotg,
+			dwc2_hsotg_en_gsint(hsotg,
 					   periodic ? GINTSTS_PTXFEMP :
 					   GINTSTS_NPTXFEMP);
 	}
@@ -443,7 +439,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
 
 		/* it's needed only when we do not use dedicated fifos */
 		if (!hsotg->dedicated_fifos)
-			s3c_hsotg_en_gsint(hsotg,
+			dwc2_hsotg_en_gsint(hsotg,
 					   periodic ? GINTSTS_PTXFEMP :
 					   GINTSTS_NPTXFEMP);
 	}
@@ -475,7 +471,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg,
  * Return the maximum data that can be queued in one go on a given endpoint
  * so that transfers that are too long can be split.
  */
-static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
+static unsigned get_ep_limit(struct dwc2_hsotg_ep *hs_ep)
 {
 	int index = hs_ep->index;
 	unsigned maxsize;
@@ -508,7 +504,7 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
 }
 
 /**
- * s3c_hsotg_start_req - start a USB request from an endpoint's queue
+ * dwc2_hsotg_start_req - start a USB request from an endpoint's queue
  * @hsotg: The controller state.
  * @hs_ep: The endpoint to process a request for
  * @hs_req: The request to start.
@@ -517,9 +513,9 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep)
  * Start the given request running by setting the endpoint registers
  * appropriately, and writing any data to the FIFOs.
  */
-static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *hs_ep,
-				struct s3c_hsotg_req *hs_req,
+static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *hs_ep,
+				struct dwc2_hsotg_req *hs_req,
 				bool continuing)
 {
 	struct usb_request *ureq = &hs_req->req;
@@ -550,13 +546,13 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	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,
+		__func__, dwc2_readl(hsotg->regs + epctrl_reg), index,
 		hs_ep->dir_in ? "in" : "out");
 
 	/* If endpoint is stalled, we will restart request later */
-	ctrl = readl(hsotg->regs + epctrl_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 
-	if (ctrl & DXEPCTL_STALL) {
+	if (index && ctrl & DXEPCTL_STALL) {
 		dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index);
 		return;
 	}
@@ -618,18 +614,18 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	hs_ep->req = hs_req;
 
 	/* write size / packets */
-	writel(epsize, hsotg->regs + epsize_reg);
+	dwc2_writel(epsize, hsotg->regs + epsize_reg);
 
 	if (using_dma(hsotg) && !continuing) {
 		unsigned int dma_reg;
 
 		/*
 		 * write DMA address to control register, buffer already
-		 * synced by s3c_hsotg_ep_queue().
+		 * synced by dwc2_hsotg_ep_queue().
 		 */
 
 		dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index);
-		writel(ureq->dma, hsotg->regs + dma_reg);
+		dwc2_writel(ureq->dma, hsotg->regs + dma_reg);
 
 		dev_dbg(hsotg->dev, "%s: %pad => 0x%08x\n",
 			__func__, &ureq->dma, dma_reg);
@@ -645,7 +641,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 		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);
+	dwc2_writel(ctrl, hsotg->regs + epctrl_reg);
 
 	/*
 	 * set these, it seems that DMA support increments past the end
@@ -659,7 +655,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 		/* set these anyway, we may need them for non-periodic in */
 		hs_ep->fifo_load = 0;
 
-		s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req);
+		dwc2_hsotg_write_fifo(hsotg, hs_ep, hs_req);
 	}
 
 	/*
@@ -667,7 +663,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	 * to debugging to see what is going on.
 	 */
 	if (dir_in)
-		writel(DIEPMSK_INTKNTXFEMPMSK,
+		dwc2_writel(DIEPMSK_INTKNTXFEMPMSK,
 		       hsotg->regs + DIEPINT(index));
 
 	/*
@@ -676,20 +672,20 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
 	 */
 
 	/* check ep is enabled */
-	if (!(readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA))
+	if (!(dwc2_readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA))
 		dev_dbg(hsotg->dev,
 			 "ep%d: failed to become enabled (DXEPCTL=0x%08x)?\n",
-			 index, readl(hsotg->regs + epctrl_reg));
+			 index, dwc2_readl(hsotg->regs + epctrl_reg));
 
 	dev_dbg(hsotg->dev, "%s: DXEPCTL=0x%08x\n",
-		__func__, readl(hsotg->regs + epctrl_reg));
+		__func__, dwc2_readl(hsotg->regs + epctrl_reg));
 
 	/* enable ep interrupts */
-	s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1);
 }
 
 /**
- * s3c_hsotg_map_dma - map the DMA memory being used for the request
+ * dwc2_hsotg_map_dma - map the DMA memory being used for the request
  * @hsotg: The device state.
  * @hs_ep: The endpoint the request is on.
  * @req: The request being processed.
@@ -700,11 +696,11 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg,
  * 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 dwc2_hsotg *hsotg,
-			     struct s3c_hsotg_ep *hs_ep,
+static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg,
+			     struct dwc2_hsotg_ep *hs_ep,
 			     struct usb_request *req)
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
 	int ret;
 
 	/* if the length is zero, ignore the DMA data */
@@ -724,8 +720,8 @@ static int s3c_hsotg_map_dma(struct dwc2_hsotg *hsotg,
 	return -EIO;
 }
 
-static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
-	struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req)
+static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
+	struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req)
 {
 	void *req_buf = hs_req->req.buf;
 
@@ -755,8 +751,8 @@ static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg,
 	return 0;
 }
 
-static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
-	struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req)
+static void dwc2_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
+	struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req)
 {
 	/* If dma is not being used or buffer was aligned */
 	if (!using_dma(hsotg) || !hs_req->saved_req_buf)
@@ -777,11 +773,11 @@ static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg,
 	hs_req->saved_req_buf = NULL;
 }
 
-static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
+static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
 			      gfp_t gfp_flags)
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	bool first;
 	int ret;
@@ -802,13 +798,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
 	req->actual = 0;
 	req->status = -EINPROGRESS;
 
-	ret = s3c_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req);
+	ret = dwc2_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req);
 	if (ret)
 		return ret;
 
 	/* if we're using DMA, sync the buffers as necessary */
 	if (using_dma(hs)) {
-		ret = s3c_hsotg_map_dma(hs, hs_ep, req);
+		ret = dwc2_hsotg_map_dma(hs, hs_ep, req);
 		if (ret)
 			return ret;
 	}
@@ -817,51 +813,51 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
 	list_add_tail(&hs_req->queue, &hs_ep->queue);
 
 	if (first)
-		s3c_hsotg_start_req(hs, hs_ep, hs_req, false);
+		dwc2_hsotg_start_req(hs, hs_ep, hs_req, false);
 
 	return 0;
 }
 
-static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req,
+static int dwc2_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req,
 			      gfp_t gfp_flags)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	unsigned long flags = 0;
 	int ret = 0;
 
 	spin_lock_irqsave(&hs->lock, flags);
-	ret = s3c_hsotg_ep_queue(ep, req, gfp_flags);
+	ret = dwc2_hsotg_ep_queue(ep, req, gfp_flags);
 	spin_unlock_irqrestore(&hs->lock, flags);
 
 	return ret;
 }
 
-static void s3c_hsotg_ep_free_request(struct usb_ep *ep,
+static void dwc2_hsotg_ep_free_request(struct usb_ep *ep,
 				      struct usb_request *req)
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
 
 	kfree(hs_req);
 }
 
 /**
- * s3c_hsotg_complete_oursetup - setup completion callback
+ * dwc2_hsotg_complete_oursetup - setup completion callback
  * @ep: The endpoint the request was on.
  * @req: The request completed.
  *
  * Called on completion of any requests the driver itself
  * submitted that need cleaning up.
  */
-static void s3c_hsotg_complete_oursetup(struct usb_ep *ep,
+static void dwc2_hsotg_complete_oursetup(struct usb_ep *ep,
 					struct usb_request *req)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 
 	dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req);
 
-	s3c_hsotg_ep_free_request(ep, req);
+	dwc2_hsotg_ep_free_request(ep, req);
 }
 
 /**
@@ -872,10 +868,10 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep,
  * 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 dwc2_hsotg *hsotg,
+static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
 					   u32 windex)
 {
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep;
 	int dir = (windex & USB_DIR_IN) ? 1 : 0;
 	int idx = windex & 0x7F;
 
@@ -894,14 +890,14 @@ static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg,
 }
 
 /**
- * s3c_hsotg_set_test_mode - Enable usb Test Modes
+ * dwc2_hsotg_set_test_mode - Enable usb Test Modes
  * @hsotg: The driver state.
  * @testmode: requested usb test mode
  * Enable usb Test Mode requested by the Host.
  */
-int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
+int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
 {
-	int dctl = readl(hsotg->regs + DCTL);
+	int dctl = dwc2_readl(hsotg->regs + DCTL);
 
 	dctl &= ~DCTL_TSTCTL_MASK;
 	switch (testmode) {
@@ -915,12 +911,12 @@ int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
 	default:
 		return -EINVAL;
 	}
-	writel(dctl, hsotg->regs + DCTL);
+	dwc2_writel(dctl, hsotg->regs + DCTL);
 	return 0;
 }
 
 /**
- * s3c_hsotg_send_reply - send reply to control request
+ * dwc2_hsotg_send_reply - send reply to control request
  * @hsotg: The device state
  * @ep: Endpoint 0
  * @buff: Buffer for request
@@ -929,8 +925,8 @@ int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode)
  * Create a request and queue it on the given endpoint. This is useful as
  * an internal method of sending replies to certain control requests, etc.
  */
-static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
-				struct s3c_hsotg_ep *ep,
+static int dwc2_hsotg_send_reply(struct dwc2_hsotg *hsotg,
+				struct dwc2_hsotg_ep *ep,
 				void *buff,
 				int length)
 {
@@ -939,7 +935,7 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
 
 	dev_dbg(hsotg->dev, "%s: buff %p, len %d\n", __func__, buff, length);
 
-	req = s3c_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC);
+	req = dwc2_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC);
 	hsotg->ep0_reply = req;
 	if (!req) {
 		dev_warn(hsotg->dev, "%s: cannot alloc req\n", __func__);
@@ -953,12 +949,12 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
 	 * STATUS stage.
 	 */
 	req->zero = 0;
-	req->complete = s3c_hsotg_complete_oursetup;
+	req->complete = dwc2_hsotg_complete_oursetup;
 
 	if (length)
 		memcpy(req->buf, buff, length);
 
-	ret = s3c_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC);
+	ret = dwc2_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC);
 	if (ret) {
 		dev_warn(hsotg->dev, "%s: cannot queue req\n", __func__);
 		return ret;
@@ -968,15 +964,15 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg,
 }
 
 /**
- * s3c_hsotg_process_req_status - process request GET_STATUS
+ * dwc2_hsotg_process_req_status - process request GET_STATUS
  * @hsotg: The device state
  * @ctrl: USB control request
  */
-static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
+static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
 					struct usb_ctrlrequest *ctrl)
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_ep *ep;
 	__le16 reply;
 	int ret;
 
@@ -1013,7 +1009,7 @@ static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
 	if (le16_to_cpu(ctrl->wLength) != 2)
 		return -EINVAL;
 
-	ret = s3c_hsotg_send_reply(hsotg, ep0, &reply, 2);
+	ret = dwc2_hsotg_send_reply(hsotg, ep0, &reply, 2);
 	if (ret) {
 		dev_err(hsotg->dev, "%s: failed to send reply\n", __func__);
 		return ret;
@@ -1022,7 +1018,7 @@ static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg,
 	return 1;
 }
 
-static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value);
+static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value);
 
 /**
  * get_ep_head - return the first request on the endpoint
@@ -1030,27 +1026,27 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value);
  *
  * Get the first request on the endpoint.
  */
-static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep)
+static struct dwc2_hsotg_req *get_ep_head(struct dwc2_hsotg_ep *hs_ep)
 {
 	if (list_empty(&hs_ep->queue))
 		return NULL;
 
-	return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue);
+	return list_first_entry(&hs_ep->queue, struct dwc2_hsotg_req, queue);
 }
 
 /**
- * s3c_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE
+ * dwc2_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE
  * @hsotg: The device state
  * @ctrl: USB control request
  */
-static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
+static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 					 struct usb_ctrlrequest *ctrl)
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
-	struct s3c_hsotg_req *hs_req;
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_req *hs_req;
 	bool restart;
 	bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep;
 	int ret;
 	bool halted;
 	u32 recip;
@@ -1074,7 +1070,7 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 				return -EINVAL;
 
 			hsotg->test_mode = wIndex >> 8;
-			ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+			ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
 			if (ret) {
 				dev_err(hsotg->dev,
 					"%s: failed to send reply\n", __func__);
@@ -1098,9 +1094,9 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 		case USB_ENDPOINT_HALT:
 			halted = ep->halted;
 
-			s3c_hsotg_ep_sethalt(&ep->ep, set);
+			dwc2_hsotg_ep_sethalt(&ep->ep, set);
 
-			ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+			ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
 			if (ret) {
 				dev_err(hsotg->dev,
 					"%s: failed to send reply\n", __func__);
@@ -1134,7 +1130,7 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 					restart = !list_empty(&ep->queue);
 					if (restart) {
 						hs_req = get_ep_head(ep);
-						s3c_hsotg_start_req(hsotg, ep,
+						dwc2_hsotg_start_req(hsotg, ep,
 								hs_req, false);
 					}
 				}
@@ -1152,17 +1148,17 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
 	return 1;
 }
 
-static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg);
+static void dwc2_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg);
 
 /**
- * s3c_hsotg_stall_ep0 - stall ep0
+ * dwc2_hsotg_stall_ep0 - stall ep0
  * @hsotg: The device state
  *
  * Set stall for ep0 as response for setup request.
  */
-static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
 	u32 reg;
 	u32 ctrl;
 
@@ -1174,24 +1170,24 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
 	 * taken effect, so no need to clear later.
 	 */
 
-	ctrl = readl(hsotg->regs + reg);
+	ctrl = dwc2_readl(hsotg->regs + reg);
 	ctrl |= DXEPCTL_STALL;
 	ctrl |= DXEPCTL_CNAK;
-	writel(ctrl, hsotg->regs + reg);
+	dwc2_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));
+		ctrl, reg, dwc2_readl(hsotg->regs + reg));
 
 	 /*
 	  * complete won't be called, so we enqueue
 	  * setup request here
 	  */
-	 s3c_hsotg_enqueue_setup(hsotg);
+	 dwc2_hsotg_enqueue_setup(hsotg);
 }
 
 /**
- * s3c_hsotg_process_control - process a control request
+ * dwc2_hsotg_process_control - process a control request
  * @hsotg: The device state
  * @ctrl: The control request received
  *
@@ -1199,16 +1195,17 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg)
  * needs to work out what to do next (and whether to pass it on to the
  * gadget driver).
  */
-static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
+static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg,
 				      struct usb_ctrlrequest *ctrl)
 {
-	struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0];
+	struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0];
 	int ret = 0;
 	u32 dcfg;
 
-	dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n",
-		 ctrl->bRequest, ctrl->bRequestType,
-		 ctrl->wValue, ctrl->wLength);
+	dev_dbg(hsotg->dev,
+		"ctrl Type=%02x, Req=%02x, V=%04x, I=%04x, L=%04x\n",
+		ctrl->bRequestType, ctrl->bRequest, ctrl->wValue,
+		ctrl->wIndex, ctrl->wLength);
 
 	if (ctrl->wLength == 0) {
 		ep0->dir_in = 1;
@@ -1225,24 +1222,24 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
 		switch (ctrl->bRequest) {
 		case USB_REQ_SET_ADDRESS:
 			hsotg->connected = 1;
-			dcfg = readl(hsotg->regs + DCFG);
+			dcfg = dwc2_readl(hsotg->regs + DCFG);
 			dcfg &= ~DCFG_DEVADDR_MASK;
 			dcfg |= (le16_to_cpu(ctrl->wValue) <<
 				 DCFG_DEVADDR_SHIFT) & DCFG_DEVADDR_MASK;
-			writel(dcfg, hsotg->regs + DCFG);
+			dwc2_writel(dcfg, hsotg->regs + DCFG);
 
 			dev_info(hsotg->dev, "new address %d\n", ctrl->wValue);
 
-			ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0);
+			ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
 			return;
 
 		case USB_REQ_GET_STATUS:
-			ret = s3c_hsotg_process_req_status(hsotg, ctrl);
+			ret = dwc2_hsotg_process_req_status(hsotg, ctrl);
 			break;
 
 		case USB_REQ_CLEAR_FEATURE:
 		case USB_REQ_SET_FEATURE:
-			ret = s3c_hsotg_process_req_feature(hsotg, ctrl);
+			ret = dwc2_hsotg_process_req_feature(hsotg, ctrl);
 			break;
 		}
 	}
@@ -1263,21 +1260,21 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
 	 */
 
 	if (ret < 0)
-		s3c_hsotg_stall_ep0(hsotg);
+		dwc2_hsotg_stall_ep0(hsotg);
 }
 
 /**
- * s3c_hsotg_complete_setup - completion of a setup transfer
+ * dwc2_hsotg_complete_setup - completion of a setup transfer
  * @ep: The endpoint the request was on.
  * @req: The request completed.
  *
  * Called on completion of any requests the driver itself submitted for
  * EP0 setup packets
  */
-static void s3c_hsotg_complete_setup(struct usb_ep *ep,
+static void dwc2_hsotg_complete_setup(struct usb_ep *ep,
 				     struct usb_request *req)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 
 	if (req->status < 0) {
@@ -1287,23 +1284,23 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep,
 
 	spin_lock(&hsotg->lock);
 	if (req->actual == 0)
-		s3c_hsotg_enqueue_setup(hsotg);
+		dwc2_hsotg_enqueue_setup(hsotg);
 	else
-		s3c_hsotg_process_control(hsotg, req->buf);
+		dwc2_hsotg_process_control(hsotg, req->buf);
 	spin_unlock(&hsotg->lock);
 }
 
 /**
- * s3c_hsotg_enqueue_setup - start a request for EP0 packets
+ * dwc2_hsotg_enqueue_setup - start a request for EP0 packets
  * @hsotg: The device state.
  *
  * Enqueue a request on EP0 if necessary to received any SETUP packets
  * received from the host.
  */
-static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 {
 	struct usb_request *req = hsotg->ctrl_req;
-	struct s3c_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
 	int ret;
 
 	dev_dbg(hsotg->dev, "%s: queueing setup request\n", __func__);
@@ -1311,7 +1308,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 	req->zero = 0;
 	req->length = 8;
 	req->buf = hsotg->ctrl_buff;
-	req->complete = s3c_hsotg_complete_setup;
+	req->complete = dwc2_hsotg_complete_setup;
 
 	if (!list_empty(&hs_req->queue)) {
 		dev_dbg(hsotg->dev, "%s already queued???\n", __func__);
@@ -1322,7 +1319,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 	hsotg->eps_out[0]->send_zlp = 0;
 	hsotg->ep0_state = DWC2_EP0_SETUP;
 
-	ret = s3c_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC);
+	ret = dwc2_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC);
 	if (ret < 0) {
 		dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret);
 		/*
@@ -1332,8 +1329,8 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg)
 	}
 }
 
-static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
-					struct s3c_hsotg_ep *hs_ep)
+static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
+					struct dwc2_hsotg_ep *hs_ep)
 {
 	u32 ctrl;
 	u8 index = hs_ep->index;
@@ -1347,19 +1344,19 @@ static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
 		dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n",
 									index);
 
-	writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
-			DXEPTSIZ_XFERSIZE(0), hsotg->regs +
-			epsiz_reg);
+	dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
+		    DXEPTSIZ_XFERSIZE(0), hsotg->regs +
+		    epsiz_reg);
 
-	ctrl = readl(hsotg->regs + epctl_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctl_reg);
 	ctrl |= DXEPCTL_CNAK;  /* clear NAK set by core */
 	ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */
 	ctrl |= DXEPCTL_USBACTEP;
-	writel(ctrl, hsotg->regs + epctl_reg);
+	dwc2_writel(ctrl, hsotg->regs + epctl_reg);
 }
 
 /**
- * s3c_hsotg_complete_request - complete a request given to us
+ * dwc2_hsotg_complete_request - complete a request given to us
  * @hsotg: The device state.
  * @hs_ep: The endpoint the request was on.
  * @hs_req: The request to complete.
@@ -1371,9 +1368,9 @@ static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg,
  *
  * Note, expects the ep to already be locked as appropriate.
  */
-static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
-				       struct s3c_hsotg_ep *hs_ep,
-				       struct s3c_hsotg_req *hs_req,
+static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg,
+				       struct dwc2_hsotg_ep *hs_ep,
+				       struct dwc2_hsotg_req *hs_req,
 				       int result)
 {
 	bool restart;
@@ -1394,14 +1391,14 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
 	if (hs_req->req.status == -EINPROGRESS)
 		hs_req->req.status = result;
 
-	s3c_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req);
+	if (using_dma(hsotg))
+		dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req);
+
+	dwc2_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req);
 
 	hs_ep->req = NULL;
 	list_del_init(&hs_req->queue);
 
-	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.
@@ -1423,13 +1420,13 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
 		restart = !list_empty(&hs_ep->queue);
 		if (restart) {
 			hs_req = get_ep_head(hs_ep);
-			s3c_hsotg_start_req(hsotg, hs_ep, hs_req, false);
+			dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, false);
 		}
 	}
 }
 
 /**
- * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint
+ * dwc2_hsotg_rx_data - receive data from the FIFO for an endpoint
  * @hsotg: The device state.
  * @ep_idx: The endpoint index for the data
  * @size: The size of data in the fifo, in bytes
@@ -1438,10 +1435,10 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg,
  * endpoint, so sort out whether we need to read the data into a request
  * that has been made for that endpoint.
  */
-static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
+static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 {
-	struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx];
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
+	struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx];
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
 	void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx);
 	int to_read;
 	int max_req;
@@ -1449,7 +1446,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 
 
 	if (!hs_req) {
-		u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx));
+		u32 epctl = dwc2_readl(hsotg->regs + DOEPCTL(ep_idx));
 		int ptr;
 
 		dev_dbg(hsotg->dev,
@@ -1458,7 +1455,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 
 		/* dump the data from the FIFO, we've nothing we can do */
 		for (ptr = 0; ptr < size; ptr += 4)
-			(void)readl(fifo);
+			(void)dwc2_readl(fifo);
 
 		return;
 	}
@@ -1492,7 +1489,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
 }
 
 /**
- * s3c_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint
+ * dwc2_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint
  * @hsotg: The device instance
  * @dir_in: If IN zlp
  *
@@ -1503,17 +1500,30 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size)
  * currently believed that we do not need to wait for any space in
  * the TxFIFO.
  */
-static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
+static void dwc2_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
 {
 	/* eps_out[0] is used in both directions */
 	hsotg->eps_out[0]->dir_in = dir_in;
 	hsotg->ep0_state = dir_in ? DWC2_EP0_STATUS_IN : DWC2_EP0_STATUS_OUT;
 
-	s3c_hsotg_program_zlp(hsotg, hsotg->eps_out[0]);
+	dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]);
+}
+
+static void dwc2_hsotg_change_ep_iso_parity(struct dwc2_hsotg *hsotg,
+			u32 epctl_reg)
+{
+	u32 ctrl;
+
+	ctrl = dwc2_readl(hsotg->regs + epctl_reg);
+	if (ctrl & DXEPCTL_EOFRNUM)
+		ctrl |= DXEPCTL_SETEVENFR;
+	else
+		ctrl |= DXEPCTL_SETODDFR;
+	dwc2_writel(ctrl, hsotg->regs + epctl_reg);
 }
 
 /**
- * s3c_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO
+ * dwc2_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO
  * @hsotg: The device instance
  * @epnum: The endpoint received from
  *
@@ -1521,11 +1531,11 @@ static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in)
  * 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 dwc2_hsotg *hsotg, int epnum)
+static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 {
-	u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum));
-	struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[epnum];
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
+	u32 epsize = dwc2_readl(hsotg->regs + DOEPTSIZ(epnum));
+	struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[epnum];
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
 	struct usb_request *req = &hs_req->req;
 	unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize);
 	int result = 0;
@@ -1537,8 +1547,8 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 
 	if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_OUT) {
 		dev_dbg(hsotg->dev, "zlp packet received\n");
-		s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
-		s3c_hsotg_enqueue_setup(hsotg);
+		dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
+		dwc2_hsotg_enqueue_setup(hsotg);
 		return;
 	}
 
@@ -1562,7 +1572,7 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 
 	/* if there is more request to do, schedule new transfer */
 	if (req->actual < req->length && size_left == 0) {
-		s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true);
+		dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, true);
 		return;
 	}
 
@@ -1578,24 +1588,34 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum)
 
 	if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_DATA_OUT) {
 		/* Move to STATUS IN */
-		s3c_hsotg_ep0_zlp(hsotg, true);
+		dwc2_hsotg_ep0_zlp(hsotg, true);
 		return;
 	}
 
-	s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
+	/*
+	 * Slave mode OUT transfers do not go through XferComplete so
+	 * adjust the ISOC parity here.
+	 */
+	if (!using_dma(hsotg)) {
+		hs_ep->has_correct_parity = 1;
+		if (hs_ep->isochronous && hs_ep->interval == 1)
+			dwc2_hsotg_change_ep_iso_parity(hsotg, DOEPCTL(epnum));
+	}
+
+	dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
 }
 
 /**
- * s3c_hsotg_read_frameno - read current frame number
+ * dwc2_hsotg_read_frameno - read current frame number
  * @hsotg: The device instance
  *
  * Return the current frame number
  */
-static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
+static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
 {
 	u32 dsts;
 
-	dsts = readl(hsotg->regs + DSTS);
+	dsts = dwc2_readl(hsotg->regs + DSTS);
 	dsts &= DSTS_SOFFN_MASK;
 	dsts >>= DSTS_SOFFN_SHIFT;
 
@@ -1603,7 +1623,7 @@ static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
 }
 
 /**
- * s3c_hsotg_handle_rx - RX FIFO has data
+ * dwc2_hsotg_handle_rx - RX FIFO has data
  * @hsotg: The device instance
  *
  * The IRQ handler has detected that the RX FIFO has some data in it
@@ -1618,9 +1638,9 @@ static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg)
  * as the actual data should be sent to the memory directly and we turn
  * on the completion interrupts to get notifications of transfer completion.
  */
-static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
 {
-	u32 grxstsr = readl(hsotg->regs + GRXSTSP);
+	u32 grxstsr = dwc2_readl(hsotg->regs + GRXSTSP);
 	u32 epnum, status, size;
 
 	WARN_ON(using_dma(hsotg));
@@ -1641,55 +1661,55 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg)
 
 	case GRXSTS_PKTSTS_OUTDONE:
 		dev_dbg(hsotg->dev, "OutDone (Frame=0x%08x)\n",
-			s3c_hsotg_read_frameno(hsotg));
+			dwc2_hsotg_read_frameno(hsotg));
 
 		if (!using_dma(hsotg))
-			s3c_hsotg_handle_outdone(hsotg, epnum);
+			dwc2_hsotg_handle_outdone(hsotg, epnum);
 		break;
 
 	case GRXSTS_PKTSTS_SETUPDONE:
 		dev_dbg(hsotg->dev,
 			"SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
-			s3c_hsotg_read_frameno(hsotg),
-			readl(hsotg->regs + DOEPCTL(0)));
+			dwc2_hsotg_read_frameno(hsotg),
+			dwc2_readl(hsotg->regs + DOEPCTL(0)));
 		/*
-		 * Call s3c_hsotg_handle_outdone here if it was not called from
+		 * Call dwc2_hsotg_handle_outdone here if it was not called from
 		 * GRXSTS_PKTSTS_OUTDONE. That is, if the core didn't
 		 * generate GRXSTS_PKTSTS_OUTDONE for setup packet.
 		 */
 		if (hsotg->ep0_state == DWC2_EP0_SETUP)
-			s3c_hsotg_handle_outdone(hsotg, epnum);
+			dwc2_hsotg_handle_outdone(hsotg, epnum);
 		break;
 
 	case GRXSTS_PKTSTS_OUTRX:
-		s3c_hsotg_rx_data(hsotg, epnum, size);
+		dwc2_hsotg_rx_data(hsotg, epnum, size);
 		break;
 
 	case GRXSTS_PKTSTS_SETUPRX:
 		dev_dbg(hsotg->dev,
 			"SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n",
-			s3c_hsotg_read_frameno(hsotg),
-			readl(hsotg->regs + DOEPCTL(0)));
+			dwc2_hsotg_read_frameno(hsotg),
+			dwc2_readl(hsotg->regs + DOEPCTL(0)));
 
 		WARN_ON(hsotg->ep0_state != DWC2_EP0_SETUP);
 
-		s3c_hsotg_rx_data(hsotg, epnum, size);
+		dwc2_hsotg_rx_data(hsotg, epnum, size);
 		break;
 
 	default:
 		dev_warn(hsotg->dev, "%s: unknown status %08x\n",
 			 __func__, grxstsr);
 
-		s3c_hsotg_dump(hsotg);
+		dwc2_hsotg_dump(hsotg);
 		break;
 	}
 }
 
 /**
- * s3c_hsotg_ep0_mps - turn max packet size into register setting
+ * dwc2_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)
+static u32 dwc2_hsotg_ep0_mps(unsigned int mps)
 {
 	switch (mps) {
 	case 64:
@@ -1708,7 +1728,7 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps)
 }
 
 /**
- * s3c_hsotg_set_ep_maxpacket - set endpoint's max-packet field
+ * dwc2_hsotg_set_ep_maxpacket - set endpoint's max-packet field
  * @hsotg: The driver state.
  * @ep: The index number of the endpoint
  * @mps: The maximum packet size in bytes
@@ -1716,10 +1736,10 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps)
  * Configure the maximum packet size for the given endpoint, updating
  * the hardware control registers to reflect this.
  */
-static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
+static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 			unsigned int ep, unsigned int mps, unsigned int dir_in)
 {
-	struct s3c_hsotg_ep *hs_ep;
+	struct dwc2_hsotg_ep *hs_ep;
 	void __iomem *regs = hsotg->regs;
 	u32 mpsval;
 	u32 mcval;
@@ -1731,7 +1751,7 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 
 	if (ep == 0) {
 		/* EP0 is a special case */
-		mpsval = s3c_hsotg_ep0_mps(mps);
+		mpsval = dwc2_hsotg_ep0_mps(mps);
 		if (mpsval > 3)
 			goto bad_mps;
 		hs_ep->ep.maxpacket = mps;
@@ -1748,15 +1768,15 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 	}
 
 	if (dir_in) {
-		reg = readl(regs + DIEPCTL(ep));
+		reg = dwc2_readl(regs + DIEPCTL(ep));
 		reg &= ~DXEPCTL_MPS_MASK;
 		reg |= mpsval;
-		writel(reg, regs + DIEPCTL(ep));
+		dwc2_writel(reg, regs + DIEPCTL(ep));
 	} else {
-		reg = readl(regs + DOEPCTL(ep));
+		reg = dwc2_readl(regs + DOEPCTL(ep));
 		reg &= ~DXEPCTL_MPS_MASK;
 		reg |= mpsval;
-		writel(reg, regs + DOEPCTL(ep));
+		dwc2_writel(reg, regs + DOEPCTL(ep));
 	}
 
 	return;
@@ -1766,23 +1786,23 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
 }
 
 /**
- * s3c_hsotg_txfifo_flush - flush Tx FIFO
+ * dwc2_hsotg_txfifo_flush - flush Tx FIFO
  * @hsotg: The driver state
  * @idx: The index for the endpoint (0..15)
  */
-static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
+static void dwc2_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
 {
 	int timeout;
 	int val;
 
-	writel(GRSTCTL_TXFNUM(idx) | GRSTCTL_TXFFLSH,
-		hsotg->regs + GRSTCTL);
+	dwc2_writel(GRSTCTL_TXFNUM(idx) | GRSTCTL_TXFFLSH,
+		    hsotg->regs + GRSTCTL);
 
 	/* wait until the fifo is flushed */
 	timeout = 100;
 
 	while (1) {
-		val = readl(hsotg->regs + GRSTCTL);
+		val = dwc2_readl(hsotg->regs + GRSTCTL);
 
 		if ((val & (GRSTCTL_TXFFLSH)) == 0)
 			break;
@@ -1799,17 +1819,17 @@ static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx)
 }
 
 /**
- * s3c_hsotg_trytx - check to see if anything needs transmitting
+ * dwc2_hsotg_trytx - check to see if anything needs transmitting
  * @hsotg: The driver state
  * @hs_ep: The driver endpoint to check.
  *
  * Check to see if there is a request that has data to send, and if so
  * make an attempt to write data into the FIFO.
  */
-static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
-			   struct s3c_hsotg_ep *hs_ep)
+static int dwc2_hsotg_trytx(struct dwc2_hsotg *hsotg,
+			   struct dwc2_hsotg_ep *hs_ep)
 {
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
 
 	if (!hs_ep->dir_in || !hs_req) {
 		/**
@@ -1817,7 +1837,7 @@ static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
 		 * for endpoints, excepting ep0
 		 */
 		if (hs_ep->index != 0)
-			s3c_hsotg_ctrl_epint(hsotg, hs_ep->index,
+			dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index,
 					     hs_ep->dir_in, 0);
 		return 0;
 	}
@@ -1825,25 +1845,25 @@ static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg,
 	if (hs_req->req.actual < hs_req->req.length) {
 		dev_dbg(hsotg->dev, "trying to write more for ep%d\n",
 			hs_ep->index);
-		return s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req);
+		return dwc2_hsotg_write_fifo(hsotg, hs_ep, hs_req);
 	}
 
 	return 0;
 }
 
 /**
- * s3c_hsotg_complete_in - complete IN transfer
+ * dwc2_hsotg_complete_in - complete IN transfer
  * @hsotg: The device state.
  * @hs_ep: The endpoint that has just completed.
  *
  * An IN transfer has been completed, update the transfer's state and then
  * call the relevant completion routines.
  */
-static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
-				  struct s3c_hsotg_ep *hs_ep)
+static void dwc2_hsotg_complete_in(struct dwc2_hsotg *hsotg,
+				  struct dwc2_hsotg_ep *hs_ep)
 {
-	struct s3c_hsotg_req *hs_req = hs_ep->req;
-	u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
+	struct dwc2_hsotg_req *hs_req = hs_ep->req;
+	u32 epsize = dwc2_readl(hsotg->regs + DIEPTSIZ(hs_ep->index));
 	int size_left, size_done;
 
 	if (!hs_req) {
@@ -1854,19 +1874,19 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
 	/* Finish ZLP handling for IN EP0 transactions */
 	if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_IN) {
 		dev_dbg(hsotg->dev, "zlp packet sent\n");
-		s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
+		dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
 		if (hsotg->test_mode) {
 			int ret;
 
-			ret = s3c_hsotg_set_test_mode(hsotg, hsotg->test_mode);
+			ret = dwc2_hsotg_set_test_mode(hsotg, hsotg->test_mode);
 			if (ret < 0) {
 				dev_dbg(hsotg->dev, "Invalid Test #%d\n",
 						hsotg->test_mode);
-				s3c_hsotg_stall_ep0(hsotg);
+				dwc2_hsotg_stall_ep0(hsotg);
 				return;
 			}
 		}
-		s3c_hsotg_enqueue_setup(hsotg);
+		dwc2_hsotg_enqueue_setup(hsotg);
 		return;
 	}
 
@@ -1895,13 +1915,13 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
 
 	if (!size_left && hs_req->req.actual < hs_req->req.length) {
 		dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__);
-		s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true);
+		dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, true);
 		return;
 	}
 
 	/* Zlp for all endpoints, for ep0 only in DATA IN stage */
 	if (hs_ep->send_zlp) {
-		s3c_hsotg_program_zlp(hsotg, hs_ep);
+		dwc2_hsotg_program_zlp(hsotg, hs_ep);
 		hs_ep->send_zlp = 0;
 		/* transfer will be completed on next complete interrupt */
 		return;
@@ -1909,36 +1929,36 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg,
 
 	if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) {
 		/* Move to STATUS OUT */
-		s3c_hsotg_ep0_zlp(hsotg, false);
+		dwc2_hsotg_ep0_zlp(hsotg, false);
 		return;
 	}
 
-	s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
+	dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
 }
 
 /**
- * s3c_hsotg_epint - handle an in/out endpoint interrupt
+ * dwc2_hsotg_epint - handle an in/out endpoint interrupt
  * @hsotg: The driver state
  * @idx: The index for the endpoint (0..15)
  * @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 dwc2_hsotg *hsotg, unsigned int idx,
+static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 			    int dir_in)
 {
-	struct s3c_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in);
+	struct dwc2_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in);
 	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;
 	u32 ctrl;
 
-	ints = readl(hsotg->regs + epint_reg);
-	ctrl = readl(hsotg->regs + epctl_reg);
+	ints = dwc2_readl(hsotg->regs + epint_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctl_reg);
 
 	/* Clear endpoint interrupts */
-	writel(ints, hsotg->regs + epint_reg);
+	dwc2_writel(ints, hsotg->regs + epint_reg);
 
 	if (!hs_ep) {
 		dev_err(hsotg->dev, "%s:Interrupt for unconfigured ep%d(%s)\n",
@@ -1954,35 +1974,31 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 		ints &= ~DXEPINT_XFERCOMPL;
 
 	if (ints & DXEPINT_XFERCOMPL) {
-		if (hs_ep->isochronous && hs_ep->interval == 1) {
-			if (ctrl & DXEPCTL_EOFRNUM)
-				ctrl |= DXEPCTL_SETEVENFR;
-			else
-				ctrl |= DXEPCTL_SETODDFR;
-			writel(ctrl, hsotg->regs + epctl_reg);
-		}
+		hs_ep->has_correct_parity = 1;
+		if (hs_ep->isochronous && hs_ep->interval == 1)
+			dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
 
 		dev_dbg(hsotg->dev,
 			"%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n",
-			__func__, readl(hsotg->regs + epctl_reg),
-			readl(hsotg->regs + epsiz_reg));
+			__func__, dwc2_readl(hsotg->regs + epctl_reg),
+			dwc2_readl(hsotg->regs + epsiz_reg));
 
 		/*
 		 * 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);
+			dwc2_hsotg_complete_in(hsotg, hs_ep);
 
 			if (idx == 0 && !hs_ep->req)
-				s3c_hsotg_enqueue_setup(hsotg);
+				dwc2_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.
 			 */
 
-			s3c_hsotg_handle_outdone(hsotg, idx);
+			dwc2_hsotg_handle_outdone(hsotg, idx);
 		}
 	}
 
@@ -1990,16 +2006,16 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 		dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__);
 
 		if (dir_in) {
-			int epctl = readl(hsotg->regs + epctl_reg);
+			int epctl = dwc2_readl(hsotg->regs + epctl_reg);
 
-			s3c_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index);
+			dwc2_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index);
 
 			if ((epctl & DXEPCTL_STALL) &&
 				(epctl & DXEPCTL_EPTYPE_BULK)) {
-				int dctl = readl(hsotg->regs + DCTL);
+				int dctl = dwc2_readl(hsotg->regs + DCTL);
 
 				dctl |= DCTL_CGNPINNAK;
-				writel(dctl, hsotg->regs + DCTL);
+				dwc2_writel(dctl, hsotg->regs + DCTL);
 			}
 		}
 	}
@@ -2021,7 +2037,7 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 			if (dir_in)
 				WARN_ON_ONCE(1);
 			else
-				s3c_hsotg_handle_outdone(hsotg, 0);
+				dwc2_hsotg_handle_outdone(hsotg, 0);
 		}
 	}
 
@@ -2047,21 +2063,21 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
 			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
 				__func__, idx);
 			if (!using_dma(hsotg))
-				s3c_hsotg_trytx(hsotg, hs_ep);
+				dwc2_hsotg_trytx(hsotg, hs_ep);
 		}
 	}
 }
 
 /**
- * s3c_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done)
+ * dwc2_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done)
  * @hsotg: The device state.
  *
  * Handle updating the device settings after the enumeration phase has
  * been completed.
  */
-static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
 {
-	u32 dsts = readl(hsotg->regs + DSTS);
+	u32 dsts = dwc2_readl(hsotg->regs + DSTS);
 	int ep0_mps = 0, ep_mps = 8;
 
 	/*
@@ -2113,23 +2129,23 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
 	if (ep0_mps) {
 		int i;
 		/* Initialize ep0 for both in and out directions */
-		s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1);
-		s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0);
+		dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1);
+		dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0);
 		for (i = 1; i < hsotg->num_of_eps; i++) {
 			if (hsotg->eps_in[i])
-				s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1);
+				dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1);
 			if (hsotg->eps_out[i])
-				s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0);
+				dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0);
 		}
 	}
 
 	/* ensure after enumeration our EP0 is active */
 
-	s3c_hsotg_enqueue_setup(hsotg);
+	dwc2_hsotg_enqueue_setup(hsotg);
 
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + DIEPCTL0),
-		readl(hsotg->regs + DOEPCTL0));
+		dwc2_readl(hsotg->regs + DIEPCTL0),
+		dwc2_readl(hsotg->regs + DOEPCTL0));
 }
 
 /**
@@ -2142,34 +2158,34 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
  * completed with the given result code.
  */
 static void kill_all_requests(struct dwc2_hsotg *hsotg,
-			      struct s3c_hsotg_ep *ep,
+			      struct dwc2_hsotg_ep *ep,
 			      int result)
 {
-	struct s3c_hsotg_req *req, *treq;
+	struct dwc2_hsotg_req *req, *treq;
 	unsigned size;
 
 	ep->req = NULL;
 
 	list_for_each_entry_safe(req, treq, &ep->queue, queue)
-		s3c_hsotg_complete_request(hsotg, ep, req,
+		dwc2_hsotg_complete_request(hsotg, ep, req,
 					   result);
 
 	if (!hsotg->dedicated_fifos)
 		return;
-	size = (readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4;
+	size = (dwc2_readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4;
 	if (size < ep->fifo_size)
-		s3c_hsotg_txfifo_flush(hsotg, ep->fifo_index);
+		dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index);
 }
 
 /**
- * s3c_hsotg_disconnect - disconnect service
+ * dwc2_hsotg_disconnect - disconnect service
  * @hsotg: The device state.
  *
  * The device has been disconnected. Remove all current
  * transactions and signal the gadget driver that this
  * has happened.
  */
-void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg)
+void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg)
 {
 	unsigned ep;
 
@@ -2189,16 +2205,17 @@ void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg)
 	}
 
 	call_gadget(hsotg, disconnect);
+	hsotg->lx_state = DWC2_L3;
 }
 
 /**
- * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler
+ * dwc2_hsotg_irq_fifoempty - TX FIFO empty interrupt handler
  * @hsotg: The device state:
  * @periodic: True if this is a periodic FIFO interrupt
  */
-static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
+static void dwc2_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 {
-	struct s3c_hsotg_ep *ep;
+	struct dwc2_hsotg_ep *ep;
 	int epno, ret;
 
 	/* look through for any more data to transmit */
@@ -2215,7 +2232,7 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 		    (!periodic && ep->periodic))
 			continue;
 
-		ret = s3c_hsotg_trytx(hsotg, ep);
+		ret = dwc2_hsotg_trytx(hsotg, ep);
 		if (ret < 0)
 			break;
 	}
@@ -2227,12 +2244,12 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic)
 			GINTSTS_RXFLVL)
 
 /**
- * s3c_hsotg_corereset - issue softreset to the core
+ * dwc2_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 dwc2_hsotg *hsotg)
+static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg)
 {
 	int timeout;
 	u32 grstctl;
@@ -2240,11 +2257,11 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "resetting core\n");
 
 	/* issue soft reset */
-	writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL);
+	dwc2_writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL);
 
 	timeout = 10000;
 	do {
-		grstctl = readl(hsotg->regs + GRSTCTL);
+		grstctl = dwc2_readl(hsotg->regs + GRSTCTL);
 	} while ((grstctl & GRSTCTL_CSFTRST) && timeout-- > 0);
 
 	if (grstctl & GRSTCTL_CSFTRST) {
@@ -2255,7 +2272,7 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
 	timeout = 10000;
 
 	while (1) {
-		u32 grstctl = readl(hsotg->regs + GRSTCTL);
+		u32 grstctl = dwc2_readl(hsotg->regs + GRSTCTL);
 
 		if (timeout-- < 0) {
 			dev_info(hsotg->dev,
@@ -2275,18 +2292,23 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
 }
 
 /**
- * s3c_hsotg_core_init - issue softreset to the core
+ * dwc2_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.
  */
-void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
+void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 						bool is_usb_reset)
 {
+	u32 intmsk;
 	u32 val;
 
+	/* Kill any ep0 requests as controller will be reinitialized */
+	kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
+
 	if (!is_usb_reset)
-		s3c_hsotg_corereset(hsotg);
+		if (dwc2_hsotg_corereset(hsotg))
+			return;
 
 	/*
 	 * we must now enable ep0 ready for host detection and then
@@ -2295,39 +2317,42 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 
 	/* set the PLL on, remove the HNP/SRP and set the PHY */
 	val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-	writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+	dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
 	       (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG);
 
-	s3c_hsotg_init_fifo(hsotg);
+	dwc2_hsotg_init_fifo(hsotg);
 
 	if (!is_usb_reset)
 		__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 
-	writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS,  hsotg->regs + DCFG);
+	dwc2_writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS,  hsotg->regs + DCFG);
 
 	/* Clear any pending OTG interrupts */
-	writel(0xffffffff, hsotg->regs + GOTGINT);
+	dwc2_writel(0xffffffff, hsotg->regs + GOTGINT);
 
 	/* Clear any pending interrupts */
-	writel(0xffffffff, hsotg->regs + GINTSTS);
-
-	writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT |
+	dwc2_writel(0xffffffff, hsotg->regs + GINTSTS);
+	intmsk = GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT |
 		GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF |
-		GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST |
-		GINTSTS_RESETDET | GINTSTS_ENUMDONE |
-		GINTSTS_OTGINT | GINTSTS_USBSUSP |
-		GINTSTS_WKUPINT,
-		hsotg->regs + GINTMSK);
+		GINTSTS_USBRST | GINTSTS_RESETDET |
+		GINTSTS_ENUMDONE | GINTSTS_OTGINT |
+		GINTSTS_USBSUSP | GINTSTS_WKUPINT |
+		GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT;
+
+	if (hsotg->core_params->external_id_pin_ctl <= 0)
+		intmsk |= GINTSTS_CONIDSTSCHNG;
+
+	dwc2_writel(intmsk, hsotg->regs + GINTMSK);
 
 	if (using_dma(hsotg))
-		writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN |
-		       (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT),
-		       hsotg->regs + GAHBCFG);
+		dwc2_writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN |
+			    (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT),
+			    hsotg->regs + GAHBCFG);
 	else
-		writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL |
-						    GAHBCFG_P_TXF_EMP_LVL) : 0) |
-		       GAHBCFG_GLBL_INTR_EN,
-		       hsotg->regs + GAHBCFG);
+		dwc2_writel(((hsotg->dedicated_fifos) ?
+						(GAHBCFG_NP_TXF_EMP_LVL |
+						 GAHBCFG_P_TXF_EMP_LVL) : 0) |
+			    GAHBCFG_GLBL_INTR_EN, hsotg->regs + GAHBCFG);
 
 	/*
 	 * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts
@@ -2335,7 +2360,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 * interrupts.
 	 */
 
-	writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ?
+	dwc2_writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ?
 		DIEPMSK_TXFIFOEMPTY | DIEPMSK_INTKNTXFEMPMSK : 0) |
 		DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK |
 		DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
@@ -2346,20 +2371,20 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 * 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 |
+	dwc2_writel((using_dma(hsotg) ? (DIEPMSK_XFERCOMPLMSK |
 				    DIEPMSK_TIMEOUTMSK) : 0) |
 		DOEPMSK_EPDISBLDMSK | DOEPMSK_AHBERRMSK |
 		DOEPMSK_SETUPMSK,
 		hsotg->regs + DOEPMSK);
 
-	writel(0, hsotg->regs + DAINTMSK);
+	dwc2_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));
+		dwc2_readl(hsotg->regs + DIEPCTL0),
+		dwc2_readl(hsotg->regs + DOEPCTL0));
 
 	/* enable in and out endpoint interrupts */
-	s3c_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT);
+	dwc2_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT);
 
 	/*
 	 * Enable the RXFIFO when in slave mode, as this is how we collect
@@ -2367,11 +2392,11 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 * things we cannot process, so do not use it.
 	 */
 	if (!using_dma(hsotg))
-		s3c_hsotg_en_gsint(hsotg, GINTSTS_RXFLVL);
+		dwc2_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);
+	dwc2_hsotg_ctrl_epint(hsotg, 0, 0, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, 0, 1, 1);
 
 	if (!is_usb_reset) {
 		__orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
@@ -2379,7 +2404,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 		__bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
 	}
 
-	dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL));
+	dev_dbg(hsotg->dev, "DCTL=0x%08x\n", dwc2_readl(hsotg->regs + DCTL));
 
 	/*
 	 * DxEPCTL_USBActEp says RO in manual, but seems to be set by
@@ -2387,23 +2412,23 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	 */
 
 	/* set to read 1 8byte packet */
-	writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
+	dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) |
 	       DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0);
 
-	writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
+	dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[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_out[0]->ep.maxpacket) |
+	dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |
 	       DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0);
 
-	s3c_hsotg_enqueue_setup(hsotg);
+	dwc2_hsotg_enqueue_setup(hsotg);
 
 	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n",
-		readl(hsotg->regs + DIEPCTL0),
-		readl(hsotg->regs + DOEPCTL0));
+		dwc2_readl(hsotg->regs + DIEPCTL0),
+		dwc2_readl(hsotg->regs + DOEPCTL0));
 
 	/* clear global NAKs */
 	val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;
@@ -2414,27 +2439,27 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 	/* must be at-least 3ms to allow bus to see disconnect */
 	mdelay(3);
 
-	hsotg->last_rst = jiffies;
+	hsotg->lx_state = DWC2_L0;
 }
 
-static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)
 {
 	/* set the soft-disconnect bit */
 	__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 }
 
-void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg)
+void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg)
 {
 	/* remove the soft-disconnect and let's go */
 	__bic32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 }
 
 /**
- * s3c_hsotg_irq - handle device interrupt
+ * dwc2_hsotg_irq - handle device interrupt
  * @irq: The IRQ number triggered
  * @pw: The pw value when registered the handler.
  */
-static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
+static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)
 {
 	struct dwc2_hsotg *hsotg = pw;
 	int retry_count = 8;
@@ -2443,49 +2468,18 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 
 	spin_lock(&hsotg->lock);
 irq_retry:
-	gintsts = readl(hsotg->regs + GINTSTS);
-	gintmsk = readl(hsotg->regs + GINTMSK);
+	gintsts = dwc2_readl(hsotg->regs + GINTSTS);
+	gintmsk = dwc2_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 & GINTSTS_ENUMDONE) {
-		writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
-
-		s3c_hsotg_irq_enumdone(hsotg);
-	}
-
-	if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
-		u32 daint = readl(hsotg->regs + DAINT);
-		u32 daintmsk = readl(hsotg->regs + DAINTMSK);
-		u32 daint_out, daint_in;
-		int ep;
-
-		daint &= daintmsk;
-		daint_out = daint >> DAINT_OUTEP_SHIFT;
-		daint_in = daint & ~(daint_out << DAINT_OUTEP_SHIFT);
-
-		dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
-
-		for (ep = 0; ep < hsotg->num_of_eps && daint_out;
-						ep++, daint_out >>= 1) {
-			if (daint_out & 1)
-				s3c_hsotg_epint(hsotg, ep, 0);
-		}
-
-		for (ep = 0; ep < hsotg->num_of_eps  && daint_in;
-						ep++, daint_in >>= 1) {
-			if (daint_in & 1)
-				s3c_hsotg_epint(hsotg, ep, 1);
-		}
-	}
-
 	if (gintsts & GINTSTS_RESETDET) {
 		dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
 
-		writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
+		dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
 
 		/* This event must be used only if controller is suspended */
 		if (hsotg->lx_state == DWC2_L2) {
@@ -2496,27 +2490,50 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 
 	if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
 
-		u32 usb_status = readl(hsotg->regs + GOTGCTL);
+		u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
+		u32 connected = hsotg->connected;
 
 		dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
 		dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
-			readl(hsotg->regs + GNPTXSTS));
+			dwc2_readl(hsotg->regs + GNPTXSTS));
 
-		writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
+		dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
 
 		/* Report disconnection if it is not already done. */
-		s3c_hsotg_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
+
+		if (usb_status & GOTGCTL_BSESVLD && connected)
+			dwc2_hsotg_core_init_disconnected(hsotg, true);
+	}
 
-		if (usb_status & GOTGCTL_BSESVLD) {
-			if (time_after(jiffies, hsotg->last_rst +
-				       msecs_to_jiffies(200))) {
+	if (gintsts & GINTSTS_ENUMDONE) {
+		dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
 
-				kill_all_requests(hsotg, hsotg->eps_out[0],
-							  -ECONNRESET);
+		dwc2_hsotg_irq_enumdone(hsotg);
+	}
 
-				hsotg->lx_state = DWC2_L0;
-				s3c_hsotg_core_init_disconnected(hsotg, true);
-			}
+	if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
+		u32 daint = dwc2_readl(hsotg->regs + DAINT);
+		u32 daintmsk = dwc2_readl(hsotg->regs + DAINTMSK);
+		u32 daint_out, daint_in;
+		int ep;
+
+		daint &= daintmsk;
+		daint_out = daint >> DAINT_OUTEP_SHIFT;
+		daint_in = daint & ~(daint_out << DAINT_OUTEP_SHIFT);
+
+		dev_dbg(hsotg->dev, "%s: daint=%08x\n", __func__, daint);
+
+		for (ep = 0; ep < hsotg->num_of_eps && daint_out;
+						ep++, daint_out >>= 1) {
+			if (daint_out & 1)
+				dwc2_hsotg_epint(hsotg, ep, 0);
+		}
+
+		for (ep = 0; ep < hsotg->num_of_eps  && daint_in;
+						ep++, daint_in >>= 1) {
+			if (daint_in & 1)
+				dwc2_hsotg_epint(hsotg, ep, 1);
 		}
 	}
 
@@ -2531,8 +2548,8 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 		 * it needs re-enabling
 		 */
 
-		s3c_hsotg_disable_gsint(hsotg, GINTSTS_NPTXFEMP);
-		s3c_hsotg_irq_fifoempty(hsotg, false);
+		dwc2_hsotg_disable_gsint(hsotg, GINTSTS_NPTXFEMP);
+		dwc2_hsotg_irq_fifoempty(hsotg, false);
 	}
 
 	if (gintsts & GINTSTS_PTXFEMP) {
@@ -2540,23 +2557,23 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 
 		/* See note in GINTSTS_NPTxFEmp */
 
-		s3c_hsotg_disable_gsint(hsotg, GINTSTS_PTXFEMP);
-		s3c_hsotg_irq_fifoempty(hsotg, true);
+		dwc2_hsotg_disable_gsint(hsotg, GINTSTS_PTXFEMP);
+		dwc2_hsotg_irq_fifoempty(hsotg, true);
 	}
 
 	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
+		 * we need to retry dwc2_hsotg_handle_rx if this is still
 		 * set.
 		 */
 
-		s3c_hsotg_handle_rx(hsotg);
+		dwc2_hsotg_handle_rx(hsotg);
 	}
 
 	if (gintsts & GINTSTS_ERLYSUSP) {
 		dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n");
-		writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS);
+		dwc2_writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS);
 	}
 
 	/*
@@ -2568,17 +2585,51 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 	if (gintsts & GINTSTS_GOUTNAKEFF) {
 		dev_info(hsotg->dev, "GOUTNakEff triggered\n");
 
-		writel(DCTL_CGOUTNAK, hsotg->regs + DCTL);
+		dwc2_writel(DCTL_CGOUTNAK, hsotg->regs + DCTL);
 
-		s3c_hsotg_dump(hsotg);
+		dwc2_hsotg_dump(hsotg);
 	}
 
 	if (gintsts & GINTSTS_GINNAKEFF) {
 		dev_info(hsotg->dev, "GINNakEff triggered\n");
 
-		writel(DCTL_CGNPINNAK, hsotg->regs + DCTL);
+		dwc2_writel(DCTL_CGNPINNAK, hsotg->regs + DCTL);
+
+		dwc2_hsotg_dump(hsotg);
+	}
+
+	if (gintsts & GINTSTS_INCOMPL_SOIN) {
+		u32 idx, epctl_reg;
+		struct dwc2_hsotg_ep *hs_ep;
+
+		dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOIN\n", __func__);
+		for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+			hs_ep = hsotg->eps_in[idx];
+
+			if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+				continue;
+
+			epctl_reg = DIEPCTL(idx);
+			dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+		}
+		dwc2_writel(GINTSTS_INCOMPL_SOIN, hsotg->regs + GINTSTS);
+	}
+
+	if (gintsts & GINTSTS_INCOMPL_SOOUT) {
+		u32 idx, epctl_reg;
+		struct dwc2_hsotg_ep *hs_ep;
 
-		s3c_hsotg_dump(hsotg);
+		dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOOUT\n", __func__);
+		for (idx = 1; idx < hsotg->num_of_eps; idx++) {
+			hs_ep = hsotg->eps_out[idx];
+
+			if (!hs_ep->isochronous || hs_ep->has_correct_parity)
+				continue;
+
+			epctl_reg = DOEPCTL(idx);
+			dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg);
+		}
+		dwc2_writel(GINTSTS_INCOMPL_SOOUT, hsotg->regs + GINTSTS);
 	}
 
 	/*
@@ -2595,16 +2646,16 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw)
 }
 
 /**
- * s3c_hsotg_ep_enable - enable the given endpoint
+ * dwc2_hsotg_ep_enable - enable the given endpoint
  * @ep: The USB endpint to configure
  * @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,
+static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
 			       const struct usb_endpoint_descriptor *desc)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	unsigned long flags;
 	unsigned int index = hs_ep->index;
@@ -2631,10 +2682,10 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 
 	mps = usb_endpoint_maxp(desc);
 
-	/* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */
+	/* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */
 
 	epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
-	epctrl = readl(hsotg->regs + epctrl_reg);
+	epctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n",
 		__func__, epctrl, epctrl_reg);
@@ -2660,13 +2711,14 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 	epctrl |= DXEPCTL_SNAK;
 
 	/* update the endpoint state */
-	s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in);
+	dwc2_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in);
 
 	/* default, set to non-periodic */
 	hs_ep->isochronous = 0;
 	hs_ep->periodic = 0;
 	hs_ep->halted = 0;
 	hs_ep->interval = desc->bInterval;
+	hs_ep->has_correct_parity = 0;
 
 	if (hs_ep->interval > 1 && hs_ep->mc > 1)
 		dev_err(hsotg->dev, "MC > 1 when interval is not 1\n");
@@ -2718,7 +2770,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 		for (i = 1; i < hsotg->num_of_eps; ++i) {
 			if (hsotg->fifo_map & (1<<i))
 				continue;
-			val = readl(hsotg->regs + DPTXFSIZN(i));
+			val = dwc2_readl(hsotg->regs + DPTXFSIZN(i));
 			val = (val >> FIFOSIZE_DEPTH_SHIFT)*4;
 			if (val < size)
 				continue;
@@ -2747,12 +2799,12 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 	dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n",
 		__func__, epctrl);
 
-	writel(epctrl, hsotg->regs + epctrl_reg);
+	dwc2_writel(epctrl, hsotg->regs + epctrl_reg);
 	dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x\n",
-		__func__, readl(hsotg->regs + epctrl_reg));
+		__func__, dwc2_readl(hsotg->regs + epctrl_reg));
 
 	/* enable the endpoint interrupt */
-	s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
+	dwc2_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
 
 error:
 	spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -2760,12 +2812,12 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
 }
 
 /**
- * s3c_hsotg_ep_disable - disable given endpoint
+ * dwc2_hsotg_ep_disable - disable given endpoint
  * @ep: The endpoint to disable.
  */
-static int s3c_hsotg_ep_disable(struct usb_ep *ep)
+static int dwc2_hsotg_ep_disable(struct usb_ep *ep)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hsotg = hs_ep->parent;
 	int dir_in = hs_ep->dir_in;
 	int index = hs_ep->index;
@@ -2788,16 +2840,16 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
 	hs_ep->fifo_index = 0;
 	hs_ep->fifo_size = 0;
 
-	ctrl = readl(hsotg->regs + epctrl_reg);
+	ctrl = dwc2_readl(hsotg->regs + epctrl_reg);
 	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);
+	dwc2_writel(ctrl, hsotg->regs + epctrl_reg);
 
 	/* disable endpoint interrupts */
-	s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0);
+	dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0);
 
 	/* terminate all requests with shutdown */
 	kill_all_requests(hsotg, hs_ep, -ESHUTDOWN);
@@ -2811,9 +2863,9 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
  * @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)
+static bool on_list(struct dwc2_hsotg_ep *ep, struct dwc2_hsotg_req *test)
 {
-	struct s3c_hsotg_req *req, *treq;
+	struct dwc2_hsotg_req *req, *treq;
 
 	list_for_each_entry_safe(req, treq, &ep->queue, queue) {
 		if (req == test)
@@ -2823,15 +2875,88 @@ static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test)
 	return false;
 }
 
+static int dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hs_otg, u32 reg,
+							u32 bit, u32 timeout)
+{
+	u32 i;
+
+	for (i = 0; i < timeout; i++) {
+		if (dwc2_readl(hs_otg->regs + reg) & bit)
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg,
+						struct dwc2_hsotg_ep *hs_ep)
+{
+	u32 epctrl_reg;
+	u32 epint_reg;
+
+	epctrl_reg = hs_ep->dir_in ? DIEPCTL(hs_ep->index) :
+		DOEPCTL(hs_ep->index);
+	epint_reg = hs_ep->dir_in ? DIEPINT(hs_ep->index) :
+		DOEPINT(hs_ep->index);
+
+	dev_dbg(hsotg->dev, "%s: stopping transfer on %s\n", __func__,
+			hs_ep->name);
+	if (hs_ep->dir_in) {
+		__orr32(hsotg->regs + epctrl_reg, DXEPCTL_SNAK);
+		/* Wait for Nak effect */
+		if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg,
+						DXEPINT_INEPNAKEFF, 100))
+			dev_warn(hsotg->dev,
+				"%s: timeout DIEPINT.NAKEFF\n", __func__);
+	} else {
+		/* Clear any pending nak effect interrupt */
+		dwc2_writel(GINTSTS_GINNAKEFF, hsotg->regs + GINTSTS);
+
+		__orr32(hsotg->regs + DCTL, DCTL_SGNPINNAK);
+
+		/* Wait for global nak to take effect */
+		if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS,
+						GINTSTS_GINNAKEFF, 100))
+			dev_warn(hsotg->dev,
+				"%s: timeout GINTSTS.GINNAKEFF\n", __func__);
+	}
+
+	/* Disable ep */
+	__orr32(hsotg->regs + epctrl_reg, DXEPCTL_EPDIS | DXEPCTL_SNAK);
+
+	/* Wait for ep to be disabled */
+	if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg, DXEPINT_EPDISBLD, 100))
+		dev_warn(hsotg->dev,
+			"%s: timeout DOEPCTL.EPDisable\n", __func__);
+
+	if (hs_ep->dir_in) {
+		if (hsotg->dedicated_fifos) {
+			dwc2_writel(GRSTCTL_TXFNUM(hs_ep->fifo_index) |
+				GRSTCTL_TXFFLSH, hsotg->regs + GRSTCTL);
+			/* Wait for fifo flush */
+			if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL,
+							GRSTCTL_TXFFLSH, 100))
+				dev_warn(hsotg->dev,
+					"%s: timeout flushing fifos\n",
+					__func__);
+		}
+		/* TODO: Flush shared tx fifo */
+	} else {
+		/* Remove global NAKs */
+		__bic32(hsotg->regs + DCTL, DCTL_SGNPINNAK);
+	}
+}
+
 /**
- * s3c_hsotg_ep_dequeue - dequeue given endpoint
+ * dwc2_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)
+static int dwc2_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
 {
-	struct s3c_hsotg_req *hs_req = our_req(req);
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_req *hs_req = our_req(req);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	unsigned long flags;
 
@@ -2844,20 +2969,24 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
 		return -EINVAL;
 	}
 
-	s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET);
+	/* Dequeue already started request */
+	if (req == &hs_ep->req->req)
+		dwc2_hsotg_ep_stop_xfr(hs, hs_ep);
+
+	dwc2_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET);
 	spin_unlock_irqrestore(&hs->lock, flags);
 
 	return 0;
 }
 
 /**
- * s3c_hsotg_ep_sethalt - set halt on a given endpoint
+ * dwc2_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)
+static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	int index = hs_ep->index;
 	u32 epreg;
@@ -2868,7 +2997,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 
 	if (index == 0) {
 		if (value)
-			s3c_hsotg_stall_ep0(hs);
+			dwc2_hsotg_stall_ep0(hs);
 		else
 			dev_warn(hs->dev,
 				 "%s: can't clear halt on ep0\n", __func__);
@@ -2877,7 +3006,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 
 	if (hs_ep->dir_in) {
 		epreg = DIEPCTL(index);
-		epctl = readl(hs->regs + epreg);
+		epctl = dwc2_readl(hs->regs + epreg);
 
 		if (value) {
 			epctl |= DXEPCTL_STALL | DXEPCTL_SNAK;
@@ -2890,11 +3019,11 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 				xfertype == DXEPCTL_EPTYPE_INTERRUPT)
 					epctl |= DXEPCTL_SETD0PID;
 		}
-		writel(epctl, hs->regs + epreg);
+		dwc2_writel(epctl, hs->regs + epreg);
 	} else {
 
 		epreg = DOEPCTL(index);
-		epctl = readl(hs->regs + epreg);
+		epctl = dwc2_readl(hs->regs + epreg);
 
 		if (value)
 			epctl |= DXEPCTL_STALL;
@@ -2905,7 +3034,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 				xfertype == DXEPCTL_EPTYPE_INTERRUPT)
 					epctl |= DXEPCTL_SETD0PID;
 		}
-		writel(epctl, hs->regs + epreg);
+		dwc2_writel(epctl, hs->regs + epreg);
 	}
 
 	hs_ep->halted = value;
@@ -2914,97 +3043,53 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
 }
 
 /**
- * s3c_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held
+ * dwc2_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held
  * @ep: The endpoint to set halt.
  * @value: Set or unset the halt.
  */
-static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
+static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value)
 {
-	struct s3c_hsotg_ep *hs_ep = our_ep(ep);
+	struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
 	struct dwc2_hsotg *hs = hs_ep->parent;
 	unsigned long flags = 0;
 	int ret = 0;
 
 	spin_lock_irqsave(&hs->lock, flags);
-	ret = s3c_hsotg_ep_sethalt(ep, value);
+	ret = dwc2_hsotg_ep_sethalt(ep, value);
 	spin_unlock_irqrestore(&hs->lock, flags);
 
 	return ret;
 }
 
-static struct usb_ep_ops s3c_hsotg_ep_ops = {
-	.enable		= s3c_hsotg_ep_enable,
-	.disable	= s3c_hsotg_ep_disable,
-	.alloc_request	= s3c_hsotg_ep_alloc_request,
-	.free_request	= s3c_hsotg_ep_free_request,
-	.queue		= s3c_hsotg_ep_queue_lock,
-	.dequeue	= s3c_hsotg_ep_dequeue,
-	.set_halt	= s3c_hsotg_ep_sethalt_lock,
+static struct usb_ep_ops dwc2_hsotg_ep_ops = {
+	.enable		= dwc2_hsotg_ep_enable,
+	.disable	= dwc2_hsotg_ep_disable,
+	.alloc_request	= dwc2_hsotg_ep_alloc_request,
+	.free_request	= dwc2_hsotg_ep_free_request,
+	.queue		= dwc2_hsotg_ep_queue_lock,
+	.dequeue	= dwc2_hsotg_ep_dequeue,
+	.set_halt	= dwc2_hsotg_ep_sethalt_lock,
 	/* note, don't believe we have any call for the fifo routines */
 };
 
 /**
- * s3c_hsotg_phy_enable - enable platform phy dev
- * @hsotg: The driver state
- *
- * A wrapper for platform code responsible for controlling
- * low-level USB code
- */
-static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg)
-{
-	struct platform_device *pdev = to_platform_device(hsotg->dev);
-
-	dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
-
-	if (hsotg->uphy)
-		usb_phy_init(hsotg->uphy);
-	else if (hsotg->plat && hsotg->plat->phy_init)
-		hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
-	else {
-		phy_init(hsotg->phy);
-		phy_power_on(hsotg->phy);
-	}
-}
-
-/**
- * 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 dwc2_hsotg *hsotg)
-{
-	struct platform_device *pdev = to_platform_device(hsotg->dev);
-
-	if (hsotg->uphy)
-		usb_phy_shutdown(hsotg->uphy);
-	else if (hsotg->plat && hsotg->plat->phy_exit)
-		hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
-	else {
-		phy_power_off(hsotg->phy);
-		phy_exit(hsotg->phy);
-	}
-}
-
-/**
- * s3c_hsotg_init - initalize the usb core
+ * dwc2_hsotg_init - initalize the usb core
  * @hsotg: The driver state
  */
-static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
 {
 	u32 trdtim;
 	/* unmask subset of endpoint interrupts */
 
-	writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
-		DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK,
-		hsotg->regs + DIEPMSK);
+	dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
+		    DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK,
+		    hsotg->regs + DIEPMSK);
 
-	writel(DOEPMSK_SETUPMSK | DOEPMSK_AHBERRMSK |
-		DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK,
-		hsotg->regs + DOEPMSK);
+	dwc2_writel(DOEPMSK_SETUPMSK | DOEPMSK_AHBERRMSK |
+		    DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK,
+		    hsotg->regs + DOEPMSK);
 
-	writel(0, hsotg->regs + DAINTMSK);
+	dwc2_writel(0, hsotg->regs + DAINTMSK);
 
 	/* Be in disconnected state until gadget is registered */
 	__orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
@@ -3012,14 +3097,14 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
 	/* setup fifos */
 
 	dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-		readl(hsotg->regs + GRXFSIZ),
-		readl(hsotg->regs + GNPTXFSIZ));
+		dwc2_readl(hsotg->regs + GRXFSIZ),
+		dwc2_readl(hsotg->regs + GNPTXFSIZ));
 
-	s3c_hsotg_init_fifo(hsotg);
+	dwc2_hsotg_init_fifo(hsotg);
 
 	/* set the PLL on, remove the HNP/SRP and set the PHY */
 	trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-	writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+	dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
 		(trdtim << GUSBCFG_USBTRDTIM_SHIFT),
 		hsotg->regs + GUSBCFG);
 
@@ -3028,14 +3113,14 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg)
 }
 
 /**
- * s3c_hsotg_udc_start - prepare the udc for work
+ * dwc2_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,
+static int dwc2_hsotg_udc_start(struct usb_gadget *gadget,
 			   struct usb_gadget_driver *driver)
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
@@ -3060,7 +3145,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
 		return -EINVAL;
 	}
 
-	mutex_lock(&hsotg->init_mutex);
 	WARN_ON(hsotg->driver);
 
 	driver->driver.bus = NULL;
@@ -3068,45 +3152,38 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
 	hsotg->gadget.dev.of_node = hsotg->dev->of_node;
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 
-	clk_enable(hsotg->clk);
-
-	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;
+	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
+		ret = dwc2_lowlevel_hw_enable(hsotg);
+		if (ret)
+			goto err;
 	}
 
-	s3c_hsotg_phy_enable(hsotg);
 	if (!IS_ERR_OR_NULL(hsotg->uphy))
 		otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget);
 
 	spin_lock_irqsave(&hsotg->lock, flags);
-	s3c_hsotg_init(hsotg);
-	s3c_hsotg_core_init_disconnected(hsotg, false);
+	dwc2_hsotg_init(hsotg);
+	dwc2_hsotg_core_init_disconnected(hsotg, false);
 	hsotg->enabled = 0;
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 
 	dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name);
 
-	mutex_unlock(&hsotg->init_mutex);
-
 	return 0;
 
 err:
-	mutex_unlock(&hsotg->init_mutex);
 	hsotg->driver = NULL;
 	return ret;
 }
 
 /**
- * s3c_hsotg_udc_stop - stop the udc
+ * dwc2_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)
+static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	unsigned long flags = 0;
@@ -3115,14 +3192,12 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)
 	if (!hsotg)
 		return -ENODEV;
 
-	mutex_lock(&hsotg->init_mutex);
-
 	/* all endpoints should be shutdown */
 	for (ep = 1; ep < hsotg->num_of_eps; ep++) {
 		if (hsotg->eps_in[ep])
-			s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
+			dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 		if (hsotg->eps_out[ep])
-			s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
+			dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 	}
 
 	spin_lock_irqsave(&hsotg->lock, flags);
@@ -3135,64 +3210,63 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget)
 
 	if (!IS_ERR_OR_NULL(hsotg->uphy))
 		otg_set_peripheral(hsotg->uphy->otg, NULL);
-	s3c_hsotg_phy_disable(hsotg);
 
-	regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
-
-	clk_disable(hsotg->clk);
-
-	mutex_unlock(&hsotg->init_mutex);
+	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+		dwc2_lowlevel_hw_disable(hsotg);
 
 	return 0;
 }
 
 /**
- * s3c_hsotg_gadget_getframe - read the frame number
+ * dwc2_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)
+static int dwc2_hsotg_gadget_getframe(struct usb_gadget *gadget)
 {
-	return s3c_hsotg_read_frameno(to_hsotg(gadget));
+	return dwc2_hsotg_read_frameno(to_hsotg(gadget));
 }
 
 /**
- * s3c_hsotg_pullup - connect/disconnect the USB PHY
+ * dwc2_hsotg_pullup - connect/disconnect the USB PHY
  * @gadget: The usb gadget state
  * @is_on: Current state of the USB PHY
  *
  * Connect/Disconnect the USB PHY pullup
  */
-static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on)
+static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	unsigned long flags = 0;
 
-	dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on);
+	dev_dbg(hsotg->dev, "%s: is_on: %d op_state: %d\n", __func__, is_on,
+			hsotg->op_state);
+
+	/* Don't modify pullup state while in host mode */
+	if (hsotg->op_state != OTG_STATE_B_PERIPHERAL) {
+		hsotg->enabled = is_on;
+		return 0;
+	}
 
-	mutex_lock(&hsotg->init_mutex);
 	spin_lock_irqsave(&hsotg->lock, flags);
 	if (is_on) {
-		clk_enable(hsotg->clk);
 		hsotg->enabled = 1;
-		s3c_hsotg_core_init_disconnected(hsotg, false);
-		s3c_hsotg_core_connect(hsotg);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		dwc2_hsotg_core_connect(hsotg);
 	} else {
-		s3c_hsotg_core_disconnect(hsotg);
-		s3c_hsotg_disconnect(hsotg);
+		dwc2_hsotg_core_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
 		hsotg->enabled = 0;
-		clk_disable(hsotg->clk);
 	}
 
 	hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 	spin_unlock_irqrestore(&hsotg->lock, flags);
-	mutex_unlock(&hsotg->init_mutex);
 
 	return 0;
 }
 
-static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
+static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 	unsigned long flags;
@@ -3200,23 +3274,22 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 	dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active);
 	spin_lock_irqsave(&hsotg->lock, flags);
 
+	/*
+	 * If controller is hibernated, it must exit from hibernation
+	 * before being initialized / de-initialized
+	 */
+	if (hsotg->lx_state == DWC2_L2)
+		dwc2_exit_hibernation(hsotg, false);
+
 	if (is_active) {
-		/*
-		 * If controller is hibernated, it must exit from hibernation
-		 * before being initialized
-		 */
-		if (hsotg->lx_state == DWC2_L2) {
-			dwc2_exit_hibernation(hsotg, false);
-			hsotg->lx_state = DWC2_L0;
-		}
-		/* Kill any ep0 requests as controller will be reinitialized */
-		kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
-		s3c_hsotg_core_init_disconnected(hsotg, false);
+		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
+
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
 		if (hsotg->enabled)
-			s3c_hsotg_core_connect(hsotg);
+			dwc2_hsotg_core_connect(hsotg);
 	} else {
-		s3c_hsotg_core_disconnect(hsotg);
-		s3c_hsotg_disconnect(hsotg);
+		dwc2_hsotg_core_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
 	}
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -3224,13 +3297,13 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 }
 
 /**
- * s3c_hsotg_vbus_draw - report bMaxPower field
+ * dwc2_hsotg_vbus_draw - report bMaxPower field
  * @gadget: The usb gadget state
  * @mA: Amount of current
  *
  * Report how much power the device may consume to the phy.
  */
-static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 {
 	struct dwc2_hsotg *hsotg = to_hsotg(gadget);
 
@@ -3239,17 +3312,17 @@ static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 	return usb_phy_set_power(hsotg->uphy, mA);
 }
 
-static const struct usb_gadget_ops s3c_hsotg_gadget_ops = {
-	.get_frame	= s3c_hsotg_gadget_getframe,
-	.udc_start		= s3c_hsotg_udc_start,
-	.udc_stop		= s3c_hsotg_udc_stop,
-	.pullup                 = s3c_hsotg_pullup,
-	.vbus_session		= s3c_hsotg_vbus_session,
-	.vbus_draw		= s3c_hsotg_vbus_draw,
+static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = {
+	.get_frame	= dwc2_hsotg_gadget_getframe,
+	.udc_start		= dwc2_hsotg_udc_start,
+	.udc_stop		= dwc2_hsotg_udc_stop,
+	.pullup                 = dwc2_hsotg_pullup,
+	.vbus_session		= dwc2_hsotg_vbus_session,
+	.vbus_draw		= dwc2_hsotg_vbus_draw,
 };
 
 /**
- * s3c_hsotg_initep - initialise a single endpoint
+ * dwc2_hsotg_initep - initialise a single endpoint
  * @hsotg: The device state.
  * @hs_ep: The endpoint to be initialised.
  * @epnum: The endpoint number
@@ -3258,8 +3331,8 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = {
  * creation) to give to the gadget driver. Setup the endpoint name, any
  * direction information and other state that may be required.
  */
-static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
-				       struct s3c_hsotg_ep *hs_ep,
+static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg,
+				       struct dwc2_hsotg_ep *hs_ep,
 				       int epnum,
 				       bool dir_in)
 {
@@ -3287,7 +3360,7 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
 	hs_ep->parent = hsotg;
 	hs_ep->ep.name = hs_ep->name;
 	usb_ep_set_maxpacket_limit(&hs_ep->ep, epnum ? 1024 : EP0_MPS_LIMIT);
-	hs_ep->ep.ops = &s3c_hsotg_ep_ops;
+	hs_ep->ep.ops = &dwc2_hsotg_ep_ops;
 
 	if (epnum == 0) {
 		hs_ep->ep.caps.type_control = true;
@@ -3310,19 +3383,19 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg,
 	if (using_dma(hsotg)) {
 		u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15);
 		if (dir_in)
-			writel(next, hsotg->regs + DIEPCTL(epnum));
+			dwc2_writel(next, hsotg->regs + DIEPCTL(epnum));
 		else
-			writel(next, hsotg->regs + DOEPCTL(epnum));
+			dwc2_writel(next, hsotg->regs + DOEPCTL(epnum));
 	}
 }
 
 /**
- * s3c_hsotg_hw_cfg - read HW configuration registers
+ * dwc2_hsotg_hw_cfg - read HW configuration registers
  * @param: The device state
  *
  * Read the USB core HW configuration registers
  */
-static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
+static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
 {
 	u32 cfg;
 	u32 ep_type;
@@ -3330,41 +3403,41 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
 
 	/* check hardware configuration */
 
-	cfg = readl(hsotg->regs + GHWCFG2);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG2);
 	hsotg->num_of_eps = (cfg >> GHWCFG2_NUM_DEV_EP_SHIFT) & 0xF;
 	/* Add ep0 */
 	hsotg->num_of_eps++;
 
-	hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct s3c_hsotg_ep),
+	hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct dwc2_hsotg_ep),
 								GFP_KERNEL);
 	if (!hsotg->eps_in[0])
 		return -ENOMEM;
-	/* Same s3c_hsotg_ep is used in both directions for ep0 */
+	/* Same dwc2_hsotg_ep is used in both directions for ep0 */
 	hsotg->eps_out[0] = hsotg->eps_in[0];
 
-	cfg = readl(hsotg->regs + GHWCFG1);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG1);
 	for (i = 1, cfg >>= 2; i < hsotg->num_of_eps; i++, cfg >>= 2) {
 		ep_type = cfg & 3;
 		/* Direction in or both */
 		if (!(ep_type & 2)) {
 			hsotg->eps_in[i] = devm_kzalloc(hsotg->dev,
-				sizeof(struct s3c_hsotg_ep), GFP_KERNEL);
+				sizeof(struct dwc2_hsotg_ep), GFP_KERNEL);
 			if (!hsotg->eps_in[i])
 				return -ENOMEM;
 		}
 		/* Direction out or both */
 		if (!(ep_type & 1)) {
 			hsotg->eps_out[i] = devm_kzalloc(hsotg->dev,
-				sizeof(struct s3c_hsotg_ep), GFP_KERNEL);
+				sizeof(struct dwc2_hsotg_ep), GFP_KERNEL);
 			if (!hsotg->eps_out[i])
 				return -ENOMEM;
 		}
 	}
 
-	cfg = readl(hsotg->regs + GHWCFG3);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG3);
 	hsotg->fifo_mem = (cfg >> GHWCFG3_DFIFO_DEPTH_SHIFT);
 
-	cfg = readl(hsotg->regs + GHWCFG4);
+	cfg = dwc2_readl(hsotg->regs + GHWCFG4);
 	hsotg->dedicated_fifos = (cfg >> GHWCFG4_DED_FIFO_SHIFT) & 1;
 
 	dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n",
@@ -3375,10 +3448,10 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg)
 }
 
 /**
- * s3c_hsotg_dump - dump state of the udc
+ * dwc2_hsotg_dump - dump state of the udc
  * @param: The device state
  */
-static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg)
 {
 #ifdef DEBUG
 	struct device *dev = hsotg->dev;
@@ -3387,19 +3460,19 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
 	int idx;
 
 	dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n",
-		 readl(regs + DCFG), readl(regs + DCTL),
-		 readl(regs + DIEPMSK));
+		 dwc2_readl(regs + DCFG), dwc2_readl(regs + DCTL),
+		 dwc2_readl(regs + DIEPMSK));
 
 	dev_info(dev, "GAHBCFG=0x%08x, GHWCFG1=0x%08x\n",
-		 readl(regs + GAHBCFG), readl(regs + GHWCFG1));
+		 dwc2_readl(regs + GAHBCFG), dwc2_readl(regs + GHWCFG1));
 
 	dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n",
-		 readl(regs + GRXFSIZ), readl(regs + GNPTXFSIZ));
+		 dwc2_readl(regs + GRXFSIZ), dwc2_readl(regs + GNPTXFSIZ));
 
 	/* show periodic fifo settings */
 
 	for (idx = 1; idx < hsotg->num_of_eps; idx++) {
-		val = readl(regs + DPTXFSIZN(idx));
+		val = dwc2_readl(regs + DPTXFSIZN(idx));
 		dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx,
 			 val >> FIFOSIZE_DEPTH_SHIFT,
 			 val & FIFOSIZE_STARTADDR_MASK);
@@ -3408,26 +3481,26 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg)
 	for (idx = 0; idx < hsotg->num_of_eps; idx++) {
 		dev_info(dev,
 			 "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx,
-			 readl(regs + DIEPCTL(idx)),
-			 readl(regs + DIEPTSIZ(idx)),
-			 readl(regs + DIEPDMA(idx)));
+			 dwc2_readl(regs + DIEPCTL(idx)),
+			 dwc2_readl(regs + DIEPTSIZ(idx)),
+			 dwc2_readl(regs + DIEPDMA(idx)));
 
-		val = readl(regs + DOEPCTL(idx));
+		val = dwc2_readl(regs + DOEPCTL(idx));
 		dev_info(dev,
 			 "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n",
-			 idx, readl(regs + DOEPCTL(idx)),
-			 readl(regs + DOEPTSIZ(idx)),
-			 readl(regs + DOEPDMA(idx)));
+			 idx, dwc2_readl(regs + DOEPCTL(idx)),
+			 dwc2_readl(regs + DOEPTSIZ(idx)),
+			 dwc2_readl(regs + DOEPDMA(idx)));
 
 	}
 
 	dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n",
-		 readl(regs + DVBUSDIS), readl(regs + DVBUSPULSE));
+		 dwc2_readl(regs + DVBUSDIS), dwc2_readl(regs + DVBUSPULSE));
 #endif
 }
 
 #ifdef CONFIG_OF
-static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg)
+static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg)
 {
 	struct device_node *np = hsotg->dev->of_node;
 	u32 len = 0;
@@ -3468,7 +3541,7 @@ static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg)
 						&hsotg->g_np_g_tx_fifo_sz);
 }
 #else
-static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
+static inline void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
 #endif
 
 /**
@@ -3479,23 +3552,17 @@ static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { }
 int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 {
 	struct device *dev = hsotg->dev;
-	struct s3c_hsotg_plat *plat = dev->platform_data;
 	int epnum;
 	int ret;
 	int i;
 	u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE;
 
-	/* Set default UTMI width */
-	hsotg->phyif = GUSBCFG_PHYIF16;
-
-	s3c_hsotg_of_probe(hsotg);
-
 	/* Initialize to legacy fifo configuration values */
 	hsotg->g_rx_fifo_sz = 2048;
 	hsotg->g_np_g_tx_fifo_sz = 1024;
 	memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo));
 	/* Device tree specific probe */
-	s3c_hsotg_of_probe(hsotg);
+	dwc2_hsotg_of_probe(hsotg);
 	/* Dump fifo information */
 	dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n",
 						hsotg->g_np_g_tx_fifo_sz);
@@ -3503,70 +3570,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 	for (i = 0; i < MAX_EPS_CHANNELS; i++)
 		dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i,
 						hsotg->g_tx_fifo_sz[i]);
-	/*
-	 * If platform probe couldn't find a generic PHY or an old style
-	 * USB PHY, fall back to pdata
-	 */
-	if (IS_ERR_OR_NULL(hsotg->phy) && IS_ERR_OR_NULL(hsotg->uphy)) {
-		plat = dev_get_platdata(dev);
-		if (!plat) {
-			dev_err(dev,
-			"no platform data or transceiver defined\n");
-			return -EPROBE_DEFER;
-		}
-		hsotg->plat = plat;
-	} else if (hsotg->phy) {
-		/*
-		 * If using the generic PHY framework, check if the PHY bus
-		 * width is 8-bit and set the phyif appropriately.
-		 */
-		if (phy_get_bus_width(hsotg->phy) == 8)
-			hsotg->phyif = GUSBCFG_PHYIF8;
-	}
-
-	hsotg->clk = devm_clk_get(dev, "otg");
-	if (IS_ERR(hsotg->clk)) {
-		hsotg->clk = NULL;
-		dev_dbg(dev, "cannot get otg clock\n");
-	}
 
 	hsotg->gadget.max_speed = USB_SPEED_HIGH;
-	hsotg->gadget.ops = &s3c_hsotg_gadget_ops;
+	hsotg->gadget.ops = &dwc2_hsotg_gadget_ops;
 	hsotg->gadget.name = dev_name(dev);
 	if (hsotg->dr_mode == USB_DR_MODE_OTG)
 		hsotg->gadget.is_otg = 1;
-
-	/* reset the system */
-
-	ret = clk_prepare_enable(hsotg->clk);
-	if (ret) {
-		dev_err(dev, "failed to enable otg clk\n");
-		goto err_clk;
-	}
-
-
-	/* regulators */
-
-	for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
-		hsotg->supplies[i].supply = s3c_hsotg_supply_names[i];
-
-	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies),
-				 hsotg->supplies);
-	if (ret) {
-		dev_err(dev, "failed to request supplies: %d\n", ret);
-		goto err_clk;
-	}
-
-	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-				    hsotg->supplies);
-
-	if (ret) {
-		dev_err(dev, "failed to enable supplies: %d\n", ret);
-		goto err_clk;
-	}
-
-	/* usb phy enable */
-	s3c_hsotg_phy_enable(hsotg);
+	else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 
 	/*
 	 * Force Device mode before initialization.
@@ -3581,14 +3592,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 	 */
 	msleep(25);
 
-	s3c_hsotg_corereset(hsotg);
-	ret = s3c_hsotg_hw_cfg(hsotg);
+	dwc2_hsotg_corereset(hsotg);
+	ret = dwc2_hsotg_hw_cfg(hsotg);
 	if (ret) {
 		dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret);
-		goto err_clk;
+		return ret;
 	}
 
-	s3c_hsotg_init(hsotg);
+	dwc2_hsotg_init(hsotg);
 
 	/* Switch back to default configuration */
 	__bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE);
@@ -3597,35 +3608,28 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 			DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
 	if (!hsotg->ctrl_buff) {
 		dev_err(dev, "failed to allocate ctrl request buff\n");
-		ret = -ENOMEM;
-		goto err_supplies;
+		return -ENOMEM;
 	}
 
 	hsotg->ep0_buff = devm_kzalloc(hsotg->dev,
 			DWC2_CTRL_BUFF_SIZE, GFP_KERNEL);
 	if (!hsotg->ep0_buff) {
 		dev_err(dev, "failed to allocate ctrl reply buff\n");
-		ret = -ENOMEM;
-		goto err_supplies;
+		return -ENOMEM;
 	}
 
-	ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED,
+	ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED,
 				dev_name(hsotg->dev), hsotg);
 	if (ret < 0) {
-		s3c_hsotg_phy_disable(hsotg);
-		clk_disable_unprepare(hsotg->clk);
-		regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-				       hsotg->supplies);
 		dev_err(dev, "cannot claim IRQ for gadget\n");
-		goto err_supplies;
+		return ret;
 	}
 
 	/* 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");
-		ret = -EINVAL;
-		goto err_supplies;
+		return -EINVAL;
 	}
 
 	/* setup endpoint information */
@@ -3635,71 +3639,49 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 
 	/* allocate EP0 request */
 
-	hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep,
+	hsotg->ctrl_req = dwc2_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep,
 						     GFP_KERNEL);
 	if (!hsotg->ctrl_req) {
 		dev_err(dev, "failed to allocate ctrl req\n");
-		ret = -ENOMEM;
-		goto err_supplies;
+		return -ENOMEM;
 	}
 
 	/* initialise the endpoints now the core has been initialised */
 	for (epnum = 0; epnum < hsotg->num_of_eps; epnum++) {
 		if (hsotg->eps_in[epnum])
-			s3c_hsotg_initep(hsotg, hsotg->eps_in[epnum],
+			dwc2_hsotg_initep(hsotg, hsotg->eps_in[epnum],
 								epnum, 1);
 		if (hsotg->eps_out[epnum])
-			s3c_hsotg_initep(hsotg, hsotg->eps_out[epnum],
+			dwc2_hsotg_initep(hsotg, hsotg->eps_out[epnum],
 								epnum, 0);
 	}
 
-	/* disable power and clock */
-	s3c_hsotg_phy_disable(hsotg);
-
-	ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-				    hsotg->supplies);
-	if (ret) {
-		dev_err(dev, "failed to disable supplies: %d\n", ret);
-		goto err_supplies;
-	}
-
 	ret = usb_add_gadget_udc(dev, &hsotg->gadget);
 	if (ret)
-		goto err_supplies;
+		return ret;
 
-	s3c_hsotg_dump(hsotg);
+	dwc2_hsotg_dump(hsotg);
 
 	return 0;
-
-err_supplies:
-	s3c_hsotg_phy_disable(hsotg);
-err_clk:
-	clk_disable_unprepare(hsotg->clk);
-
-	return ret;
 }
 
 /**
- * s3c_hsotg_remove - remove function for hsotg driver
+ * dwc2_hsotg_remove - remove function for hsotg driver
  * @pdev: The platform information for the driver
  */
-int s3c_hsotg_remove(struct dwc2_hsotg *hsotg)
+int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg)
 {
 	usb_del_gadget_udc(&hsotg->gadget);
-	clk_disable_unprepare(hsotg->clk);
 
 	return 0;
 }
 
-int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg)
+int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg)
 {
 	unsigned long flags;
-	int ret = 0;
 
 	if (hsotg->lx_state != DWC2_L0)
-		return ret;
-
-	mutex_lock(&hsotg->init_mutex);
+		return 0;
 
 	if (hsotg->driver) {
 		int ep;
@@ -3709,57 +3691,39 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg)
 
 		spin_lock_irqsave(&hsotg->lock, flags);
 		if (hsotg->enabled)
-			s3c_hsotg_core_disconnect(hsotg);
-		s3c_hsotg_disconnect(hsotg);
+			dwc2_hsotg_core_disconnect(hsotg);
+		dwc2_hsotg_disconnect(hsotg);
 		hsotg->gadget.speed = USB_SPEED_UNKNOWN;
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 
-		s3c_hsotg_phy_disable(hsotg);
-
 		for (ep = 0; ep < hsotg->num_of_eps; ep++) {
 			if (hsotg->eps_in[ep])
-				s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
+				dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep);
 			if (hsotg->eps_out[ep])
-				s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
+				dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep);
 		}
-
-		ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
-					     hsotg->supplies);
-		clk_disable(hsotg->clk);
 	}
 
-	mutex_unlock(&hsotg->init_mutex);
-
-	return ret;
+	return 0;
 }
 
-int s3c_hsotg_resume(struct dwc2_hsotg *hsotg)
+int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg)
 {
 	unsigned long flags;
-	int ret = 0;
 
 	if (hsotg->lx_state == DWC2_L2)
-		return ret;
-
-	mutex_lock(&hsotg->init_mutex);
+		return 0;
 
 	if (hsotg->driver) {
 		dev_info(hsotg->dev, "resuming usb gadget %s\n",
 			 hsotg->driver->driver.name);
 
-		clk_enable(hsotg->clk);
-		ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
-					    hsotg->supplies);
-
-		s3c_hsotg_phy_enable(hsotg);
-
 		spin_lock_irqsave(&hsotg->lock, flags);
-		s3c_hsotg_core_init_disconnected(hsotg, false);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
 		if (hsotg->enabled)
-			s3c_hsotg_core_connect(hsotg);
+			dwc2_hsotg_core_connect(hsotg);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 	}
-	mutex_unlock(&hsotg->init_mutex);
 
-	return ret;
+	return 0;
 }
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f845c41fe9e5e8c788c35d0fd7711b54debbe97e..e79baf73c234f58bf3162bb9d52d5efce9bca1ca 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -80,10 +80,10 @@ static void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg,
 	if (chan == NULL)
 		return;
 
-	hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num));
-	hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num));
-	hctsiz = readl(hsotg->regs + HCTSIZ(chan->hc_num));
-	hc_dma = readl(hsotg->regs + HCDMA(chan->hc_num));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num));
+	hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chan->hc_num));
+	hc_dma = dwc2_readl(hsotg->regs + HCDMA(chan->hc_num));
 
 	dev_dbg(hsotg->dev, "  Assigned to channel %p:\n", chan);
 	dev_dbg(hsotg->dev, "    hcchar 0x%08x, hcsplt 0x%08x\n",
@@ -134,7 +134,7 @@ static void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg,
 	list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) {
 		list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list,
 					 qtd_list_entry) {
-			dwc2_host_complete(hsotg, qtd, -ETIMEDOUT);
+			dwc2_host_complete(hsotg, qtd, -ECONNRESET);
 			dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
 		}
 	}
@@ -207,7 +207,7 @@ void dwc2_hcd_start(struct dwc2_hsotg *hsotg)
 		 */
 		hprt0 = dwc2_read_hprt0(hsotg);
 		hprt0 |= HPRT0_RST;
-		writel(hprt0, hsotg->regs + HPRT0);
+		dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	}
 
 	queue_delayed_work(hsotg->wq_otg, &hsotg->start_work,
@@ -228,11 +228,11 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg)
 			channel = hsotg->hc_ptr_array[i];
 			if (!list_empty(&channel->hc_list_entry))
 				continue;
-			hcchar = readl(hsotg->regs + HCCHAR(i));
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 			if (hcchar & HCCHAR_CHENA) {
 				hcchar &= ~(HCCHAR_CHENA | HCCHAR_EPDIR);
 				hcchar |= HCCHAR_CHDIS;
-				writel(hcchar, hsotg->regs + HCCHAR(i));
+				dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 			}
 		}
 	}
@@ -241,11 +241,11 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg)
 		channel = hsotg->hc_ptr_array[i];
 		if (!list_empty(&channel->hc_list_entry))
 			continue;
-		hcchar = readl(hsotg->regs + HCCHAR(i));
+		hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
 		if (hcchar & HCCHAR_CHENA) {
 			/* Halt the channel */
 			hcchar |= HCCHAR_CHDIS;
-			writel(hcchar, hsotg->regs + HCCHAR(i));
+			dwc2_writel(hcchar, hsotg->regs + HCCHAR(i));
 		}
 
 		dwc2_hc_cleanup(hsotg, channel);
@@ -287,11 +287,11 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg)
 	 * interrupt mask and status bits and disabling subsequent host
 	 * channel interrupts.
 	 */
-	intr = readl(hsotg->regs + GINTMSK);
+	intr = dwc2_readl(hsotg->regs + GINTMSK);
 	intr &= ~(GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT);
-	writel(intr, hsotg->regs + GINTMSK);
+	dwc2_writel(intr, hsotg->regs + GINTMSK);
 	intr = GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT;
-	writel(intr, hsotg->regs + GINTSTS);
+	dwc2_writel(intr, hsotg->regs + GINTSTS);
 
 	/*
 	 * Turn off the vbus power only if the core has transitioned to device
@@ -301,7 +301,7 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg)
 	if (dwc2_is_device_mode(hsotg)) {
 		if (hsotg->op_state != OTG_STATE_A_SUSPEND) {
 			dev_dbg(hsotg->dev, "Disconnect: PortPower off\n");
-			writel(0, hsotg->regs + HPRT0);
+			dwc2_writel(0, hsotg->regs + HPRT0);
 		}
 
 		dwc2_disable_host_interrupts(hsotg);
@@ -354,7 +354,7 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg)
 
 	/* Turn off the vbus power */
 	dev_dbg(hsotg->dev, "PortPower off\n");
-	writel(0, hsotg->regs + HPRT0);
+	dwc2_writel(0, hsotg->regs + HPRT0);
 }
 
 /* Caller must hold driver lock */
@@ -378,7 +378,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
 	if ((dev_speed == USB_SPEED_LOW) &&
 	    (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) &&
 	    (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) {
-		u32 hprt0 = readl(hsotg->regs + HPRT0);
+		u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 		u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 
 		if (prtspd == HPRT0_SPD_FULL_SPEED)
@@ -397,7 +397,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
 		return retval;
 	}
 
-	intr_mask = readl(hsotg->regs + GINTMSK);
+	intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 	if (!(intr_mask & GINTSTS_SOF)) {
 		enum dwc2_transaction_type tr_type;
 
@@ -1070,7 +1070,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 	if (dbg_perio())
 		dev_vdbg(hsotg->dev, "Queue periodic transactions\n");
 
-	tx_status = readl(hsotg->regs + HPTXSTS);
+	tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 	qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		    TXSTS_QSPCAVAIL_SHIFT;
 	fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1085,7 +1085,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 
 	qh_ptr = hsotg->periodic_sched_assigned.next;
 	while (qh_ptr != &hsotg->periodic_sched_assigned) {
-		tx_status = readl(hsotg->regs + HPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 		if (qspcavail == 0) {
@@ -1145,7 +1145,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 	}
 
 	if (hsotg->core_params->dma_enable <= 0) {
-		tx_status = readl(hsotg->regs + HPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 		fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1168,9 +1168,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 			 * level to ensure that new requests are loaded as
 			 * soon as possible.)
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_PTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		} else {
 			/*
 			 * Disable the Tx FIFO empty interrupt since there are
@@ -1179,9 +1179,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
 			 * handlers to queue more transactions as transfer
 			 * states change.
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk &= ~GINTSTS_PTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 	}
 }
@@ -1210,7 +1210,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 
 	dev_vdbg(hsotg->dev, "Queue non-periodic transactions\n");
 
-	tx_status = readl(hsotg->regs + GNPTXSTS);
+	tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 	qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 		    TXSTS_QSPCAVAIL_SHIFT;
 	fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1233,7 +1233,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 	 * available in the request queue or the Tx FIFO
 	 */
 	do {
-		tx_status = readl(hsotg->regs + GNPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 		if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) {
@@ -1270,7 +1270,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 	} while (hsotg->non_periodic_qh_ptr != orig_qh_ptr);
 
 	if (hsotg->core_params->dma_enable <= 0) {
-		tx_status = readl(hsotg->regs + GNPTXSTS);
+		tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 		qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >>
 			    TXSTS_QSPCAVAIL_SHIFT;
 		fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >>
@@ -1290,9 +1290,9 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 			 * level to ensure that new requests are loaded as
 			 * soon as possible.)
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		} else {
 			/*
 			 * Disable the Tx FIFO empty interrupt since there are
@@ -1301,9 +1301,9 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg)
 			 * handlers to queue more transactions as transfer
 			 * states change.
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk &= ~GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 	}
 }
@@ -1341,10 +1341,10 @@ void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
 			 * Ensure NP Tx FIFO empty interrupt is disabled when
 			 * there are no non-periodic transfers to process
 			 */
-			u32 gintmsk = readl(hsotg->regs + GINTMSK);
+			u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 
 			gintmsk &= ~GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 	}
 }
@@ -1355,10 +1355,11 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
 						wf_otg);
 	u32 count = 0;
 	u32 gotgctl;
+	unsigned long flags;
 
 	dev_dbg(hsotg->dev, "%s()\n", __func__);
 
-	gotgctl = readl(hsotg->regs + GOTGCTL);
+	gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 	dev_dbg(hsotg->dev, "gotgctl=%0x\n", gotgctl);
 	dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%d\n",
 		!!(gotgctl & GOTGCTL_CONID_B));
@@ -1382,8 +1383,10 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
 		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 		dwc2_core_init(hsotg, false, -1);
 		dwc2_enable_global_interrupts(hsotg);
-		s3c_hsotg_core_init_disconnected(hsotg, false);
-		s3c_hsotg_core_connect(hsotg);
+		spin_lock_irqsave(&hsotg->lock, flags);
+		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		dwc2_hsotg_core_connect(hsotg);
 	} else {
 		/* A-Device connector (Host Mode) */
 		dev_dbg(hsotg->dev, "connId A\n");
@@ -1421,10 +1424,11 @@ static void dwc2_wakeup_detected(unsigned long data)
 	hprt0 = dwc2_read_hprt0(hsotg);
 	dev_dbg(hsotg->dev, "Resume: HPRT0=%0x\n", hprt0);
 	hprt0 &= ~HPRT0_RES;
-	writel(hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n",
-		readl(hsotg->regs + HPRT0));
+		dwc2_readl(hsotg->regs + HPRT0));
 
+	hsotg->bus_suspended = 0;
 	dwc2_hcd_rem_wakeup(hsotg);
 
 	/* Change to L0 state */
@@ -1451,30 +1455,35 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 	spin_lock_irqsave(&hsotg->lock, flags);
 
 	if (windex == hsotg->otg_port && dwc2_host_is_b_hnp_enabled(hsotg)) {
-		gotgctl = readl(hsotg->regs + GOTGCTL);
+		gotgctl = dwc2_readl(hsotg->regs + GOTGCTL);
 		gotgctl |= GOTGCTL_HSTSETHNPEN;
-		writel(gotgctl, hsotg->regs + GOTGCTL);
+		dwc2_writel(gotgctl, hsotg->regs + GOTGCTL);
 		hsotg->op_state = OTG_STATE_A_SUSPEND;
 	}
 
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 |= HPRT0_SUSP;
-	writel(hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
 
-	/* Update lx_state */
-	hsotg->lx_state = DWC2_L2;
+	hsotg->bus_suspended = 1;
 
-	/* Suspend the Phy Clock */
-	pcgctl = readl(hsotg->regs + PCGCTL);
-	pcgctl |= PCGCTL_STOPPCLK;
-	writel(pcgctl, hsotg->regs + PCGCTL);
-	udelay(10);
+	/*
+	 * If hibernation is supported, Phy clock will be suspended
+	 * after registers are backuped.
+	 */
+	if (!hsotg->core_params->hibernation) {
+		/* Suspend the Phy Clock */
+		pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
+		pcgctl |= PCGCTL_STOPPCLK;
+		dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
+		udelay(10);
+	}
 
 	/* For HNP the bus must be suspended for at least 200ms */
 	if (dwc2_host_is_b_hnp_enabled(hsotg)) {
-		pcgctl = readl(hsotg->regs + PCGCTL);
+		pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
 		pcgctl &= ~PCGCTL_STOPPCLK;
-		writel(pcgctl, hsotg->regs + PCGCTL);
+		dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
 
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 
@@ -1484,6 +1493,44 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 	}
 }
 
+/* Must NOT be called with interrupt disabled or spinlock held */
+static void dwc2_port_resume(struct dwc2_hsotg *hsotg)
+{
+	unsigned long flags;
+	u32 hprt0;
+	u32 pcgctl;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	/*
+	 * If hibernation is supported, Phy clock is already resumed
+	 * after registers restore.
+	 */
+	if (!hsotg->core_params->hibernation) {
+		pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
+		pcgctl &= ~PCGCTL_STOPPCLK;
+		dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		usleep_range(20000, 40000);
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
+
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 |= HPRT0_RES;
+	hprt0 &= ~HPRT0_SUSP;
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	msleep(USB_RESUME_TIMEOUT);
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 &= ~(HPRT0_RES | HPRT0_SUSP);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
+	hsotg->bus_suspended = 0;
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+}
+
 /* Handles hub class-specific requests */
 static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				u16 wvalue, u16 windex, char *buf, u16 wlength)
@@ -1523,23 +1570,15 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"ClearPortFeature USB_PORT_FEAT_ENABLE\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 |= HPRT0_ENA;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 
 		case USB_PORT_FEAT_SUSPEND:
 			dev_dbg(hsotg->dev,
 				"ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
-			writel(0, hsotg->regs + PCGCTL);
-			usleep_range(20000, 40000);
-
-			hprt0 = dwc2_read_hprt0(hsotg);
-			hprt0 |= HPRT0_RES;
-			writel(hprt0, hsotg->regs + HPRT0);
-			hprt0 &= ~HPRT0_SUSP;
-			msleep(USB_RESUME_TIMEOUT);
 
-			hprt0 &= ~HPRT0_RES;
-			writel(hprt0, hsotg->regs + HPRT0);
+			if (hsotg->bus_suspended)
+				dwc2_port_resume(hsotg);
 			break;
 
 		case USB_PORT_FEAT_POWER:
@@ -1547,7 +1586,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"ClearPortFeature USB_PORT_FEAT_POWER\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 &= ~HPRT0_PWR;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 
 		case USB_PORT_FEAT_INDICATOR:
@@ -1668,7 +1707,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 			break;
 		}
 
-		hprt0 = readl(hsotg->regs + HPRT0);
+		hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 		dev_vdbg(hsotg->dev, "  HPRT0: 0x%08x\n", hprt0);
 
 		if (hprt0 & HPRT0_CONNSTS)
@@ -1733,18 +1772,18 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"SetPortFeature - USB_PORT_FEAT_POWER\n");
 			hprt0 = dwc2_read_hprt0(hsotg);
 			hprt0 |= HPRT0_PWR;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 
 		case USB_PORT_FEAT_RESET:
 			hprt0 = dwc2_read_hprt0(hsotg);
 			dev_dbg(hsotg->dev,
 				"SetPortFeature - USB_PORT_FEAT_RESET\n");
-			pcgctl = readl(hsotg->regs + PCGCTL);
+			pcgctl = dwc2_readl(hsotg->regs + PCGCTL);
 			pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK);
-			writel(pcgctl, hsotg->regs + PCGCTL);
+			dwc2_writel(pcgctl, hsotg->regs + PCGCTL);
 			/* ??? Original driver does this */
-			writel(0, hsotg->regs + PCGCTL);
+			dwc2_writel(0, hsotg->regs + PCGCTL);
 
 			hprt0 = dwc2_read_hprt0(hsotg);
 			/* Clear suspend bit if resetting from suspend state */
@@ -1759,13 +1798,13 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				hprt0 |= HPRT0_PWR | HPRT0_RST;
 				dev_dbg(hsotg->dev,
 					"In host mode, hprt0=%08x\n", hprt0);
-				writel(hprt0, hsotg->regs + HPRT0);
+				dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			}
 
 			/* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
 			usleep_range(50000, 70000);
 			hprt0 &= ~HPRT0_RST;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			hsotg->lx_state = DWC2_L0; /* Now back to On state */
 			break;
 
@@ -1781,7 +1820,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 				"SetPortFeature - USB_PORT_FEAT_TEST\n");
 			hprt0 &= ~HPRT0_TSTCTL_MASK;
 			hprt0 |= (windex >> 8) << HPRT0_TSTCTL_SHIFT;
-			writel(hprt0, hsotg->regs + HPRT0);
+			dwc2_writel(hprt0, hsotg->regs + HPRT0);
 			break;
 
 		default:
@@ -1838,7 +1877,7 @@ static int dwc2_hcd_is_status_changed(struct dwc2_hsotg *hsotg, int port)
 
 int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
 {
-	u32 hfnum = readl(hsotg->regs + HFNUM);
+	u32 hfnum = dwc2_readl(hsotg->regs + HFNUM);
 
 #ifdef DWC2_DEBUG_SOF
 	dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n",
@@ -1941,11 +1980,11 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
 		if (chan->xfer_started) {
 			u32 hfnum, hcchar, hctsiz, hcint, hcintmsk;
 
-			hfnum = readl(hsotg->regs + HFNUM);
-			hcchar = readl(hsotg->regs + HCCHAR(i));
-			hctsiz = readl(hsotg->regs + HCTSIZ(i));
-			hcint = readl(hsotg->regs + HCINT(i));
-			hcintmsk = readl(hsotg->regs + HCINTMSK(i));
+			hfnum = dwc2_readl(hsotg->regs + HFNUM);
+			hcchar = dwc2_readl(hsotg->regs + HCCHAR(i));
+			hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(i));
+			hcint = dwc2_readl(hsotg->regs + HCINT(i));
+			hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(i));
 			dev_dbg(hsotg->dev, "    hfnum: 0x%08x\n", hfnum);
 			dev_dbg(hsotg->dev, "    hcchar: 0x%08x\n", hcchar);
 			dev_dbg(hsotg->dev, "    hctsiz: 0x%08x\n", hctsiz);
@@ -1993,12 +2032,12 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg)
 	dev_dbg(hsotg->dev, "  periodic_channels: %d\n",
 		hsotg->periodic_channels);
 	dev_dbg(hsotg->dev, "  periodic_usecs: %d\n", hsotg->periodic_usecs);
-	np_tx_status = readl(hsotg->regs + GNPTXSTS);
+	np_tx_status = dwc2_readl(hsotg->regs + GNPTXSTS);
 	dev_dbg(hsotg->dev, "  NP Tx Req Queue Space Avail: %d\n",
 		(np_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT);
 	dev_dbg(hsotg->dev, "  NP Tx FIFO Space Avail: %d\n",
 		(np_tx_status & TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT);
-	p_tx_status = readl(hsotg->regs + HPTXSTS);
+	p_tx_status = dwc2_readl(hsotg->regs + HPTXSTS);
 	dev_dbg(hsotg->dev, "  P Tx Req Queue Space Avail: %d\n",
 		(p_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT);
 	dev_dbg(hsotg->dev, "  P Tx FIFO Space Avail: %d\n",
@@ -2194,11 +2233,6 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
 			 usb_pipein(urb->pipe) ? "IN" : "OUT", status,
 			 urb->actual_length);
 
-	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) {
-		for (i = 0; i < urb->number_of_packets; i++)
-			dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n",
-				 i, urb->iso_frame_desc[i].status);
-	}
 
 	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
 		urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb);
@@ -2211,6 +2245,12 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
 		}
 	}
 
+	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) {
+		for (i = 0; i < urb->number_of_packets; i++)
+			dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n",
+				 i, urb->iso_frame_desc[i].status);
+	}
+
 	urb->status = status;
 	if (!status) {
 		if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
@@ -2262,7 +2302,7 @@ static void dwc2_hcd_reset_func(struct work_struct *work)
 	dev_dbg(hsotg->dev, "USB RESET function called\n");
 	hprt0 = dwc2_read_hprt0(hsotg);
 	hprt0 &= ~HPRT0_RST;
-	writel(hprt0, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0, hsotg->regs + HPRT0);
 	hsotg->flags.b.port_reset_change = 1;
 }
 
@@ -2286,8 +2326,9 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd)
 	dev_dbg(hsotg->dev, "DWC OTG HCD START\n");
 
 	spin_lock_irqsave(&hsotg->lock, flags);
-
+	hsotg->lx_state = DWC2_L0;
 	hcd->state = HC_STATE_RUNNING;
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (dwc2_is_device_mode(hsotg)) {
 		spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -2316,8 +2357,19 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
 	unsigned long flags;
 
+	/* Turn off all host-specific interrupts */
+	dwc2_disable_host_interrupts(hsotg);
+
+	/* Wait for interrupt processing to finish */
+	synchronize_irq(hcd->irq);
+
 	spin_lock_irqsave(&hsotg->lock, flags);
+	/* Ensure hcd is disconnected */
+	dwc2_hcd_disconnect(hsotg);
 	dwc2_hcd_stop(hsotg);
+	hsotg->lx_state = DWC2_L3;
+	hcd->state = HC_STATE_HALT;
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 
 	usleep_range(1000, 3000);
@@ -2326,17 +2378,125 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd)
 static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 {
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
+	unsigned long flags;
+	int ret = 0;
+	u32 hprt0;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	if (hsotg->lx_state != DWC2_L0)
+		goto unlock;
+
+	if (!HCD_HW_ACCESSIBLE(hcd))
+		goto unlock;
+
+	if (!hsotg->core_params->hibernation)
+		goto skip_power_saving;
 
+	/*
+	 * Drive USB suspend and disable port Power
+	 * if usb bus is not suspended.
+	 */
+	if (!hsotg->bus_suspended) {
+		hprt0 = dwc2_read_hprt0(hsotg);
+		hprt0 |= HPRT0_SUSP;
+		hprt0 &= ~HPRT0_PWR;
+		dwc2_writel(hprt0, hsotg->regs + HPRT0);
+	}
+
+	/* Enter hibernation */
+	ret = dwc2_enter_hibernation(hsotg);
+	if (ret) {
+		if (ret != -ENOTSUPP)
+			dev_err(hsotg->dev,
+				"enter hibernation failed\n");
+		goto skip_power_saving;
+	}
+
+	/* Ask phy to be suspended */
+	if (!IS_ERR_OR_NULL(hsotg->uphy)) {
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		usb_phy_set_suspend(hsotg->uphy, true);
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
+
+	/* After entering hibernation, hardware is no more accessible */
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+skip_power_saving:
 	hsotg->lx_state = DWC2_L2;
-	return 0;
+unlock:
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	return ret;
 }
 
 static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 {
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&hsotg->lock, flags);
+
+	if (hsotg->lx_state != DWC2_L2)
+		goto unlock;
+
+	if (!hsotg->core_params->hibernation) {
+		hsotg->lx_state = DWC2_L0;
+		goto unlock;
+	}
+
+	/*
+	 * Set HW accessible bit before powering on the controller
+	 * since an interrupt may rise.
+	 */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+	/*
+	 * Enable power if not already done.
+	 * This must not be spinlocked since duration
+	 * of this call is unknown.
+	 */
+	if (!IS_ERR_OR_NULL(hsotg->uphy)) {
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		usb_phy_set_suspend(hsotg->uphy, false);
+		spin_lock_irqsave(&hsotg->lock, flags);
+	}
+
+	/* Exit hibernation */
+	ret = dwc2_exit_hibernation(hsotg, true);
+	if (ret && (ret != -ENOTSUPP))
+		dev_err(hsotg->dev, "exit hibernation failed\n");
 
 	hsotg->lx_state = DWC2_L0;
-	return 0;
+
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	if (hsotg->bus_suspended) {
+		spin_lock_irqsave(&hsotg->lock, flags);
+		hsotg->flags.b.port_suspend_change = 1;
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		dwc2_port_resume(hsotg);
+	} else {
+		/* Wait for controller to correctly update D+/D- level */
+		usleep_range(3000, 5000);
+
+		/*
+		 * Clear Port Enable and Port Status changes.
+		 * Enable Port Power.
+		 */
+		dwc2_writel(HPRT0_PWR | HPRT0_CONNDET |
+				HPRT0_ENACHG, hsotg->regs + HPRT0);
+		/* Wait for controller to detect Port Connect */
+		usleep_range(5000, 7000);
+	}
+
+	return ret;
+unlock:
+	spin_unlock_irqrestore(&hsotg->lock, flags);
+
+	return ret;
 }
 
 /* Returns the current frame number */
@@ -2790,17 +2950,17 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg)
 		hsotg->status_buf = NULL;
 	}
 
-	ahbcfg = readl(hsotg->regs + GAHBCFG);
+	ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG);
 
 	/* Disable all interrupts */
 	ahbcfg &= ~GAHBCFG_GLBL_INTR_EN;
-	writel(ahbcfg, hsotg->regs + GAHBCFG);
-	writel(0, hsotg->regs + GINTMSK);
+	dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG);
+	dwc2_writel(0, hsotg->regs + GINTMSK);
 
 	if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) {
-		dctl = readl(hsotg->regs + DCTL);
+		dctl = dwc2_readl(hsotg->regs + DCTL);
 		dctl |= DCTL_SFTDISCON;
-		writel(dctl, hsotg->regs + DCTL);
+		dwc2_writel(dctl, hsotg->regs + DCTL);
 	}
 
 	if (hsotg->wq_otg) {
@@ -2841,7 +3001,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq)
 
 	retval = -ENOMEM;
 
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg);
 
 #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index fc1054965552aca51fa7f9bcdf87bae769077437..f105bada2fd13bddb7005a3a36936bd21a4cf5a5 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -371,10 +371,10 @@ static inline struct usb_hcd *dwc2_hsotg_to_hcd(struct dwc2_hsotg *hsotg)
  */
 static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
 {
-	u32 mask = readl(hsotg->regs + HCINTMSK(chnum));
+	u32 mask = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
 
 	mask &= ~intr;
-	writel(mask, hsotg->regs + HCINTMSK(chnum));
+	dwc2_writel(mask, hsotg->regs + HCINTMSK(chnum));
 }
 
 /*
@@ -382,11 +382,11 @@ static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
  */
 static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg)
 {
-	return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
+	return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
 }
 static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
 {
-	return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
+	return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
 }
 
 /*
@@ -395,7 +395,7 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
  */
 static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg)
 {
-	u32 hprt0 = readl(hsotg->regs + HPRT0);
+	u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 
 	hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG);
 	return hprt0;
@@ -580,7 +580,8 @@ static inline u16 dwc2_micro_frame_num(u16 frame)
  */
 static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg)
 {
-	return readl(hsotg->regs + GINTSTS) & readl(hsotg->regs + GINTMSK);
+	return dwc2_readl(hsotg->regs + GINTSTS) &
+	       dwc2_readl(hsotg->regs + GINTMSK);
 }
 
 static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb)
@@ -732,7 +733,7 @@ do {									\
 			   qtd_list_entry);				\
 	if (usb_pipeint(_qtd_->urb->pipe) &&				\
 	    (_qh_)->start_split_frame != 0 && !_qtd_->complete_split) {	\
-		_hfnum_.d32 = readl((_hcd_)->regs + HFNUM);		\
+		_hfnum_.d32 = dwc2_readl((_hcd_)->regs + HFNUM);	\
 		switch (_hfnum_.b.frnum & 0x7) {			\
 		case 7:							\
 			(_hcd_)->hfnum_7_samples_##_letter_++;		\
diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c
index 3376177e4d3c0c8b1998829ae79a47dcab953a9e..78993aba9335c7ec3263e4dcf82e88254c49895f 100644
--- a/drivers/usb/dwc2/hcd_ddma.c
+++ b/drivers/usb/dwc2/hcd_ddma.c
@@ -169,19 +169,19 @@ static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en)
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	if (hcfg & HCFG_PERSCHEDENA) {
 		/* already enabled */
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 		return;
 	}
 
-	writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR);
+	dwc2_writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR);
 
 	hcfg &= ~HCFG_FRLISTEN_MASK;
 	hcfg |= fr_list_en | HCFG_PERSCHEDENA;
 	dev_vdbg(hsotg->dev, "Enabling Periodic schedule\n");
-	writel(hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hcfg, hsotg->regs + HCFG);
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 }
@@ -193,7 +193,7 @@ static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg)
 
 	spin_lock_irqsave(&hsotg->lock, flags);
 
-	hcfg = readl(hsotg->regs + HCFG);
+	hcfg = dwc2_readl(hsotg->regs + HCFG);
 	if (!(hcfg & HCFG_PERSCHEDENA)) {
 		/* already disabled */
 		spin_unlock_irqrestore(&hsotg->lock, flags);
@@ -202,7 +202,7 @@ static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg)
 
 	hcfg &= ~HCFG_PERSCHEDENA;
 	dev_vdbg(hsotg->dev, "Disabling Periodic schedule\n");
-	writel(hcfg, hsotg->regs + HCFG);
+	dwc2_writel(hcfg, hsotg->regs + HCFG);
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 }
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 4cc95df4262d27eed328ea904b347e4ee520351f..bda0b21b850f695627efb5b1e70ae0e63de39638 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -148,7 +148,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
 		dwc2_hcd_queue_transactions(hsotg, tr_type);
 
 	/* Clear interrupt */
-	writel(GINTSTS_SOF, hsotg->regs + GINTSTS);
+	dwc2_writel(GINTSTS_SOF, hsotg->regs + GINTSTS);
 }
 
 /*
@@ -164,7 +164,7 @@ static void dwc2_rx_fifo_level_intr(struct dwc2_hsotg *hsotg)
 	if (dbg_perio())
 		dev_vdbg(hsotg->dev, "--RxFIFO Level Interrupt--\n");
 
-	grxsts = readl(hsotg->regs + GRXSTSP);
+	grxsts = dwc2_readl(hsotg->regs + GRXSTSP);
 	chnum = (grxsts & GRXSTS_HCHNUM_MASK) >> GRXSTS_HCHNUM_SHIFT;
 	chan = hsotg->hc_ptr_array[chnum];
 	if (!chan) {
@@ -247,11 +247,11 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 	dev_vdbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
 
 	/* Every time when port enables calculate HFIR.FrInterval */
-	hfir = readl(hsotg->regs + HFIR);
+	hfir = dwc2_readl(hsotg->regs + HFIR);
 	hfir &= ~HFIR_FRINT_MASK;
 	hfir |= dwc2_calc_frame_interval(hsotg) << HFIR_FRINT_SHIFT &
 		HFIR_FRINT_MASK;
-	writel(hfir, hsotg->regs + HFIR);
+	dwc2_writel(hfir, hsotg->regs + HFIR);
 
 	/* Check if we need to adjust the PHY clock speed for low power */
 	if (!params->host_support_fs_ls_low_power) {
@@ -260,7 +260,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 		return;
 	}
 
-	usbcfg = readl(hsotg->regs + GUSBCFG);
+	usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
 	prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 
 	if (prtspd == HPRT0_SPD_LOW_SPEED || prtspd == HPRT0_SPD_FULL_SPEED) {
@@ -268,11 +268,11 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 		if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL)) {
 			/* Set PHY low power clock select for FS/LS devices */
 			usbcfg |= GUSBCFG_PHY_LP_CLK_SEL;
-			writel(usbcfg, hsotg->regs + GUSBCFG);
+			dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 			do_reset = 1;
 		}
 
-		hcfg = readl(hsotg->regs + HCFG);
+		hcfg = dwc2_readl(hsotg->regs + HCFG);
 		fslspclksel = (hcfg & HCFG_FSLSPCLKSEL_MASK) >>
 			      HCFG_FSLSPCLKSEL_SHIFT;
 
@@ -286,7 +286,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 				fslspclksel = HCFG_FSLSPCLKSEL_6_MHZ;
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT;
-				writel(hcfg, hsotg->regs + HCFG);
+				dwc2_writel(hcfg, hsotg->regs + HCFG);
 				do_reset = 1;
 			}
 		} else {
@@ -297,7 +297,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 				fslspclksel = HCFG_FSLSPCLKSEL_48_MHZ;
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT;
-				writel(hcfg, hsotg->regs + HCFG);
+				dwc2_writel(hcfg, hsotg->regs + HCFG);
 				do_reset = 1;
 			}
 		}
@@ -305,7 +305,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0,
 		/* Not low power */
 		if (usbcfg & GUSBCFG_PHY_LP_CLK_SEL) {
 			usbcfg &= ~GUSBCFG_PHY_LP_CLK_SEL;
-			writel(usbcfg, hsotg->regs + GUSBCFG);
+			dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 			do_reset = 1;
 		}
 	}
@@ -332,7 +332,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
 
 	dev_vdbg(hsotg->dev, "--Port Interrupt--\n");
 
-	hprt0 = readl(hsotg->regs + HPRT0);
+	hprt0 = dwc2_readl(hsotg->regs + HPRT0);
 	hprt0_modify = hprt0;
 
 	/*
@@ -388,7 +388,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg)
 	}
 
 	/* Clear Port Interrupts */
-	writel(hprt0_modify, hsotg->regs + HPRT0);
+	dwc2_writel(hprt0_modify, hsotg->regs + HPRT0);
 }
 
 /*
@@ -408,7 +408,7 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg,
 {
 	u32 hctsiz, count, length;
 
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 
 	if (halt_status == DWC2_HC_XFER_COMPLETE) {
 		if (chan->ep_is_in) {
@@ -491,7 +491,7 @@ static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg,
 		urb->status = 0;
 	}
 
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 	dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n",
 		 __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum);
 	dev_vdbg(hsotg->dev, "  chan->xfer_len %d\n", chan->xfer_len);
@@ -514,7 +514,7 @@ void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
 			       struct dwc2_host_chan *chan, int chnum,
 			       struct dwc2_qtd *qtd)
 {
-	u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	u32 hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 	u32 pid = (hctsiz & TSIZ_SC_MC_PID_MASK) >> TSIZ_SC_MC_PID_SHIFT;
 
 	if (chan->ep_type != USB_ENDPOINT_XFER_CONTROL) {
@@ -771,9 +771,9 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
 		}
 	}
 
-	haintmsk = readl(hsotg->regs + HAINTMSK);
+	haintmsk = dwc2_readl(hsotg->regs + HAINTMSK);
 	haintmsk &= ~(1 << chan->hc_num);
-	writel(haintmsk, hsotg->regs + HAINTMSK);
+	dwc2_writel(haintmsk, hsotg->regs + HAINTMSK);
 
 	/* Try to queue more transfers now that there's a free channel */
 	tr_type = dwc2_hcd_select_transactions(hsotg);
@@ -820,9 +820,9 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
 			 * is enabled so that the non-periodic schedule will
 			 * be processed
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_NPTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		} else {
 			dev_vdbg(hsotg->dev, "isoc/intr\n");
 			/*
@@ -839,9 +839,9 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
 			 * enabled so that the periodic schedule will be
 			 * processed
 			 */
-			gintmsk = readl(hsotg->regs + GINTMSK);
+			gintmsk = dwc2_readl(hsotg->regs + GINTMSK);
 			gintmsk |= GINTSTS_PTXFEMP;
-			writel(gintmsk, hsotg->regs + GINTMSK);
+			dwc2_writel(gintmsk, hsotg->regs + GINTMSK);
 		}
 	}
 }
@@ -906,7 +906,7 @@ static void dwc2_complete_periodic_xfer(struct dwc2_hsotg *hsotg,
 					struct dwc2_qtd *qtd,
 					enum dwc2_halt_status halt_status)
 {
-	u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	u32 hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 
 	qtd->error_count = 0;
 
@@ -1184,7 +1184,7 @@ static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg,
 
 	urb->actual_length += xfer_length;
 
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
 	dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n",
 		 __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum);
 	dev_vdbg(hsotg->dev, "  chan->start_pkt_count %d\n",
@@ -1505,10 +1505,10 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg,
 
 	dwc2_hc_handle_tt_clear(hsotg, chan, qtd);
 
-	hcchar = readl(hsotg->regs + HCCHAR(chnum));
-	hcsplt = readl(hsotg->regs + HCSPLT(chnum));
-	hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
-	hc_dma = readl(hsotg->regs + HCDMA(chnum));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum));
+	hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chnum));
+	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
+	hc_dma = dwc2_readl(hsotg->regs + HCDMA(chnum));
 
 	dev_err(hsotg->dev, "AHB ERROR, Channel %d\n", chnum);
 	dev_err(hsotg->dev, "  hcchar 0x%08x, hcsplt 0x%08x\n", hcchar, hcsplt);
@@ -1721,10 +1721,10 @@ static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg,
 		 * This code is here only as a check. This condition should
 		 * never happen. Ignore the halt if it does occur.
 		 */
-		hcchar = readl(hsotg->regs + HCCHAR(chnum));
-		hctsiz = readl(hsotg->regs + HCTSIZ(chnum));
-		hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
-		hcsplt = readl(hsotg->regs + HCSPLT(chnum));
+		hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum));
+		hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));
+		hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
+		hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chnum));
 		dev_dbg(hsotg->dev,
 			"%s: chan->halt_status DWC2_HC_XFER_NO_HALT_STATUS,\n",
 			 __func__);
@@ -1748,7 +1748,7 @@ static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg,
 	 * when the halt interrupt occurs. Halt the channel again if it does
 	 * occur.
 	 */
-	hcchar = readl(hsotg->regs + HCCHAR(chnum));
+	hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum));
 	if (hcchar & HCCHAR_CHDIS) {
 		dev_warn(hsotg->dev,
 			 "%s: hcchar.chdis set unexpectedly, hcchar 0x%08x, trying to halt again\n",
@@ -1808,7 +1808,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
 		return;
 	}
 
-	hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
+	hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
 
 	if (chan->hcint & HCINTMSK_XFERCOMPL) {
 		/*
@@ -1903,7 +1903,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg,
 				dev_err(hsotg->dev,
 					"hcint 0x%08x, intsts 0x%08x\n",
 					chan->hcint,
-					readl(hsotg->regs + GINTSTS));
+					dwc2_readl(hsotg->regs + GINTSTS));
 				goto error;
 			}
 		}
@@ -1949,6 +1949,24 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg,
 	}
 }
 
+/*
+ * Check if the given qtd is still the top of the list (and thus valid).
+ *
+ * If dwc2_hcd_qtd_unlink_and_free() has been called since we grabbed
+ * the qtd from the top of the list, this will return false (otherwise true).
+ */
+static bool dwc2_check_qtd_still_ok(struct dwc2_qtd *qtd, struct dwc2_qh *qh)
+{
+	struct dwc2_qtd *cur_head;
+
+	if (qh == NULL)
+		return false;
+
+	cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd,
+				    qtd_list_entry);
+	return (cur_head == qtd);
+}
+
 /* Handles interrupt for a specific Host Channel */
 static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 {
@@ -1958,11 +1976,11 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 
 	chan = hsotg->hc_ptr_array[chnum];
 
-	hcint = readl(hsotg->regs + HCINT(chnum));
-	hcintmsk = readl(hsotg->regs + HCINTMSK(chnum));
+	hcint = dwc2_readl(hsotg->regs + HCINT(chnum));
+	hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
 	if (!chan) {
 		dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n");
-		writel(hcint, hsotg->regs + HCINT(chnum));
+		dwc2_writel(hcint, hsotg->regs + HCINT(chnum));
 		return;
 	}
 
@@ -1974,7 +1992,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 			 hcint, hcintmsk, hcint & hcintmsk);
 	}
 
-	writel(hcint, hsotg->regs + HCINT(chnum));
+	dwc2_writel(hcint, hsotg->regs + HCINT(chnum));
 	chan->hcint = hcint;
 	hcint &= hcintmsk;
 
@@ -2031,27 +2049,59 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum)
 		 */
 		hcint &= ~HCINTMSK_NYET;
 	}
-	if (hcint & HCINTMSK_CHHLTD)
+
+	if (hcint & HCINTMSK_CHHLTD) {
 		dwc2_hc_chhltd_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_AHBERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_AHBERR) {
 		dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_STALL)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_STALL) {
 		dwc2_hc_stall_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_NAK)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_NAK) {
 		dwc2_hc_nak_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_ACK)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_ACK) {
 		dwc2_hc_ack_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_NYET)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_NYET) {
 		dwc2_hc_nyet_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_XACTERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_XACTERR) {
 		dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_BBLERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_BBLERR) {
 		dwc2_hc_babble_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_FRMOVRUN)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_FRMOVRUN) {
 		dwc2_hc_frmovrun_intr(hsotg, chan, chnum, qtd);
-	if (hcint & HCINTMSK_DATATGLERR)
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
+	if (hcint & HCINTMSK_DATATGLERR) {
 		dwc2_hc_datatglerr_intr(hsotg, chan, chnum, qtd);
+		if (!dwc2_check_qtd_still_ok(qtd, chan->qh))
+			goto exit;
+	}
 
+exit:
 	chan->hcint = 0;
 }
 
@@ -2066,7 +2116,7 @@ static void dwc2_hc_intr(struct dwc2_hsotg *hsotg)
 	u32 haint;
 	int i;
 
-	haint = readl(hsotg->regs + HAINT);
+	haint = dwc2_readl(hsotg->regs + HAINT);
 	if (dbg_perio()) {
 		dev_vdbg(hsotg->dev, "%s()\n", __func__);
 
@@ -2134,8 +2184,8 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg)
 				 "DWC OTG HCD Finished Servicing Interrupts\n");
 			dev_vdbg(hsotg->dev,
 				 "DWC OTG HCD gintsts=0x%08x gintmsk=0x%08x\n",
-				 readl(hsotg->regs + GINTSTS),
-				 readl(hsotg->regs + GINTMSK));
+				 dwc2_readl(hsotg->regs + GINTSTS),
+				 dwc2_readl(hsotg->regs + GINTMSK));
 		}
 	}
 
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 3ad63d392e13f51c5e9aa8a31069de3795cdf86f..7d8d06cfe3c1df1d5bc1a5534205464d89f65a56 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -106,6 +106,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
 				USB_SPEED_HIGH : dev_speed, qh->ep_is_in,
 				qh->ep_type == USB_ENDPOINT_XFER_ISOC,
 				bytecount));
+
+		/* Ensure frame_number corresponds to the reality */
+		hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg);
 		/* Start in a slightly future (micro)frame */
 		qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number,
 						     SCHEDULE_SLOP);
@@ -115,7 +118,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
 		if (qh->ep_type == USB_ENDPOINT_XFER_INT)
 			qh->interval = 8;
 #endif
-		hprt = readl(hsotg->regs + HPRT0);
+		hprt = dwc2_readl(hsotg->regs + HPRT0);
 		prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
 		if (prtspd == HPRT0_SPD_HIGH_SPEED &&
 		    (dev_speed == USB_SPEED_LOW ||
@@ -583,6 +586,14 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 		/* QH already in a schedule */
 		return 0;
 
+	if (!dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number) &&
+			!hsotg->frame_number) {
+		dev_dbg(hsotg->dev,
+				"reset frame number counter\n");
+		qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number,
+				SCHEDULE_SLOP);
+	}
+
 	/* Add the new QH to the appropriate schedule */
 	if (dwc2_qh_is_non_per(qh)) {
 		/* Always start in inactive schedule */
@@ -595,9 +606,9 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 	if (status)
 		return status;
 	if (!hsotg->periodic_qh_count) {
-		intr_mask = readl(hsotg->regs + GINTMSK);
+		intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 		intr_mask |= GINTSTS_SOF;
-		writel(intr_mask, hsotg->regs + GINTMSK);
+		dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
 	}
 	hsotg->periodic_qh_count++;
 
@@ -632,9 +643,9 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 	dwc2_deschedule_periodic(hsotg, qh);
 	hsotg->periodic_qh_count--;
 	if (!hsotg->periodic_qh_count) {
-		intr_mask = readl(hsotg->regs + GINTMSK);
+		intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 		intr_mask &= ~GINTSTS_SOF;
-		writel(intr_mask, hsotg->regs + GINTMSK);
+		dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
 	}
 }
 
diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h
index d0a5ed8fa15a481bb7c659367b9da5f9212fbb59..553f24606c43c9ef77306bc97d1250535e878679 100644
--- a/drivers/usb/dwc2/hw.h
+++ b/drivers/usb/dwc2/hw.h
@@ -142,6 +142,7 @@
 #define GINTSTS_RESETDET		(1 << 23)
 #define GINTSTS_FET_SUSP		(1 << 22)
 #define GINTSTS_INCOMPL_IP		(1 << 21)
+#define GINTSTS_INCOMPL_SOOUT		(1 << 21)
 #define GINTSTS_INCOMPL_SOIN		(1 << 20)
 #define GINTSTS_OEPINT			(1 << 19)
 #define GINTSTS_IEPINT			(1 << 18)
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 90935304185a01ab93bb28d9ad7ac4a2b5364e6e..5859b0fa19ee3f907b2bfa93945a6378ae10911a 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -37,11 +37,14 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_data/s3c-hsotg.h>
 
 #include <linux/usb/of.h>
 
@@ -111,6 +114,145 @@ static const struct dwc2_core_params params_rk3066 = {
 	.hibernation			= -1,
 };
 
+static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
+{
+	struct platform_device *pdev = to_platform_device(hsotg->dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
+				    hsotg->supplies);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(hsotg->clk);
+	if (ret)
+		return ret;
+
+	if (hsotg->uphy)
+		ret = usb_phy_init(hsotg->uphy);
+	else if (hsotg->plat && hsotg->plat->phy_init)
+		ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
+	else {
+		ret = phy_power_on(hsotg->phy);
+		if (ret == 0)
+			ret = phy_init(hsotg->phy);
+	}
+
+	return ret;
+}
+
+/**
+ * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources
+ * @hsotg: The driver state
+ *
+ * A wrapper for platform code responsible for controlling
+ * low-level USB platform resources (phy, clock, regulators)
+ */
+int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
+{
+	int ret = __dwc2_lowlevel_hw_enable(hsotg);
+
+	if (ret == 0)
+		hsotg->ll_hw_enabled = true;
+	return ret;
+}
+
+static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
+{
+	struct platform_device *pdev = to_platform_device(hsotg->dev);
+	int ret = 0;
+
+	if (hsotg->uphy)
+		usb_phy_shutdown(hsotg->uphy);
+	else if (hsotg->plat && hsotg->plat->phy_exit)
+		ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
+	else {
+		ret = phy_exit(hsotg->phy);
+		if (ret == 0)
+			ret = phy_power_off(hsotg->phy);
+	}
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(hsotg->clk);
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
+				     hsotg->supplies);
+
+	return ret;
+}
+
+/**
+ * dwc2_lowlevel_hw_disable - disable platform lowlevel hw resources
+ * @hsotg: The driver state
+ *
+ * A wrapper for platform code responsible for controlling
+ * low-level USB platform resources (phy, clock, regulators)
+ */
+int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
+{
+	int ret = __dwc2_lowlevel_hw_disable(hsotg);
+
+	if (ret == 0)
+		hsotg->ll_hw_enabled = false;
+	return ret;
+}
+
+static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
+{
+	int i, ret;
+
+	/* Set default UTMI width */
+	hsotg->phyif = GUSBCFG_PHYIF16;
+
+	/*
+	 * Attempt to find a generic PHY, then look for an old style
+	 * USB PHY and then fall back to pdata
+	 */
+	hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
+	if (IS_ERR(hsotg->phy)) {
+		hsotg->phy = NULL;
+		hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
+		if (IS_ERR(hsotg->uphy))
+			hsotg->uphy = NULL;
+		else
+			hsotg->plat = dev_get_platdata(hsotg->dev);
+	}
+
+	if (hsotg->phy) {
+		/*
+		 * If using the generic PHY framework, check if the PHY bus
+		 * width is 8-bit and set the phyif appropriately.
+		 */
+		if (phy_get_bus_width(hsotg->phy) == 8)
+			hsotg->phyif = GUSBCFG_PHYIF8;
+	}
+
+	if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) {
+		dev_err(hsotg->dev, "no platform data or transceiver defined\n");
+		return -EPROBE_DEFER;
+	}
+
+	/* Clock */
+	hsotg->clk = devm_clk_get(hsotg->dev, "otg");
+	if (IS_ERR(hsotg->clk)) {
+		hsotg->clk = NULL;
+		dev_dbg(hsotg->dev, "cannot get otg clock\n");
+	}
+
+	/* Regulators */
+	for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++)
+		hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i];
+
+	ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies),
+				      hsotg->supplies);
+	if (ret) {
+		dev_err(hsotg->dev, "failed to request supplies: %d\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
 /**
  * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the
  * DWC_otg driver
@@ -130,7 +272,10 @@ static int dwc2_driver_remove(struct platform_device *dev)
 	if (hsotg->hcd_enabled)
 		dwc2_hcd_remove(hsotg);
 	if (hsotg->gadget_enabled)
-		s3c_hsotg_remove(hsotg);
+		dwc2_hsotg_remove(hsotg);
+
+	if (hsotg->ll_hw_enabled)
+		dwc2_lowlevel_hw_disable(hsotg);
 
 	return 0;
 }
@@ -163,8 +308,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
 	struct dwc2_core_params defparams;
 	struct dwc2_hsotg *hsotg;
 	struct resource *res;
-	struct phy *phy;
-	struct usb_phy *uphy;
 	int retval;
 	int irq;
 
@@ -220,34 +363,25 @@ static int dwc2_driver_probe(struct platform_device *dev)
 	dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
 		(unsigned long)res->start, hsotg->regs);
 
-	hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node);
-
-	/*
-	 * Attempt to find a generic PHY, then look for an old style
-	 * USB PHY
-	 */
-	phy = devm_phy_get(&dev->dev, "usb2-phy");
-	if (IS_ERR(phy)) {
-		hsotg->phy = NULL;
-		uphy = devm_usb_get_phy(&dev->dev, USB_PHY_TYPE_USB2);
-		if (IS_ERR(uphy))
-			hsotg->uphy = NULL;
-		else
-			hsotg->uphy = uphy;
-	} else {
-		hsotg->phy = phy;
-		phy_power_on(hsotg->phy);
-		phy_init(hsotg->phy);
+	hsotg->dr_mode = usb_get_dr_mode(&dev->dev);
+	if (IS_ENABLED(CONFIG_USB_DWC2_HOST) &&
+			hsotg->dr_mode != USB_DR_MODE_HOST) {
+		hsotg->dr_mode = USB_DR_MODE_HOST;
+		dev_warn(hsotg->dev,
+			"Configuration mismatch. Forcing host mode\n");
+	} else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) &&
+			hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) {
+		hsotg->dr_mode = USB_DR_MODE_PERIPHERAL;
+		dev_warn(hsotg->dev,
+			"Configuration mismatch. Forcing peripheral mode\n");
 	}
 
-	spin_lock_init(&hsotg->lock);
-	mutex_init(&hsotg->init_mutex);
-
-	/* Detect config values from hardware */
-	retval = dwc2_get_hwparams(hsotg);
+	retval = dwc2_lowlevel_hw_init(hsotg);
 	if (retval)
 		return retval;
 
+	spin_lock_init(&hsotg->lock);
+
 	hsotg->core_params = devm_kzalloc(&dev->dev,
 				sizeof(*hsotg->core_params), GFP_KERNEL);
 	if (!hsotg->core_params)
@@ -255,13 +389,22 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
 	dwc2_set_all_params(hsotg->core_params, -1);
 
+	retval = dwc2_lowlevel_hw_enable(hsotg);
+	if (retval)
+		return retval;
+
+	/* Detect config values from hardware */
+	retval = dwc2_get_hwparams(hsotg);
+	if (retval)
+		goto error;
+
 	/* Validate parameter values */
 	dwc2_set_parameters(hsotg, params);
 
 	if (hsotg->dr_mode != USB_DR_MODE_HOST) {
 		retval = dwc2_gadget_init(hsotg, irq);
 		if (retval)
-			return retval;
+			goto error;
 		hsotg->gadget_enabled = 1;
 	}
 
@@ -269,8 +412,8 @@ static int dwc2_driver_probe(struct platform_device *dev)
 		retval = dwc2_hcd_init(hsotg, irq);
 		if (retval) {
 			if (hsotg->gadget_enabled)
-				s3c_hsotg_remove(hsotg);
-			return retval;
+				dwc2_hsotg_remove(hsotg);
+			goto error;
 		}
 		hsotg->hcd_enabled = 1;
 	}
@@ -279,6 +422,14 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
 	dwc2_debugfs_init(hsotg);
 
+	/* Gadget code manages lowlevel hw on its own */
+	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+		dwc2_lowlevel_hw_disable(hsotg);
+
+	return 0;
+
+error:
+	dwc2_lowlevel_hw_disable(hsotg);
 	return retval;
 }
 
@@ -287,15 +438,12 @@ static int __maybe_unused dwc2_suspend(struct device *dev)
 	struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 	int ret = 0;
 
-	if (dwc2_is_device_mode(dwc2)) {
-		ret = s3c_hsotg_suspend(dwc2);
-	} else {
-		if (dwc2->lx_state == DWC2_L0)
-			return 0;
-		phy_exit(dwc2->phy);
-		phy_power_off(dwc2->phy);
+	if (dwc2_is_device_mode(dwc2))
+		dwc2_hsotg_suspend(dwc2);
+
+	if (dwc2->ll_hw_enabled)
+		ret = __dwc2_lowlevel_hw_disable(dwc2);
 
-	}
 	return ret;
 }
 
@@ -304,13 +452,15 @@ static int __maybe_unused dwc2_resume(struct device *dev)
 	struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev);
 	int ret = 0;
 
-	if (dwc2_is_device_mode(dwc2)) {
-		ret = s3c_hsotg_resume(dwc2);
-	} else {
-		phy_power_on(dwc2->phy);
-		phy_init(dwc2->phy);
-
+	if (dwc2->ll_hw_enabled) {
+		ret = __dwc2_lowlevel_hw_enable(dwc2);
+		if (ret)
+			return ret;
 	}
+
+	if (dwc2_is_device_mode(dwc2))
+		ret = dwc2_hsotg_resume(dwc2);
+
 	return ret;
 }
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 064123e445664a5e23bb28ba48cfb1755ec7fb88..22b4797383cd0021953b58e1f8d60178eeb89389 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -34,6 +34,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/acpi.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -143,6 +144,32 @@ static int dwc3_soft_reset(struct dwc3 *dwc)
 	return 0;
 }
 
+/*
+ * dwc3_frame_length_adjustment - Adjusts frame length if required
+ * @dwc3: Pointer to our controller context structure
+ * @fladj: Value of GFLADJ_30MHZ to adjust frame length
+ */
+static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
+{
+	u32 reg;
+	u32 dft;
+
+	if (dwc->revision < DWC3_REVISION_250A)
+		return;
+
+	if (fladj == 0)
+		return;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+	dft = reg & DWC3_GFLADJ_30MHZ_MASK;
+	if (!dev_WARN_ONCE(dwc->dev, dft == fladj,
+	    "request value same as default, ignoring\n")) {
+		reg &= ~DWC3_GFLADJ_30MHZ_MASK;
+		reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj;
+		dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+	}
+}
+
 /**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
@@ -488,6 +515,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
 	if (dwc->dis_u2_susphy_quirk)
 		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
+	if (dwc->dis_enblslpm_quirk)
+		reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
 	return 0;
@@ -507,12 +537,18 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
 	reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
 	/* This should read as U3 followed by revision number */
-	if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
+	if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
+		/* Detected DWC_usb3 IP */
+		dwc->revision = reg;
+	} else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
+		/* Detected DWC_usb31 IP */
+		dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
+		dwc->revision |= DWC3_REVISION_IS_DWC31;
+	} else {
 		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
 		ret = -ENODEV;
 		goto err0;
 	}
-	dwc->revision = reg;
 
 	/*
 	 * Write Linux Version Code to our GUID register so it's easy to figure
@@ -773,12 +809,12 @@ static int dwc3_probe(struct platform_device *pdev)
 {
 	struct device		*dev = &pdev->dev;
 	struct dwc3_platform_data *pdata = dev_get_platdata(dev);
-	struct device_node	*node = dev->of_node;
 	struct resource		*res;
 	struct dwc3		*dwc;
 	u8			lpm_nyet_threshold;
 	u8			tx_de_emphasis;
 	u8			hird_threshold;
+	u32			fladj = 0;
 
 	int			ret;
 
@@ -842,51 +878,56 @@ static int dwc3_probe(struct platform_device *pdev)
 	 */
 	hird_threshold = 12;
 
-	if (node) {
-		dwc->maximum_speed = of_usb_get_maximum_speed(node);
-		dwc->has_lpm_erratum = of_property_read_bool(node,
+	dwc->maximum_speed = usb_get_maximum_speed(dev);
+	dwc->dr_mode = usb_get_dr_mode(dev);
+
+	dwc->has_lpm_erratum = device_property_read_bool(dev,
 				"snps,has-lpm-erratum");
-		of_property_read_u8(node, "snps,lpm-nyet-threshold",
+	device_property_read_u8(dev, "snps,lpm-nyet-threshold",
 				&lpm_nyet_threshold);
-		dwc->is_utmi_l1_suspend = of_property_read_bool(node,
+	dwc->is_utmi_l1_suspend = device_property_read_bool(dev,
 				"snps,is-utmi-l1-suspend");
-		of_property_read_u8(node, "snps,hird-threshold",
+	device_property_read_u8(dev, "snps,hird-threshold",
 				&hird_threshold);
-		dwc->usb3_lpm_capable = of_property_read_bool(node,
+	dwc->usb3_lpm_capable = device_property_read_bool(dev,
 				"snps,usb3_lpm_capable");
 
-		dwc->needs_fifo_resize = of_property_read_bool(node,
+	dwc->needs_fifo_resize = device_property_read_bool(dev,
 				"tx-fifo-resize");
-		dwc->dr_mode = of_usb_get_dr_mode(node);
 
-		dwc->disable_scramble_quirk = of_property_read_bool(node,
+	dwc->disable_scramble_quirk = device_property_read_bool(dev,
 				"snps,disable_scramble_quirk");
-		dwc->u2exit_lfps_quirk = of_property_read_bool(node,
+	dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
 				"snps,u2exit_lfps_quirk");
-		dwc->u2ss_inp3_quirk = of_property_read_bool(node,
+	dwc->u2ss_inp3_quirk = device_property_read_bool(dev,
 				"snps,u2ss_inp3_quirk");
-		dwc->req_p1p2p3_quirk = of_property_read_bool(node,
+	dwc->req_p1p2p3_quirk = device_property_read_bool(dev,
 				"snps,req_p1p2p3_quirk");
-		dwc->del_p1p2p3_quirk = of_property_read_bool(node,
+	dwc->del_p1p2p3_quirk = device_property_read_bool(dev,
 				"snps,del_p1p2p3_quirk");
-		dwc->del_phy_power_chg_quirk = of_property_read_bool(node,
+	dwc->del_phy_power_chg_quirk = device_property_read_bool(dev,
 				"snps,del_phy_power_chg_quirk");
-		dwc->lfps_filter_quirk = of_property_read_bool(node,
+	dwc->lfps_filter_quirk = device_property_read_bool(dev,
 				"snps,lfps_filter_quirk");
-		dwc->rx_detect_poll_quirk = of_property_read_bool(node,
+	dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
 				"snps,rx_detect_poll_quirk");
-		dwc->dis_u3_susphy_quirk = of_property_read_bool(node,
+	dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
 				"snps,dis_u3_susphy_quirk");
-		dwc->dis_u2_susphy_quirk = of_property_read_bool(node,
+	dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
 				"snps,dis_u2_susphy_quirk");
+	dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
+				"snps,dis_enblslpm_quirk");
 
-		dwc->tx_de_emphasis_quirk = of_property_read_bool(node,
+	dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
 				"snps,tx_de_emphasis_quirk");
-		of_property_read_u8(node, "snps,tx_de_emphasis",
+	device_property_read_u8(dev, "snps,tx_de_emphasis",
 				&tx_de_emphasis);
-		of_property_read_string(node, "snps,hsphy_interface",
-					&dwc->hsphy_interface);
-	} else if (pdata) {
+	device_property_read_string(dev, "snps,hsphy_interface",
+				    &dwc->hsphy_interface);
+	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
+				 &fladj);
+
+	if (pdata) {
 		dwc->maximum_speed = pdata->maximum_speed;
 		dwc->has_lpm_erratum = pdata->has_lpm_erratum;
 		if (pdata->lpm_nyet_threshold)
@@ -909,12 +950,14 @@ static int dwc3_probe(struct platform_device *pdev)
 		dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk;
 		dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk;
 		dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk;
+		dwc->dis_enblslpm_quirk = pdata->dis_enblslpm_quirk;
 
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		if (pdata->tx_de_emphasis)
 			tx_de_emphasis = pdata->tx_de_emphasis;
 
 		dwc->hsphy_interface = pdata->hsphy_interface;
+		fladj = pdata->fladj_value;
 	}
 
 	/* default to superspeed if no maximum_speed passed */
@@ -971,6 +1014,9 @@ static int dwc3_probe(struct platform_device *pdev)
 		goto err1;
 	}
 
+	/* Adjust Frame Length */
+	dwc3_frame_length_adjustment(dwc, fladj);
+
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
 	usb_phy_set_suspend(dwc->usb3_phy, 0);
 	ret = phy_power_on(dwc->usb2_generic_phy);
@@ -1091,6 +1137,8 @@ static int dwc3_suspend(struct device *dev)
 	phy_exit(dwc->usb2_generic_phy);
 	phy_exit(dwc->usb3_generic_phy);
 
+	pinctrl_pm_select_sleep_state(dev);
+
 	return 0;
 }
 
@@ -1100,6 +1148,8 @@ static int dwc3_resume(struct device *dev)
 	unsigned long	flags;
 	int		ret;
 
+	pinctrl_pm_select_default_state(dev);
+
 	usb_phy_init(dwc->usb3_phy);
 	usb_phy_init(dwc->usb2_phy);
 	ret = phy_init(dwc->usb2_generic_phy);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 0447788845856e57190561b1117253200c1050a6..36f1cb74588c5b7bff230e3ed91e42f73c3b47e8 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -108,6 +108,9 @@
 #define DWC3_GPRTBIMAP_FS0	0xc188
 #define DWC3_GPRTBIMAP_FS1	0xc18c
 
+#define DWC3_VER_NUMBER		0xc1a0
+#define DWC3_VER_TYPE		0xc1a4
+
 #define DWC3_GUSB2PHYCFG(n)	(0xc200 + (n * 0x04))
 #define DWC3_GUSB2I2CCTL(n)	(0xc240 + (n * 0x04))
 
@@ -124,6 +127,7 @@
 #define DWC3_GEVNTCOUNT(n)	(0xc40c + (n * 0x10))
 
 #define DWC3_GHWPARAMS8		0xc600
+#define DWC3_GFLADJ		0xc630
 
 /* Device Registers */
 #define DWC3_DCFG		0xc700
@@ -175,6 +179,7 @@
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB2PHYCFG_SUSPHY		(1 << 6)
 #define DWC3_GUSB2PHYCFG_ULPI_UTMI	(1 << 4)
+#define DWC3_GUSB2PHYCFG_ENBLSLPM	(1 << 8)
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ	(1 << 25)
@@ -234,6 +239,10 @@
 /* Global HWPARAMS6 Register */
 #define DWC3_GHWPARAMS6_EN_FPGA			(1 << 7)
 
+/* Global Frame Length Adjustment Register */
+#define DWC3_GFLADJ_30MHZ_SDBND_SEL		(1 << 7)
+#define DWC3_GFLADJ_30MHZ_MASK			0x3f
+
 /* Device Configuration Register */
 #define DWC3_DCFG_DEVADDR(addr)	((addr) << 3)
 #define DWC3_DCFG_DEVADDR_MASK	DWC3_DCFG_DEVADDR(0x7f)
@@ -712,6 +721,8 @@ struct dwc3_scratchpad_array {
  * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk
  * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
+ * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
+ *                      disabling the suspend signal to the PHY.
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 	0	- -6dB de-emphasis
@@ -766,6 +777,14 @@ struct dwc3 {
 	u32			num_event_buffers;
 	u32			u1u2;
 	u32			maximum_speed;
+
+	/*
+	 * All 3.1 IP version constants are greater than the 3.0 IP
+	 * version constants. This works for most version checks in
+	 * dwc3. However, in the future, this may not apply as
+	 * features may be developed on newer versions of the 3.0 IP
+	 * that are not in the 3.1 IP.
+	 */
 	u32			revision;
 
 #define DWC3_REVISION_173A	0x5533173a
@@ -788,6 +807,13 @@ struct dwc3 {
 #define DWC3_REVISION_270A	0x5533270a
 #define DWC3_REVISION_280A	0x5533280a
 
+/*
+ * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really
+ * just so dwc31 revisions are always larger than dwc3.
+ */
+#define DWC3_REVISION_IS_DWC31		0x80000000
+#define DWC3_USB31_REVISION_110A	(0x3131302a | DWC3_REVISION_IS_USB31)
+
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_state	ep0state;
 	enum dwc3_link_state	link_state;
@@ -841,6 +867,7 @@ struct dwc3 {
 	unsigned		rx_detect_poll_quirk:1;
 	unsigned		dis_u3_susphy_quirk:1;
 	unsigned		dis_u2_susphy_quirk:1;
+	unsigned		dis_enblslpm_quirk:1;
 
 	unsigned		tx_de_emphasis_quirk:1;
 	unsigned		tx_de_emphasis:2;
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index f62617999f3c7fb093ff09d18088560a6ecb003e..77a622cb48ab1555a87dfaf279f5d25368672e99 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -26,12 +26,14 @@
 
 #include "platform_data.h"
 
-#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3	0xabcd
-#define PCI_DEVICE_ID_INTEL_BYT		0x0f37
-#define PCI_DEVICE_ID_INTEL_MRFLD	0x119e
-#define PCI_DEVICE_ID_INTEL_BSW		0x22B7
-#define PCI_DEVICE_ID_INTEL_SPTLP	0x9d30
-#define PCI_DEVICE_ID_INTEL_SPTH	0xa130
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3		0xabcd
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI	0xabce
+#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31	0xabcf
+#define PCI_DEVICE_ID_INTEL_BYT			0x0f37
+#define PCI_DEVICE_ID_INTEL_MRFLD		0x119e
+#define PCI_DEVICE_ID_INTEL_BSW			0x22b7
+#define PCI_DEVICE_ID_INTEL_SPTLP		0x9d30
+#define PCI_DEVICE_ID_INTEL_SPTH		0xa130
 
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
 static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
@@ -106,6 +108,22 @@ static int dwc3_pci_quirks(struct pci_dev *pdev)
 		}
 	}
 
+	if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS &&
+	    (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 ||
+	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI ||
+	     pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) {
+
+		struct dwc3_platform_data pdata;
+
+		memset(&pdata, 0, sizeof(pdata));
+		pdata.usb3_lpm_capable = true;
+		pdata.has_lpm_erratum = true;
+		pdata.dis_enblslpm_quirk = true;
+
+		return platform_device_add_data(pci_get_drvdata(pdev), &pdata,
+						sizeof(pdata));
+	}
+
 	return 0;
 }
 
@@ -154,6 +172,7 @@ static int dwc3_pci_probe(struct pci_dev *pci,
 		goto err;
 
 	dwc3->dev.parent = dev;
+	ACPI_COMPANION_SET(&dwc3->dev, ACPI_COMPANION(dev));
 
 	ret = platform_device_add(dwc3);
 	if (ret) {
@@ -178,6 +197,14 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
 				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
 	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI),
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
+				PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31),
+	},
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), },
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
index de4d52f62517a8ec744c0897e97edc516bd8643f..5c0adb9c6fb27baa778615f17705ac6ab7896079 100644
--- a/drivers/usb/dwc3/dwc3-st.c
+++ b/drivers/usb/dwc3/dwc3-st.c
@@ -195,6 +195,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct device *dev = &pdev->dev;
 	struct device_node *node = dev->of_node, *child;
+	struct platform_device *child_pdev;
 	struct regmap *regmap;
 	int ret;
 
@@ -253,8 +254,6 @@ static int st_dwc3_probe(struct platform_device *pdev)
 		goto undo_softreset;
 	}
 
-	dwc3_data->dr_mode = of_usb_get_dr_mode(child);
-
 	/* Allocate and initialize the core */
 	ret = of_platform_populate(node, NULL, NULL, dev);
 	if (ret) {
@@ -262,6 +261,15 @@ static int st_dwc3_probe(struct platform_device *pdev)
 		goto undo_softreset;
 	}
 
+	child_pdev = of_find_device_by_node(child);
+	if (!child_pdev) {
+		dev_err(dev, "failed to find dwc3 core device\n");
+		ret = -ENODEV;
+		goto undo_softreset;
+	}
+
+	dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev);
+
 	/*
 	 * Configure the USB port as device or host according to the static
 	 * configuration passed from DT.
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1e8bdf8178113af9db2c556488224acf6504e853..55ba447fdf8bf56720eeac029ed4f96d932ee0ea 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -948,7 +948,6 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 		dwc3_trace(trace_dwc3_gadget, "%s: endpoint busy", dep->name);
 		return -EBUSY;
 	}
-	dep->flags &= ~DWC3_EP_PENDING_REQUEST;
 
 	/*
 	 * If we are getting here after a short-out-packet we don't enqueue any
@@ -1050,6 +1049,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	req->direction		= dep->direction;
 	req->epnum		= dep->number;
 
+	trace_dwc3_ep_queue(req);
+
 	/*
 	 * We only add to our list of requests now and
 	 * start consuming the list once we get XferNotReady
@@ -1069,6 +1070,19 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 
 	list_add_tail(&req->list, &dep->request_list);
 
+	/*
+	 * If there are no pending requests and the endpoint isn't already
+	 * busy, we will just start the request straight away.
+	 *
+	 * This will save one IRQ (XFER_NOT_READY) and possibly make it a
+	 * little bit faster.
+	 */
+	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+			!(dep->flags & DWC3_EP_BUSY)) {
+		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
+		goto out;
+	}
+
 	/*
 	 * There are a few special cases:
 	 *
@@ -1096,10 +1110,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 		}
 
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
-		if (ret && ret != -EBUSY)
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-		return ret;
+		if (!ret)
+			dep->flags &= ~DWC3_EP_PENDING_REQUEST;
+
+		goto out;
 	}
 
 	/*
@@ -1113,10 +1127,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 		WARN_ON_ONCE(!dep->resource_index);
 		ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index,
 				false);
-		if (ret && ret != -EBUSY)
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-		return ret;
+		goto out;
 	}
 
 	/*
@@ -1124,14 +1135,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	 * right away, otherwise host will not know we have streams to be
 	 * handled.
 	 */
-	if (dep->stream_capable) {
+	if (dep->stream_capable)
 		ret = __dwc3_gadget_kick_transfer(dep, 0, true);
-		if (ret && ret != -EBUSY)
-			dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
-					dep->name);
-	}
 
-	return 0;
+out:
+	if (ret && ret != -EBUSY)
+		dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
+				dep->name);
+	if (ret == -EBUSY)
+		ret = 0;
+
+	return ret;
 }
 
 static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
@@ -1159,8 +1173,6 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
 		goto out;
 	}
 
-	trace_dwc3_ep_queue(req);
-
 	ret = __dwc3_gadget_ep_queue(dep, req);
 
 out:
@@ -1872,27 +1884,32 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
 	unsigned int		i;
 	int			ret;
 
-	req = next_request(&dep->req_queued);
-	if (!req) {
-		WARN_ON_ONCE(1);
-		return 1;
-	}
-	i = 0;
 	do {
-		slot = req->start_slot + i;
-		if ((slot == DWC3_TRB_NUM - 1) &&
+		req = next_request(&dep->req_queued);
+		if (!req) {
+			WARN_ON_ONCE(1);
+			return 1;
+		}
+		i = 0;
+		do {
+			slot = req->start_slot + i;
+			if ((slot == DWC3_TRB_NUM - 1) &&
 				usb_endpoint_xfer_isoc(dep->endpoint.desc))
-			slot++;
-		slot %= DWC3_TRB_NUM;
-		trb = &dep->trb_pool[slot];
+				slot++;
+			slot %= DWC3_TRB_NUM;
+			trb = &dep->trb_pool[slot];
+
+			ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
+					event, status);
+			if (ret)
+				break;
+		} while (++i < req->request.num_mapped_sgs);
+
+		dwc3_gadget_giveback(dep, req, status);
 
-		ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
-				event, status);
 		if (ret)
 			break;
-	} while (++i < req->request.num_mapped_sgs);
-
-	dwc3_gadget_giveback(dep, req, status);
+	} while (1);
 
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 			list_empty(&dep->req_queued)) {
@@ -1955,6 +1972,14 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
 
 		dwc->u1u2 = 0;
 	}
+
+	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
+		int ret;
+
+		ret = __dwc3_gadget_kick_transfer(dep, 0, is_xfer_complete);
+		if (!ret || ret == -EBUSY)
+			return;
+	}
 }
 
 static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
@@ -1992,15 +2017,16 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
 		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
 			dwc3_gadget_start_isoc(dwc, dep, event);
 		} else {
+			int active;
 			int ret;
 
+			active = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE;
+
 			dwc3_trace(trace_dwc3_gadget, "%s: reason %s",
-					dep->name, event->status &
-					DEPEVT_STATUS_TRANSFER_ACTIVE
-					? "Transfer Active"
+					dep->name, active ? "Transfer Active"
 					: "Transfer Not Active");
 
-			ret = __dwc3_gadget_kick_transfer(dep, 0, 1);
+			ret = __dwc3_gadget_kick_transfer(dep, 0, !active);
 			if (!ret || ret == -EBUSY)
 				return;
 
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index d3614ecbb9ca284cf6304eee2291ec3ce03a7990..2bb4d3ad0e6b724d71ceae0261955a2551c6859b 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -42,9 +42,12 @@ struct dwc3_platform_data {
 	unsigned rx_detect_poll_quirk:1;
 	unsigned dis_u3_susphy_quirk:1;
 	unsigned dis_u2_susphy_quirk:1;
+	unsigned dis_enblslpm_quirk:1;
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
 
+	u32 fladj_value;
+
 	const char *hsphy_interface;
 };
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index bcf83c0a6e62b340899ea661955de89bbfc9df11..33834aa09ed43be03b0dd0ad418febf0ca25432d 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -113,7 +113,7 @@ config USB_GADGET_VBUS_DRAW
 
 config USB_GADGET_STORAGE_NUM_BUFFERS
 	int "Number of storage pipeline buffers"
-	range 2 4
+	range 2 32
 	default 2
 	help
 	   Usually 2 buffers are enough to establish a good buffering
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index b474499839d395289803501fdbb57d5c6c59b785..8b14c2a13ac51abc9d3f433a0261c599ec8cdaf6 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -839,9 +839,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
 		}
 	}
 
-	/* set_alt(), or next bind(), sets up
-	 * ep->driver_data as needed.
-	 */
+	/* set_alt(), or next bind(), sets up ep->claimed as needed */
 	usb_ep_autoconfig_reset(cdev->gadget);
 
 done:
@@ -1506,6 +1504,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
 				} else {
 					cdev->desc.bcdUSB = cpu_to_le16(0x0210);
 				}
+			} else {
+				cdev->desc.bcdUSB = cpu_to_le16(0x0200);
 			}
 
 			value = min(w_length, (u16) sizeof cdev->desc);
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 6399c106a3a55d2a380829af2dcc932c02193094..30fdab0ae38368b07dd957e34b141ddef88c2571 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -53,13 +53,13 @@
  * the restrictions that may apply. Some combinations of driver
  * and hardware won't be able to autoconfigure.
  *
- * On success, this returns an un-claimed usb_ep, and modifies the endpoint
+ * On success, this returns an claimed usb_ep, and modifies the endpoint
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  * is initialized as if the endpoint were used at full speed and
  * the bmAttribute field in the ep companion descriptor is
  * updated with the assigned number of streams if it is
  * different from the original value. To prevent the endpoint
- * from being returned by a later autoconfig call, claim it by
+ * from being returned by a later autoconfig call, claims it by
  * assigning ep->claimed to true.
  *
  * On failure, this returns a null endpoint descriptor.
@@ -154,10 +154,10 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss);
  * USB controller, and it can't know all the restrictions that may apply.
  * Some combinations of driver and hardware won't be able to autoconfigure.
  *
- * On success, this returns an un-claimed usb_ep, and modifies the endpoint
+ * On success, this returns an claimed usb_ep, and modifies the endpoint
  * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  * is initialized as if the endpoint were used at full speed.  To prevent
- * the endpoint from being returned by a later autoconfig call, claim it
+ * the endpoint from being returned by a later autoconfig call, claims it
  * by assigning ep->claimed to true.
  *
  * On failure, this returns a null endpoint descriptor.
@@ -171,6 +171,23 @@ struct usb_ep *usb_ep_autoconfig(
 }
 EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
 
+/**
+ * usb_ep_autoconfig_release - releases endpoint and set it to initial state
+ * @ep: endpoint which should be released
+ *
+ * This function can be used during function bind for endpoints obtained
+ * from usb_ep_autoconfig(). It unclaims endpoint claimed by
+ * usb_ep_autoconfig() to make it available for other functions. Endpoint
+ * which was released is no longer invalid and shouldn't be used in
+ * context of function which released it.
+ */
+void usb_ep_autoconfig_release(struct usb_ep *ep)
+{
+	ep->claimed = false;
+	ep->driver_data = NULL;
+}
+EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release);
+
 /**
  * usb_ep_autoconfig_reset - reset endpoint autoconfig state
  * @gadget: device for which autoconfig state will be reset
diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c
index be9df09fde26508c6b658cd0686681fb43e1d4bb..22e723d12d36ff4a6a24b07b703ac6172cf799ba 100644
--- a/drivers/usb/gadget/function/f_acm.c
+++ b/drivers/usb/gadget/function/f_acm.c
@@ -428,21 +428,18 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 	/* we know alt == 0, so this is an activation or a reset */
 
 	if (intf == acm->ctrl_id) {
-		if (acm->notify->driver_data) {
-			dev_vdbg(&cdev->gadget->dev,
-				 "reset acm control interface %d\n", intf);
-			usb_ep_disable(acm->notify);
-		}
+		dev_vdbg(&cdev->gadget->dev,
+				"reset acm control interface %d\n", intf);
+		usb_ep_disable(acm->notify);
 
 		if (!acm->notify->desc)
 			if (config_ep_by_speed(cdev->gadget, f, acm->notify))
 				return -EINVAL;
 
 		usb_ep_enable(acm->notify);
-		acm->notify->driver_data = acm;
 
 	} else if (intf == acm->data_id) {
-		if (acm->port.in->driver_data) {
+		if (acm->notify->enabled) {
 			dev_dbg(&cdev->gadget->dev,
 				"reset acm ttyGS%d\n", acm->port_num);
 			gserial_disconnect(&acm->port);
@@ -475,7 +472,6 @@ static void acm_disable(struct usb_function *f)
 	dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num);
 	gserial_disconnect(&acm->port);
 	usb_ep_disable(acm->notify);
-	acm->notify->driver_data = NULL;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -655,19 +651,16 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	acm->port.in = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc);
 	if (!ep)
 		goto fail;
 	acm->port.out = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc);
 	if (!ep)
 		goto fail;
 	acm->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	/* allocate notification */
 	acm->notify_req = gs_alloc_req(ep,
@@ -709,14 +702,6 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (acm->notify_req)
 		gs_free_req(acm->notify, acm->notify_req);
 
-	/* we might as well release our claims on endpoints */
-	if (acm->notify)
-		acm->notify->driver_data = NULL;
-	if (acm->port.out)
-		acm->port.out->driver_data = NULL;
-	if (acm->port.in)
-		acm->port.in->driver_data = NULL;
-
 	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c
index 7b7424f10dddce479fca8945cd238293a2f02cc6..4abca70cdaab9d52e529dcc85b2dabb30137d7e1 100644
--- a/drivers/usb/gadget/function/f_ecm.c
+++ b/drivers/usb/gadget/function/f_ecm.c
@@ -541,24 +541,21 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		if (alt != 0)
 			goto fail;
 
-		if (ecm->notify->driver_data) {
-			VDBG(cdev, "reset ecm control %d\n", intf);
-			usb_ep_disable(ecm->notify);
-		}
+		VDBG(cdev, "reset ecm control %d\n", intf);
+		usb_ep_disable(ecm->notify);
 		if (!(ecm->notify->desc)) {
 			VDBG(cdev, "init ecm ctrl %d\n", intf);
 			if (config_ep_by_speed(cdev->gadget, f, ecm->notify))
 				goto fail;
 		}
 		usb_ep_enable(ecm->notify);
-		ecm->notify->driver_data = ecm;
 
 	/* Data interface has two altsettings, 0 and 1 */
 	} else if (intf == ecm->data_id) {
 		if (alt > 1)
 			goto fail;
 
-		if (ecm->port.in_ep->driver_data) {
+		if (ecm->port.in_ep->enabled) {
 			DBG(cdev, "reset ecm\n");
 			gether_disconnect(&ecm->port);
 		}
@@ -618,7 +615,7 @@ static int ecm_get_alt(struct usb_function *f, unsigned intf)
 
 	if (intf == ecm->ctrl_id)
 		return 0;
-	return ecm->port.in_ep->driver_data ? 1 : 0;
+	return ecm->port.in_ep->enabled ? 1 : 0;
 }
 
 static void ecm_disable(struct usb_function *f)
@@ -628,14 +625,11 @@ static void ecm_disable(struct usb_function *f)
 
 	DBG(cdev, "ecm deactivated\n");
 
-	if (ecm->port.in_ep->driver_data)
+	if (ecm->port.in_ep->enabled)
 		gether_disconnect(&ecm->port);
 
-	if (ecm->notify->driver_data) {
-		usb_ep_disable(ecm->notify);
-		ecm->notify->driver_data = NULL;
-		ecm->notify->desc = NULL;
-	}
+	usb_ep_disable(ecm->notify);
+	ecm->notify->desc = NULL;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -750,13 +744,11 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	ecm->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
 	if (!ep)
 		goto fail;
 	ecm->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	/* NOTE:  a status/notification endpoint is *OPTIONAL* but we
 	 * don't treat it that way.  It's simpler, and some newer CDC
@@ -766,7 +758,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	ecm->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	status = -ENOMEM;
 
@@ -820,14 +811,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
 		usb_ep_free_request(ecm->notify, ecm->notify_req);
 	}
 
-	/* we might as well release our claims on endpoints */
-	if (ecm->notify)
-		ecm->notify->driver_data = NULL;
-	if (ecm->port.out_ep)
-		ecm->port.out_ep->driver_data = NULL;
-	if (ecm->port.in_ep)
-		ecm->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c
index c9e90de5bdd9192c459dd3dea7a9aafa3c086c6b..9a55757c729b2f59f1d512a8f4f67dffa89c5feb 100644
--- a/drivers/usb/gadget/function/f_eem.c
+++ b/drivers/usb/gadget/function/f_eem.c
@@ -195,11 +195,8 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		goto fail;
 
 	if (intf == eem->ctrl_id) {
-
-		if (eem->port.in_ep->driver_data) {
-			DBG(cdev, "reset eem\n");
-			gether_disconnect(&eem->port);
-		}
+		DBG(cdev, "reset eem\n");
+		gether_disconnect(&eem->port);
 
 		if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
 			DBG(cdev, "init eem\n");
@@ -237,7 +234,7 @@ static void eem_disable(struct usb_function *f)
 
 	DBG(cdev, "eem deactivated\n");
 
-	if (eem->port.in_ep->driver_data)
+	if (eem->port.in_ep->enabled)
 		gether_disconnect(&eem->port);
 }
 
@@ -293,13 +290,11 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	eem->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc);
 	if (!ep)
 		goto fail;
 	eem->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	status = -ENOMEM;
 
@@ -325,11 +320,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 
 fail:
-	if (eem->port.out_ep)
-		eem->port.out_ep->driver_data = NULL;
-	if (eem->port.in_ep)
-		eem->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index 6df9715a4bcd31179cb190100df45b2dd975a0d2..21fcf18f53a0409ed00bc302ac62b4f012e5c766 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -492,10 +492,7 @@ static void hidg_disable(struct usb_function *f)
 	struct f_hidg_req_list *list, *next;
 
 	usb_ep_disable(hidg->in_ep);
-	hidg->in_ep->driver_data = NULL;
-
 	usb_ep_disable(hidg->out_ep);
-	hidg->out_ep->driver_data = NULL;
 
 	list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
 		list_del(&list->list);
@@ -513,8 +510,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 	if (hidg->in_ep != NULL) {
 		/* restart endpoint */
-		if (hidg->in_ep->driver_data != NULL)
-			usb_ep_disable(hidg->in_ep);
+		usb_ep_disable(hidg->in_ep);
 
 		status = config_ep_by_speed(f->config->cdev->gadget, f,
 					    hidg->in_ep);
@@ -533,8 +529,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 	if (hidg->out_ep != NULL) {
 		/* restart endpoint */
-		if (hidg->out_ep->driver_data != NULL)
-			usb_ep_disable(hidg->out_ep);
+		usb_ep_disable(hidg->out_ep);
 
 		status = config_ep_by_speed(f->config->cdev->gadget, f,
 					    hidg->out_ep);
@@ -566,7 +561,6 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 						hidg->out_ep->name, status);
 			} else {
 				usb_ep_disable(hidg->out_ep);
-				hidg->out_ep->driver_data = NULL;
 				status = -ENOMEM;
 				goto fail;
 			}
@@ -614,13 +608,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
 	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc);
 	if (!ep)
 		goto fail;
-	ep->driver_data = c->cdev;	/* claim */
 	hidg->in_ep = ep;
 
 	ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc);
 	if (!ep)
 		goto fail;
-	ep->driver_data = c->cdev;	/* claim */
 	hidg->out_ep = ep;
 
 	/* preallocate request and buffer */
diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c
index 6e2fe63b926741abf184f2ee54a0fe740a372e42..6b2102bc069973554db95d3311470b0545067727 100644
--- a/drivers/usb/gadget/function/f_loopback.c
+++ b/drivers/usb/gadget/function/f_loopback.c
@@ -34,6 +34,9 @@ struct f_loopback {
 
 	struct usb_ep		*in_ep;
 	struct usb_ep		*out_ep;
+
+	unsigned                qlen;
+	unsigned                buflen;
 };
 
 static inline struct f_loopback *func_to_loop(struct usb_function *f)
@@ -41,13 +44,10 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f)
 	return container_of(f, struct f_loopback, function);
 }
 
-static unsigned qlen;
-static unsigned buflen;
-
 /*-------------------------------------------------------------------------*/
 
 static struct usb_interface_descriptor loopback_intf = {
-	.bLength =		sizeof loopback_intf,
+	.bLength =		sizeof(loopback_intf),
 	.bDescriptorType =	USB_DT_INTERFACE,
 
 	.bNumEndpoints =	2,
@@ -195,12 +195,10 @@ static int loopback_bind(struct usb_configuration *c, struct usb_function *f)
 			f->name, cdev->gadget->name);
 		return -ENODEV;
 	}
-	loop->in_ep->driver_data = cdev;	/* claim */
 
 	loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
 	if (!loop->out_ep)
 		goto autoconf_fail;
-	loop->out_ep->driver_data = cdev;	/* claim */
 
 	/* support high speed hardware */
 	hs_loop_source_desc.bEndpointAddress =
@@ -245,22 +243,38 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
 	int			status = req->status;
 
 	switch (status) {
-
 	case 0:				/* normal completion? */
 		if (ep == loop->out_ep) {
-			req->zero = (req->actual < req->length);
-			req->length = req->actual;
+			/*
+			 * We received some data from the host so let's
+			 * queue it so host can read the from our in ep
+			 */
+			struct usb_request *in_req = req->context;
+
+			in_req->zero = (req->actual < req->length);
+			in_req->length = req->actual;
+			ep = loop->in_ep;
+			req = in_req;
+		} else {
+			/*
+			 * We have just looped back a bunch of data
+			 * to host. Now let's wait for some more data.
+			 */
+			req = req->context;
+			ep = loop->out_ep;
 		}
 
-		/* queue the buffer for some later OUT packet */
-		req->length = buflen;
+		/* queue the buffer back to host or for next bunch of data */
 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
-		if (status == 0)
+		if (status == 0) {
 			return;
+		} else {
+			ERROR(cdev, "Unable to loop back buffer to %s: %d\n",
+			      ep->name, status);
+			goto free_req;
+		}
 
 		/* "should never get here" */
-		/* FALLTHROUGH */
-
 	default:
 		ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
 				status, req->actual, req->length);
@@ -274,6 +288,10 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
 	case -ECONNABORTED:		/* hardware forced ep reset */
 	case -ECONNRESET:		/* request dequeued */
 	case -ESHUTDOWN:		/* disconnect from host */
+free_req:
+		usb_ep_free_request(ep == loop->in_ep ?
+				    loop->out_ep : loop->in_ep,
+				    req->context);
 		free_ep_req(ep, req);
 		return;
 	}
@@ -290,53 +308,77 @@ static void disable_loopback(struct f_loopback *loop)
 
 static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len)
 {
-	return alloc_ep_req(ep, len, buflen);
+	struct f_loopback	*loop = ep->driver_data;
+
+	return alloc_ep_req(ep, len, loop->buflen);
 }
 
-static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop,
-		struct usb_ep *ep)
+static int alloc_requests(struct usb_composite_dev *cdev,
+			  struct f_loopback *loop)
 {
-	struct usb_request			*req;
-	unsigned				i;
-	int					result;
-
-	/*
-	 * one endpoint writes data back IN to the host while another endpoint
-	 * just reads OUT packets
-	 */
-	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
-	if (result)
-		goto fail0;
-	result = usb_ep_enable(ep);
-	if (result < 0)
-		goto fail0;
-	ep->driver_data = loop;
+	struct usb_request *in_req, *out_req;
+	int i;
+	int result = 0;
 
 	/*
 	 * allocate a bunch of read buffers and queue them all at once.
-	 * we buffer at most 'qlen' transfers; fewer if any need more
-	 * than 'buflen' bytes each.
+	 * we buffer at most 'qlen' transfers; We allocate buffers only
+	 * for out transfer and reuse them in IN transfers to implement
+	 * our loopback functionality
 	 */
-	for (i = 0; i < qlen && result == 0; i++) {
-		req = lb_alloc_ep_req(ep, 0);
-		if (!req)
-			goto fail1;
+	for (i = 0; i < loop->qlen && result == 0; i++) {
+		result = -ENOMEM;
+
+		in_req = usb_ep_alloc_request(loop->in_ep, GFP_KERNEL);
+		if (!in_req)
+			goto fail;
+
+		out_req = lb_alloc_ep_req(loop->out_ep, 0);
+		if (!out_req)
+			goto fail_in;
 
-		req->complete = loopback_complete;
-		result = usb_ep_queue(ep, req, GFP_ATOMIC);
+		in_req->complete = loopback_complete;
+		out_req->complete = loopback_complete;
+
+		in_req->buf = out_req->buf;
+		/* length will be set in complete routine */
+		in_req->context = out_req;
+		out_req->context = in_req;
+
+		result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC);
 		if (result) {
 			ERROR(cdev, "%s queue req --> %d\n",
-					ep->name, result);
-			goto fail1;
+					loop->out_ep->name, result);
+			goto fail_out;
 		}
 	}
 
 	return 0;
 
-fail1:
-	usb_ep_disable(ep);
+fail_out:
+	free_ep_req(loop->out_ep, out_req);
+fail_in:
+	usb_ep_free_request(loop->in_ep, in_req);
+fail:
+	return result;
+}
+
+static int enable_endpoint(struct usb_composite_dev *cdev,
+			   struct f_loopback *loop, struct usb_ep *ep)
+{
+	int					result;
+
+	result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
+	if (result)
+		goto out;
 
-fail0:
+	result = usb_ep_enable(ep);
+	if (result < 0)
+		goto out;
+	ep->driver_data = loop;
+	result = 0;
+
+out:
 	return result;
 }
 
@@ -347,13 +389,24 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
 
 	result = enable_endpoint(cdev, loop, loop->in_ep);
 	if (result)
-		return result;
+		goto out;
 
 	result = enable_endpoint(cdev, loop, loop->out_ep);
 	if (result)
-		return result;
+		goto disable_in;
+
+	result = alloc_requests(cdev, loop);
+	if (result)
+		goto disable_out;
 
 	DBG(cdev, "%s enabled\n", loop->function.name);
+	return 0;
+
+disable_out:
+	usb_ep_disable(loop->out_ep);
+disable_in:
+	usb_ep_disable(loop->in_ep);
+out:
 	return result;
 }
 
@@ -364,8 +417,7 @@ static int loopback_set_alt(struct usb_function *f,
 	struct usb_composite_dev *cdev = f->config->cdev;
 
 	/* we know alt is zero */
-	if (loop->in_ep->driver_data)
-		disable_loopback(loop);
+	disable_loopback(loop);
 	return enable_loopback(cdev, loop);
 }
 
@@ -391,10 +443,10 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
 	lb_opts->refcnt++;
 	mutex_unlock(&lb_opts->lock);
 
-	buflen = lb_opts->bulk_buflen;
-	qlen = lb_opts->qlen;
-	if (!qlen)
-		qlen = 32;
+	loop->buflen = lb_opts->bulk_buflen;
+	loop->qlen = lb_opts->qlen;
+	if (!loop->qlen)
+		loop->qlen = 32;
 
 	loop->function.name = "loopback";
 	loop->function.bind = loopback_bind;
@@ -434,7 +486,7 @@ static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%d", opts->qlen);
+	result = sprintf(page, "%d\n", opts->qlen);
 	mutex_unlock(&opts->lock);
 
 	return result;
@@ -473,7 +525,7 @@ static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%d", opts->bulk_buflen);
+	result = sprintf(page, "%d\n", opts->bulk_buflen);
 	mutex_unlock(&opts->lock);
 
 	return result;
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index a6eb537d77689f53e7b0e31cff14c2f523c52fe4..cd54e72a6c50d74ee5088b015e71d772cddd9d38 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -2258,12 +2258,10 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
 		/* Disable the endpoints */
 		if (fsg->bulk_in_enabled) {
 			usb_ep_disable(fsg->bulk_in);
-			fsg->bulk_in->driver_data = NULL;
 			fsg->bulk_in_enabled = 0;
 		}
 		if (fsg->bulk_out_enabled) {
 			usb_ep_disable(fsg->bulk_out);
-			fsg->bulk_out->driver_data = NULL;
 			fsg->bulk_out_enabled = 0;
 		}
 
@@ -2662,10 +2660,12 @@ EXPORT_SYMBOL_GPL(fsg_common_put);
 /* check if fsg_num_buffers is within a valid range */
 static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers)
 {
-	if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
+#define FSG_MAX_NUM_BUFFERS	32
+
+	if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS)
 		return 0;
 	pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
-	       fsg_num_buffers, 2, 4);
+	       fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS);
 	return -EINVAL;
 }
 
@@ -3070,13 +3070,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
 	if (!ep)
 		goto autoconf_fail;
-	ep->driver_data = fsg->common;	/* claim the endpoint */
 	fsg->bulk_in = ep;
 
 	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
 	if (!ep)
 		goto autoconf_fail;
-	ep->driver_data = fsg->common;	/* claim the endpoint */
 	fsg->bulk_out = ep;
 
 	/* Assume endpoint addresses are the same for both speeds */
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index a287a48292731b2b9eda7a0294eed98dfd6b0987..ce3c8a629266c12d6de7638f2c9900af4085cd83 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -302,8 +302,7 @@ static int f_midi_start_ep(struct f_midi *midi,
 	int err;
 	struct usb_composite_dev *cdev = f->config->cdev;
 
-	if (ep->driver_data)
-		usb_ep_disable(ep);
+	usb_ep_disable(ep);
 
 	err = config_ep_by_speed(midi->gadget, f, ep);
 	if (err) {
@@ -341,8 +340,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 	if (err)
 		return err;
 
-	if (midi->out_ep->driver_data)
-		usb_ep_disable(midi->out_ep);
+	usb_ep_disable(midi->out_ep);
 
 	err = config_ep_by_speed(midi->gadget, f, midi->out_ep);
 	if (err) {
@@ -547,10 +545,16 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
 		}
 	}
 
-	if (req->length > 0)
-		usb_ep_queue(ep, req, GFP_ATOMIC);
-	else
+	if (req->length > 0) {
+		int err;
+
+		err = usb_ep_queue(ep, req, GFP_ATOMIC);
+		if (err < 0)
+			ERROR(midi, "%s queue req: %d\n",
+			      midi->in_ep->name, err);
+	} else {
 		free_ep_req(ep, req);
+	}
 }
 
 static void f_midi_in_tasklet(unsigned long data)
@@ -757,12 +761,10 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 	midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc);
 	if (!midi->in_ep)
 		goto fail;
-	midi->in_ep->driver_data = cdev;	/* claim */
 
 	midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc);
 	if (!midi->out_ep)
 		goto fail;
-	midi->out_ep->driver_data = cdev;	/* claim */
 
 	/* allocate temporary function list */
 	midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function),
@@ -889,12 +891,6 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
 fail:
 	f_midi_unregister_card(midi);
 fail_register:
-	/* we might as well release our claims on endpoints */
-	if (midi->out_ep)
-		midi->out_ep->driver_data = NULL;
-	if (midi->in_ep)
-		midi->in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index 3f05c6bd57f0c3353b5a2973a3e344593834b5b5..b6f7ed7d48a7fa6a297ccfeca6440465593462be 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -586,7 +586,7 @@ static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req)
 	unsigned		in_size;
 	struct usb_function	*f = req->context;
 	struct f_ncm		*ncm = func_to_ncm(f);
-	struct usb_composite_dev *cdev = ep->driver_data;
+	struct usb_composite_dev *cdev = f->config->cdev;
 
 	req->context = NULL;
 	if (req->status || req->actual != req->length) {
@@ -803,10 +803,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		if (alt != 0)
 			goto fail;
 
-		if (ncm->notify->driver_data) {
-			DBG(cdev, "reset ncm control %d\n", intf);
-			usb_ep_disable(ncm->notify);
-		}
+		DBG(cdev, "reset ncm control %d\n", intf);
+		usb_ep_disable(ncm->notify);
 
 		if (!(ncm->notify->desc)) {
 			DBG(cdev, "init ncm ctrl %d\n", intf);
@@ -814,14 +812,13 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 				goto fail;
 		}
 		usb_ep_enable(ncm->notify);
-		ncm->notify->driver_data = ncm;
 
 	/* Data interface has two altsettings, 0 and 1 */
 	} else if (intf == ncm->data_id) {
 		if (alt > 1)
 			goto fail;
 
-		if (ncm->port.in_ep->driver_data) {
+		if (ncm->port.in_ep->enabled) {
 			DBG(cdev, "reset ncm\n");
 			ncm->timer_stopping = true;
 			ncm->netdev = NULL;
@@ -885,7 +882,7 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf)
 
 	if (intf == ncm->ctrl_id)
 		return 0;
-	return ncm->port.in_ep->driver_data ? 1 : 0;
+	return ncm->port.in_ep->enabled ? 1 : 0;
 }
 
 static struct sk_buff *package_for_tx(struct f_ncm *ncm)
@@ -1276,15 +1273,14 @@ static void ncm_disable(struct usb_function *f)
 
 	DBG(cdev, "ncm deactivated\n");
 
-	if (ncm->port.in_ep->driver_data) {
+	if (ncm->port.in_ep->enabled) {
 		ncm->timer_stopping = true;
 		ncm->netdev = NULL;
 		gether_disconnect(&ncm->port);
 	}
 
-	if (ncm->notify->driver_data) {
+	if (ncm->notify->enabled) {
 		usb_ep_disable(ncm->notify);
-		ncm->notify->driver_data = NULL;
 		ncm->notify->desc = NULL;
 	}
 }
@@ -1402,19 +1398,16 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	ncm->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc);
 	if (!ep)
 		goto fail;
 	ncm->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc);
 	if (!ep)
 		goto fail;
 	ncm->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	status = -ENOMEM;
 
@@ -1468,14 +1461,6 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 		usb_ep_free_request(ncm->notify, ncm->notify_req);
 	}
 
-	/* we might as well release our claims on endpoints */
-	if (ncm->notify)
-		ncm->notify->driver_data = NULL;
-	if (ncm->port.out_ep)
-		ncm->port.out_ep->driver_data = NULL;
-	if (ncm->port.in_ep)
-		ncm->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c
index 5460426057eb232d13e6a071a47f114fb8cd4e14..1c3d30ad2f92cb3edba2ab0eb3ca490378de86f1 100644
--- a/drivers/usb/gadget/function/f_obex.c
+++ b/drivers/usb/gadget/function/f_obex.c
@@ -206,7 +206,7 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 		if (alt > 1)
 			goto fail;
 
-		if (obex->port.in->driver_data) {
+		if (obex->port.in->enabled) {
 			dev_dbg(&cdev->gadget->dev,
 				"reset obex ttyGS%d\n", obex->port_num);
 			gserial_disconnect(&obex->port);
@@ -348,13 +348,11 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	obex->port.in = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
 	if (!ep)
 		goto fail;
 	obex->port.out = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -378,12 +376,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 
 fail:
-	/* we might as well release our claims on endpoints */
-	if (obex->port.out)
-		obex->port.out->driver_data = NULL;
-	if (obex->port.in)
-		obex->port.in->driver_data = NULL;
-
 	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c
index c0c3ef272714b58ea4980ba25cf24076b502a105..62a198754029e1f707147a12713f758a186cdd8e 100644
--- a/drivers/usb/gadget/function/f_phonet.c
+++ b/drivers/usb/gadget/function/f_phonet.c
@@ -418,7 +418,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 		spin_lock(&port->lock);
 
-		if (fp->in_ep->driver_data)
+		if (fp->in_ep->enabled)
 			__pn_reset(f);
 
 		if (alt == 1) {
@@ -530,13 +530,11 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto err;
 	fp->out_ep = ep;
-	ep->driver_data = fp; /* Claim */
 
 	ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc);
 	if (!ep)
 		goto err;
 	fp->in_ep = ep;
-	ep->driver_data = fp; /* Claim */
 
 	pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress;
 	pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress;
@@ -575,10 +573,6 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f)
 		usb_ep_free_request(fp->out_ep, fp->out_reqv[i]);
 	usb_free_all_descriptors(f);
 err:
-	if (fp->out_ep)
-		fp->out_ep->driver_data = NULL;
-	if (fp->in_ep)
-		fp->in_ep->driver_data = NULL;
 	ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n");
 	return status;
 }
diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c
index 8e2b6bea07bc0e6a6fa1758aa38841a52afdcf3c..7fb3209ed52c31c662b24b1799e78ff9a4d38700 100644
--- a/drivers/usb/gadget/function/f_printer.c
+++ b/drivers/usb/gadget/function/f_printer.c
@@ -1039,12 +1039,10 @@ static int printer_func_bind(struct usb_configuration *c,
 			cdev->gadget->name);
 		return -ENODEV;
 	}
-	in_ep->driver_data = in_ep;	/* claim */
 
 	out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc);
 	if (!out_ep)
 		goto autoconf_fail;
-	out_ep->driver_data = out_ep;	/* claim */
 
 	/* assumes that all endpoints are dual-speed */
 	hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c
index 32985dade8385145b6c4493a153656cc6b1aea22..fd301ed9e294fa480ad0336fc17833e772611765 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -543,22 +543,20 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 	/* we know alt == 0 */
 
 	if (intf == rndis->ctrl_id) {
-		if (rndis->notify->driver_data) {
-			VDBG(cdev, "reset rndis control %d\n", intf);
-			usb_ep_disable(rndis->notify);
-		}
+		VDBG(cdev, "reset rndis control %d\n", intf);
+		usb_ep_disable(rndis->notify);
+
 		if (!rndis->notify->desc) {
 			VDBG(cdev, "init rndis ctrl %d\n", intf);
 			if (config_ep_by_speed(cdev->gadget, f, rndis->notify))
 				goto fail;
 		}
 		usb_ep_enable(rndis->notify);
-		rndis->notify->driver_data = rndis;
 
 	} else if (intf == rndis->data_id) {
 		struct net_device	*net;
 
-		if (rndis->port.in_ep->driver_data) {
+		if (rndis->port.in_ep->enabled) {
 			DBG(cdev, "reset rndis\n");
 			gether_disconnect(&rndis->port);
 		}
@@ -612,7 +610,7 @@ static void rndis_disable(struct usb_function *f)
 	struct f_rndis		*rndis = func_to_rndis(f);
 	struct usb_composite_dev *cdev = f->config->cdev;
 
-	if (!rndis->notify->driver_data)
+	if (!rndis->notify->enabled)
 		return;
 
 	DBG(cdev, "rndis deactivated\n");
@@ -621,7 +619,6 @@ static void rndis_disable(struct usb_function *f)
 	gether_disconnect(&rndis->port);
 
 	usb_ep_disable(rndis->notify);
-	rndis->notify->driver_data = NULL;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -745,13 +742,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	rndis->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
 	if (!ep)
 		goto fail;
 	rndis->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	/* NOTE:  a status/notification endpoint is, strictly speaking,
 	 * optional.  We don't treat it that way though!  It's simpler,
@@ -761,7 +756,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	rndis->notify = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	status = -ENOMEM;
 
@@ -829,14 +823,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
 		usb_ep_free_request(rndis->notify, rndis->notify_req);
 	}
 
-	/* we might as well release our claims on endpoints */
-	if (rndis->notify)
-		rndis->notify->driver_data = NULL;
-	if (rndis->port.out_ep)
-		rndis->port.out_ep->driver_data = NULL;
-	if (rndis->port.in_ep)
-		rndis->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c
index 1d162e200e831ce1320a8e3d3f36f3bbd82b5a92..ba705e047d7e0fca31ce8a2ede4d67f595efb5ca 100644
--- a/drivers/usb/gadget/function/f_serial.c
+++ b/drivers/usb/gadget/function/f_serial.c
@@ -153,7 +153,7 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 	/* we know alt == 0, so this is an activation or a reset */
 
-	if (gser->port.in->driver_data) {
+	if (gser->port.in->enabled) {
 		dev_dbg(&cdev->gadget->dev,
 			"reset generic ttyGS%d\n", gser->port_num);
 		gserial_disconnect(&gser->port);
@@ -219,13 +219,11 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	gser->port.in = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc);
 	if (!ep)
 		goto fail;
 	gser->port.out = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -249,12 +247,6 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 
 fail:
-	/* we might as well release our claims on endpoints */
-	if (gser->port.out)
-		gser->port.out->driver_data = NULL;
-	if (gser->port.in)
-		gser->port.in->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c
index cbfaf86fe45652911744055d6549a88c88b056d3..d7646d3acd63ecb4aa87362e069b54faff909844 100644
--- a/drivers/usb/gadget/function/f_sourcesink.c
+++ b/drivers/usb/gadget/function/f_sourcesink.c
@@ -50,6 +50,13 @@ struct f_sourcesink {
 	struct usb_ep		*iso_in_ep;
 	struct usb_ep		*iso_out_ep;
 	int			cur_alt;
+
+	unsigned pattern;
+	unsigned isoc_interval;
+	unsigned isoc_maxpacket;
+	unsigned isoc_mult;
+	unsigned isoc_maxburst;
+	unsigned buflen;
 };
 
 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -57,13 +64,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
 	return container_of(f, struct f_sourcesink, function);
 }
 
-static unsigned pattern;
-static unsigned isoc_interval;
-static unsigned isoc_maxpacket;
-static unsigned isoc_mult;
-static unsigned isoc_maxburst;
-static unsigned buflen;
-
 /*-------------------------------------------------------------------------*/
 
 static struct usb_interface_descriptor source_sink_intf_alt0 = {
@@ -298,7 +298,9 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
 
 static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
 {
-	return alloc_ep_req(ep, len, buflen);
+	struct f_sourcesink		*ss = ep->driver_data;
+
+	return alloc_ep_req(ep, len, ss->buflen);
 }
 
 void free_ep_req(struct usb_ep *ep, struct usb_request *req)
@@ -311,13 +313,9 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
 {
 	int			value;
 
-	if (ep->driver_data) {
-		value = usb_ep_disable(ep);
-		if (value < 0)
-			DBG(cdev, "disable %s --> %d\n",
-					ep->name, value);
-		ep->driver_data = NULL;
-	}
+	value = usb_ep_disable(ep);
+	if (value < 0)
+		DBG(cdev, "disable %s --> %d\n", ep->name, value);
 }
 
 void disable_endpoints(struct usb_composite_dev *cdev,
@@ -355,42 +353,37 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 			f->name, cdev->gadget->name);
 		return -ENODEV;
 	}
-	ss->in_ep->driver_data = cdev;	/* claim */
 
 	ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
 	if (!ss->out_ep)
 		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;
+	if (ss->isoc_interval < 1)
+		ss->isoc_interval = 1;
+	if (ss->isoc_interval > 16)
+		ss->isoc_interval = 16;
+	if (ss->isoc_mult > 2)
+		ss->isoc_mult = 2;
+	if (ss->isoc_maxburst > 15)
+		ss->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;
+	fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
+						1023 : ss->isoc_maxpacket;
+	fs_iso_source_desc.bInterval = ss->isoc_interval;
+	fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
+						1023 : ss->isoc_maxpacket;
+	fs_iso_sink_desc.bInterval = ss->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;
+	if (!ss->iso_out_ep) {
+		usb_ep_autoconfig_release(ss->iso_in_ep);
 		ss->iso_in_ep = NULL;
 no_iso:
 		/*
@@ -403,8 +396,8 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 		ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
 	}
 
-	if (isoc_maxpacket > 1024)
-		isoc_maxpacket = 1024;
+	if (ss->isoc_maxpacket > 1024)
+		ss->isoc_maxpacket = 1024;
 
 	/* support high speed hardware */
 	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
@@ -415,15 +408,15 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 	 * 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.wMaxPacketSize = ss->isoc_maxpacket;
+	hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11;
+	hs_iso_source_desc.bInterval = ss->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.wMaxPacketSize = ss->isoc_maxpacket;
+	hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11;
+	hs_iso_sink_desc.bInterval = ss->isoc_interval;
 	hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
 	/* support super speed hardware */
@@ -437,21 +430,21 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 	 * 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.wMaxPacketSize = ss->isoc_maxpacket;
+	ss_iso_source_desc.bInterval = ss->isoc_interval;
+	ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult;
+	ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst;
+	ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
+		(ss->isoc_mult + 1) * (ss->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.wMaxPacketSize = ss->isoc_maxpacket;
+	ss_iso_sink_desc.bInterval = ss->isoc_interval;
+	ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult;
+	ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst;
+	ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
+		(ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
 	ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
 	ret = usb_assign_descriptors(f, fs_source_sink_descs,
@@ -489,12 +482,13 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
 	unsigned		i;
 	u8			*buf = req->buf;
 	struct usb_composite_dev *cdev = ss->function.config->cdev;
+	int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize);
 
-	if (pattern == 2)
+	if (ss->pattern == 2)
 		return 0;
 
 	for (i = 0; i < req->actual; i++, buf++) {
-		switch (pattern) {
+		switch (ss->pattern) {
 
 		/* all-zeroes has no synchronization issues */
 		case 0:
@@ -510,7 +504,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
 		 * stutter for any reason, including buffer duplication...)
 		 */
 		case 1:
-			if (*buf == (u8)(i % 63))
+			if (*buf == (u8)((i % max_packet_size) % 63))
 				continue;
 			break;
 		}
@@ -525,14 +519,16 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
 {
 	unsigned	i;
 	u8		*buf = req->buf;
+	int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize);
+	struct f_sourcesink *ss = ep->driver_data;
 
-	switch (pattern) {
+	switch (ss->pattern) {
 	case 0:
 		memset(req->buf, 0, req->length);
 		break;
 	case 1:
 		for  (i = 0; i < req->length; i++)
-			*buf++ = (u8) (i % 63);
+			*buf++ = (u8) ((i % max_packet_size) % 63);
 		break;
 	case 2:
 		break;
@@ -556,7 +552,7 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
 	case 0:				/* normal completion? */
 		if (ep == ss->out_ep) {
 			check_read_data(ss, req);
-			if (pattern != 2)
+			if (ss->pattern != 2)
 				memset(req->buf, 0x55, req->length);
 		}
 		break;
@@ -605,15 +601,16 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 		if (is_iso) {
 			switch (speed) {
 			case USB_SPEED_SUPER:
-				size = isoc_maxpacket * (isoc_mult + 1) *
-						(isoc_maxburst + 1);
+				size = ss->isoc_maxpacket *
+						(ss->isoc_mult + 1) *
+						(ss->isoc_maxburst + 1);
 				break;
 			case USB_SPEED_HIGH:
-				size = isoc_maxpacket * (isoc_mult + 1);
+				size = ss->isoc_maxpacket * (ss->isoc_mult + 1);
 				break;
 			default:
-				size = isoc_maxpacket > 1023 ?
-						1023 : isoc_maxpacket;
+				size = ss->isoc_maxpacket > 1023 ?
+						1023 : ss->isoc_maxpacket;
 				break;
 			}
 			ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
@@ -629,7 +626,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 		req->complete = source_sink_complete;
 		if (is_in)
 			reinit_write_data(ep, req);
-		else if (pattern != 2)
+		else if (ss->pattern != 2)
 			memset(req->buf, 0x55, req->length);
 
 		status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@ -683,7 +680,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 fail:
 		ep = ss->in_ep;
 		usb_ep_disable(ep);
-		ep->driver_data = NULL;
 		return result;
 	}
 
@@ -702,7 +698,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 fail2:
 		ep = ss->out_ep;
 		usb_ep_disable(ep);
-		ep->driver_data = NULL;
 		goto fail;
 	}
 
@@ -724,10 +719,8 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 		if (result < 0) {
 fail3:
 			ep = ss->iso_in_ep;
-			if (ep) {
+			if (ep)
 				usb_ep_disable(ep);
-				ep->driver_data = NULL;
-			}
 			goto fail2;
 		}
 	}
@@ -746,7 +739,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 		result = source_sink_start_ep(ss, false, true, speed);
 		if (result < 0) {
 			usb_ep_disable(ep);
-			ep->driver_data = NULL;
 			goto fail3;
 		}
 	}
@@ -763,8 +755,7 @@ static int sourcesink_set_alt(struct usb_function *f,
 	struct f_sourcesink		*ss = func_to_ss(f);
 	struct usb_composite_dev	*cdev = f->config->cdev;
 
-	if (ss->in_ep->driver_data)
-		disable_source_sink(ss);
+	disable_source_sink(ss);
 	return enable_source_sink(cdev, ss, alt);
 }
 
@@ -872,12 +863,12 @@ static struct usb_function *source_sink_alloc_func(
 	ss_opts->refcnt++;
 	mutex_unlock(&ss_opts->lock);
 
-	pattern = ss_opts->pattern;
-	isoc_interval = ss_opts->isoc_interval;
-	isoc_maxpacket = ss_opts->isoc_maxpacket;
-	isoc_mult = ss_opts->isoc_mult;
-	isoc_maxburst = ss_opts->isoc_maxburst;
-	buflen = ss_opts->bulk_buflen;
+	ss->pattern = ss_opts->pattern;
+	ss->isoc_interval = ss_opts->isoc_interval;
+	ss->isoc_maxpacket = ss_opts->isoc_maxpacket;
+	ss->isoc_mult = ss_opts->isoc_mult;
+	ss->isoc_maxburst = ss_opts->isoc_maxburst;
+	ss->buflen = ss_opts->bulk_buflen;
 
 	ss->function.name = "source/sink";
 	ss->function.bind = sourcesink_bind;
@@ -919,7 +910,7 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->pattern);
+	result = sprintf(page, "%u\n", opts->pattern);
 	mutex_unlock(&opts->lock);
 
 	return result;
@@ -963,7 +954,7 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_interval);
+	result = sprintf(page, "%u\n", opts->isoc_interval);
 	mutex_unlock(&opts->lock);
 
 	return result;
@@ -1007,7 +998,7 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_maxpacket);
+	result = sprintf(page, "%u\n", opts->isoc_maxpacket);
 	mutex_unlock(&opts->lock);
 
 	return result;
@@ -1051,7 +1042,7 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_mult);
+	result = sprintf(page, "%u\n", opts->isoc_mult);
 	mutex_unlock(&opts->lock);
 
 	return result;
@@ -1095,7 +1086,7 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->isoc_maxburst);
+	result = sprintf(page, "%u\n", opts->isoc_maxburst);
 	mutex_unlock(&opts->lock);
 
 	return result;
@@ -1139,7 +1130,7 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
 	int result;
 
 	mutex_lock(&opts->lock);
-	result = sprintf(page, "%u", opts->bulk_buflen);
+	result = sprintf(page, "%u\n", opts->bulk_buflen);
 	mutex_unlock(&opts->lock);
 
 	return result;
diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c
index e3dfa675ff06db9ca627e6d211f30263f298eb8f..2e66e624e6e13dfed2fde71fff294a10a986bb7a 100644
--- a/drivers/usb/gadget/function/f_subset.c
+++ b/drivers/usb/gadget/function/f_subset.c
@@ -262,7 +262,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 
 	/* we know alt == 0, so this is an activation or a reset */
 
-	if (geth->port.in_ep->driver_data) {
+	if (geth->port.in_ep->enabled) {
 		DBG(cdev, "reset cdc subset\n");
 		gether_disconnect(&geth->port);
 	}
@@ -343,13 +343,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
 	if (!ep)
 		goto fail;
 	geth->port.in_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
 	if (!ep)
 		goto fail;
 	geth->port.out_ep = ep;
-	ep->driver_data = cdev;	/* claim */
 
 	/* support all relevant hardware speeds... we expect that when
 	 * hardware is dual speed, all bulk-capable endpoints work at
@@ -380,12 +378,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 
 fail:
-	/* we might as well release our claims on endpoints */
-	if (geth->port.out_ep)
-		geth->port.out_ep->driver_data = NULL;
-	if (geth->port.in_ep)
-		geth->port.in_ep->driver_data = NULL;
-
 	ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
 
 	return status;
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
index 7856b3394494b7d4250637277dd1f42f45d7a1ea..8ee701924d29d0c5ad27edfed1b3e23c15b5c3e7 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -593,7 +593,6 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 				return err;
 
 			usb_ep_enable(out_ep);
-			out_ep->driver_data = audio;
 			audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
 			if (IS_ERR(audio->copy_buf))
 				return -ENOMEM;
@@ -718,7 +717,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 		goto fail;
 	audio->out_ep = ep;
 	audio->out_ep->desc = &as_out_ep_desc;
-	ep->driver_data = cdev;	/* claim */
 
 	status = -ENOMEM;
 
@@ -730,8 +728,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 
 fail:
 	gaudio_cleanup(&audio->card);
-	if (ep)
-		ep->driver_data = NULL;
 	return status;
 }
 
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index f8de7ea2a0c1e9585782e2fe60af23a41c072e37..63336e269898d07ac42c2ab66117c9aaed2ae142 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -1081,14 +1081,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 		goto err;
 	}
-	agdev->out_ep->driver_data = agdev;
 
 	agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
 	if (!agdev->in_ep) {
 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 		goto err;
 	}
-	agdev->in_ep->driver_data = agdev;
 
 	uac2->p_prm.uac2 = uac2;
 	uac2->c_prm.uac2 = uac2;
@@ -1132,10 +1130,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 err:
 	kfree(agdev->uac2.p_prm.rbuf);
 	kfree(agdev->uac2.c_prm.rbuf);
-	if (agdev->in_ep)
-		agdev->in_ep->driver_data = NULL;
-	if (agdev->out_ep)
-		agdev->out_ep->driver_data = NULL;
 	return -EINVAL;
 }
 
@@ -1583,11 +1577,6 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
 	prm = &agdev->uac2.c_prm;
 	kfree(prm->rbuf);
 	usb_free_all_descriptors(f);
-
-	if (agdev->in_ep)
-		agdev->in_ep->driver_data = NULL;
-	if (agdev->out_ep)
-		agdev->out_ep->driver_data = NULL;
 }
 
 static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index 743be34605dcbff26eaf066c80578fb5112e41cf..29b41b5dee04d2e0e3e87a6dc97d6dde84af49d0 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -280,7 +280,7 @@ uvc_function_get_alt(struct usb_function *f, unsigned interface)
 	else if (interface != uvc->streaming_intf)
 		return -EINVAL;
 	else
-		return uvc->video.ep->driver_data ? 1 : 0;
+		return uvc->video.ep->enabled ? 1 : 0;
 }
 
 static int
@@ -298,18 +298,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
 		if (alt)
 			return -EINVAL;
 
-		if (uvc->control_ep->driver_data) {
-			INFO(cdev, "reset UVC Control\n");
-			usb_ep_disable(uvc->control_ep);
-			uvc->control_ep->driver_data = NULL;
-		}
+		INFO(cdev, "reset UVC Control\n");
+		usb_ep_disable(uvc->control_ep);
 
 		if (!uvc->control_ep->desc)
 			if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep))
 				return -EINVAL;
 
 		usb_ep_enable(uvc->control_ep);
-		uvc->control_ep->driver_data = uvc;
 
 		if (uvc->state == UVC_STATE_DISCONNECTED) {
 			memset(&v4l2_event, 0, sizeof(v4l2_event));
@@ -336,10 +332,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
 		if (uvc->state != UVC_STATE_STREAMING)
 			return 0;
 
-		if (uvc->video.ep) {
+		if (uvc->video.ep)
 			usb_ep_disable(uvc->video.ep);
-			uvc->video.ep->driver_data = NULL;
-		}
 
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		v4l2_event.type = UVC_EVENT_STREAMOFF;
@@ -355,18 +349,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
 		if (!uvc->video.ep)
 			return -EINVAL;
 
-		if (uvc->video.ep->driver_data) {
-			INFO(cdev, "reset UVC\n");
-			usb_ep_disable(uvc->video.ep);
-			uvc->video.ep->driver_data = NULL;
-		}
+		INFO(cdev, "reset UVC\n");
+		usb_ep_disable(uvc->video.ep);
 
 		ret = config_ep_by_speed(f->config->cdev->gadget,
 				&(uvc->func), uvc->video.ep);
 		if (ret)
 			return ret;
 		usb_ep_enable(uvc->video.ep);
-		uvc->video.ep->driver_data = uvc;
 
 		memset(&v4l2_event, 0, sizeof(v4l2_event));
 		v4l2_event.type = UVC_EVENT_STREAMON;
@@ -392,15 +382,8 @@ uvc_function_disable(struct usb_function *f)
 
 	uvc->state = UVC_STATE_DISCONNECTED;
 
-	if (uvc->video.ep->driver_data) {
-		usb_ep_disable(uvc->video.ep);
-		uvc->video.ep->driver_data = NULL;
-	}
-
-	if (uvc->control_ep->driver_data) {
-		usb_ep_disable(uvc->control_ep);
-		uvc->control_ep->driver_data = NULL;
-	}
+	usb_ep_disable(uvc->video.ep);
+	usb_ep_disable(uvc->control_ep);
 }
 
 /* --------------------------------------------------------------------------
@@ -651,7 +634,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
 		goto error;
 	}
 	uvc->control_ep = ep;
-	ep->driver_data = uvc;
 
 	if (gadget_is_superspeed(c->cdev->gadget))
 		ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
@@ -666,7 +648,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
 		goto error;
 	}
 	uvc->video.ep = ep;
-	ep->driver_data = uvc;
 
 	uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
 	uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
@@ -755,11 +736,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
 error:
 	v4l2_device_unregister(&uvc->v4l2_dev);
 
-	if (uvc->control_ep)
-		uvc->control_ep->driver_data = NULL;
-	if (uvc->video.ep)
-		uvc->video.ep->driver_data = NULL;
-
 	if (uvc->control_req)
 		usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
 	kfree(uvc->control_buf);
@@ -886,8 +862,6 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f)
 
 	video_unregister_device(&uvc->vdev);
 	v4l2_device_unregister(&uvc->v4l2_dev);
-	uvc->control_ep->driver_data = NULL;
-	uvc->video.ep->driver_data = NULL;
 
 	usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
 	kfree(uvc->control_buf);
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index f1fd777ef4ec6bcf3bb233074c3aab53d62493a3..6554322af2c16a076385ba021b8ee15c8483bdc1 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -48,6 +48,11 @@
 
 #define UETH__VERSION	"29-May-2008"
 
+/* Experiments show that both Linux and Windows hosts allow up to 16k
+ * frame sizes. Set the max size to 15k+52 to prevent allocating 32k
+ * blocks and still have efficient handling. */
+#define GETHER_MAX_ETH_FRAME_LEN 15412
+
 struct eth_dev {
 	/* lock is held while accessing port_usb
 	 */
@@ -146,7 +151,7 @@ static int ueth_change_mtu(struct net_device *net, int new_mtu)
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->port_usb)
 		status = -EBUSY;
-	else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
+	else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN)
 		status = -ERANGE;
 	else
 		net->mtu = new_mtu;
@@ -294,7 +299,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
 		while (skb2) {
 			if (status < 0
 					|| ETH_HLEN > skb2->len
-					|| skb2->len > VLAN_ETH_FRAME_LEN) {
+					|| skb2->len > GETHER_MAX_ETH_FRAME_LEN) {
 				dev->net->stats.rx_errors++;
 				dev->net->stats.rx_length_errors++;
 				DBG(dev, "rx length %d\n", skb2->len);
@@ -1144,7 +1149,6 @@ void gether_disconnect(struct gether *link)
 		spin_lock(&dev->req_lock);
 	}
 	spin_unlock(&dev->req_lock);
-	link->in_ep->driver_data = NULL;
 	link->in_ep->desc = NULL;
 
 	usb_ep_disable(link->out_ep);
@@ -1159,7 +1163,6 @@ void gether_disconnect(struct gether *link)
 		spin_lock(&dev->req_lock);
 	}
 	spin_unlock(&dev->req_lock);
-	link->out_ep->driver_data = NULL;
 	link->out_ep->desc = NULL;
 
 	/* finish forgetting about this USB link episode */
diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c
index 7ee057930ae71793bcbd2777cb275572af21c295..9cc6a13d5e5b04893658b3ab83f507ab73c58658 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -876,7 +876,6 @@ static void gs_close(struct tty_struct *tty, struct file *file)
 	else
 		gs_buf_clear(&port->port_write_buf);
 
-	tty->driver_data = NULL;
 	port->port.tty = NULL;
 
 	port->openclose = false;
@@ -1224,7 +1223,6 @@ int gserial_connect(struct gserial *gser, u8 port_num)
 
 fail_out:
 	usb_ep_disable(gser->in);
-	gser->in->driver_data = NULL;
 	return status;
 }
 EXPORT_SYMBOL_GPL(gserial_connect);
@@ -1264,10 +1262,7 @@ void gserial_disconnect(struct gserial *gser)
 
 	/* disable endpoints, aborting down any active I/O */
 	usb_ep_disable(gser->out);
-	gser->out->driver_data = NULL;
-
 	usb_ep_disable(gser->in);
-	gser->in->driver_data = NULL;
 
 	/* finally, free any unused/unusable I/O buffers */
 	spin_lock_irqsave(&port->port_lock, flags);
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c
index 5231a32aef55a4c6640a772038a260b76d7bf2b6..99ca3dabc4f34c6c2cacc7957323128b2b10f544 100644
--- a/drivers/usb/gadget/legacy/dbgp.c
+++ b/drivers/usb/gadget/legacy/dbgp.c
@@ -79,10 +79,7 @@ static int dbgp_consume(char *buf, unsigned len)
 
 static void __disable_ep(struct usb_ep *ep)
 {
-	if (ep && ep->driver_data == dbgp.gadget) {
-		usb_ep_disable(ep);
-		ep->driver_data = NULL;
-	}
+	usb_ep_disable(ep);
 }
 
 static void dbgp_disable_ep(void)
@@ -171,7 +168,6 @@ static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc)
 	int err;
 	ep->desc = desc;
 	err = usb_ep_enable(ep);
-	ep->driver_data = dbgp.gadget;
 	return err;
 }
 
@@ -229,8 +225,6 @@ static void dbgp_unbind(struct usb_gadget *gadget)
 		usb_ep_free_request(gadget->ep0, dbgp.req);
 		dbgp.req = NULL;
 	}
-
-	gadget->ep0->driver_data = NULL;
 }
 
 #ifdef CONFIG_USB_G_DBGP_SERIAL
@@ -249,18 +243,15 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget)
 		goto fail_1;
 	}
 
-	dbgp.i_ep->driver_data = gadget;
 	i_desc.wMaxPacketSize =
 		cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE);
 
 	dbgp.o_ep = usb_ep_autoconfig(gadget, &o_desc);
 	if (!dbgp.o_ep) {
-		dbgp.i_ep->driver_data = NULL;
 		stp = 2;
-		goto fail_2;
+		goto fail_1;
 	}
 
-	dbgp.o_ep->driver_data = gadget;
 	o_desc.wMaxPacketSize =
 		cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE);
 
@@ -277,8 +268,6 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget)
 
 	return 0;
 
-fail_2:
-	dbgp.i_ep->driver_data = NULL;
 fail_1:
 	dev_dbg(&dbgp.gadget->dev, "ep config: failure (%d)\n", stp);
 	return -ENODEV;
@@ -306,7 +295,6 @@ static int dbgp_bind(struct usb_gadget *gadget,
 	}
 
 	dbgp.req->length = DBGP_REQ_EP0_LEN;
-	gadget->ep0->driver_data = gadget;
 
 #ifdef CONFIG_USB_G_DBGP_SERIAL
 	dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL);
@@ -356,8 +344,6 @@ static int dbgp_setup(struct usb_gadget *gadget,
 	void *data = NULL;
 	u16 len = 0;
 
-	gadget->ep0->driver_data = gadget;
-
 	if (request == USB_REQ_GET_DESCRIPTOR) {
 		switch (value>>8) {
 		case USB_DT_DEVICE:
diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c
index c3c48088fced7b90703b068b2527635a6a5e01ea..778e42abb3cb8703fcf19b829e21f764ac798d1e 100644
--- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c
@@ -2018,14 +2018,6 @@ static struct usb_configuration usbg_config_driver = {
 	.bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 };
 
-static void give_back_ep(struct usb_ep **pep)
-{
-	struct usb_ep *ep = *pep;
-	if (!ep)
-		return;
-	ep->driver_data = NULL;
-}
-
 static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct f_uas		*fu = to_f_uas(f);
@@ -2045,29 +2037,24 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 			&uasp_bi_ep_comp_desc);
 	if (!ep)
 		goto ep_fail;
-
-	ep->driver_data = fu;
 	fu->ep_in = ep;
 
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
 			&uasp_bo_ep_comp_desc);
 	if (!ep)
 		goto ep_fail;
-	ep->driver_data = fu;
 	fu->ep_out = ep;
 
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
 			&uasp_status_in_ep_comp_desc);
 	if (!ep)
 		goto ep_fail;
-	ep->driver_data = fu;
 	fu->ep_status = ep;
 
 	ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
 			&uasp_cmd_comp_desc);
 	if (!ep)
 		goto ep_fail;
-	ep->driver_data = fu;
 	fu->ep_cmd = ep;
 
 	/* Assume endpoint addresses are the same for both speeds */
@@ -2091,11 +2078,6 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 ep_fail:
 	pr_err("Can't claim all required eps\n");
-
-	give_back_ep(&fu->ep_in);
-	give_back_ep(&fu->ep_out);
-	give_back_ep(&fu->ep_status);
-	give_back_ep(&fu->ep_cmd);
 	return -ENOTSUPP;
 }
 
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 9a3a6b00391aa41042836d78d1b88eed27b9ee73..cdbff54e07acc4365a387bdd726ce8e34546a389 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -55,7 +55,7 @@ config USB_LPC32XX
 
 config USB_ATMEL_USBA
 	tristate "Atmel USBA"
-	depends on AVR32 || ARCH_AT91
+	depends on ((AVR32 && !OF) || ARCH_AT91)
 	help
 	  USBA is the integrated high-speed USB Device controller on
 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c
index 175ca93fe5e2d5159804301e99d12e6f048a47da..cd8764150861cf1c677bb25a52f4a1b00294b52e 100644
--- a/drivers/usb/gadget/udc/amd5536udc.c
+++ b/drivers/usb/gadget/udc/amd5536udc.c
@@ -65,18 +65,10 @@
 
 static void udc_tasklet_disconnect(unsigned long);
 static void empty_req_queue(struct udc_ep *);
-static int udc_probe(struct udc *dev);
-static void udc_basic_init(struct udc *dev);
 static void udc_setup_endpoints(struct udc *dev);
 static void udc_soft_reset(struct udc *dev);
 static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep);
 static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq);
-static int udc_free_dma_chain(struct udc *dev, struct udc_request *req);
-static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req,
-				unsigned long buf_len, gfp_t gfp_flags);
-static int udc_remote_wakeup(struct udc *dev);
-static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
-static void udc_pci_remove(struct pci_dev *pdev);
 
 /* description */
 static const char mod_desc[] = UDC_MOD_DESCRIPTION;
@@ -615,6 +607,30 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
 	return &req->req;
 }
 
+/* frees pci pool descriptors of a DMA chain */
+static int udc_free_dma_chain(struct udc *dev, struct udc_request *req)
+{
+	int ret_val = 0;
+	struct udc_data_dma	*td;
+	struct udc_data_dma	*td_last = NULL;
+	unsigned int i;
+
+	DBG(dev, "free chain req = %p\n", req);
+
+	/* do not free first desc., will be done by free for request */
+	td_last = req->td_data;
+	td = phys_to_virt(td_last->next);
+
+	for (i = 1; i < req->chain_len; i++) {
+		pci_pool_free(dev->data_requests, td,
+			      (dma_addr_t)td_last->next);
+		td_last = td;
+		td = phys_to_virt(td_last->next);
+	}
+
+	return ret_val;
+}
+
 /* Frees request packet, called by gadget driver */
 static void
 udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq)
@@ -789,6 +805,123 @@ udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req)
 	return finished;
 }
 
+/* Creates or re-inits a DMA chain */
+static int udc_create_dma_chain(
+	struct udc_ep *ep,
+	struct udc_request *req,
+	unsigned long buf_len, gfp_t gfp_flags
+)
+{
+	unsigned long bytes = req->req.length;
+	unsigned int i;
+	dma_addr_t dma_addr;
+	struct udc_data_dma	*td = NULL;
+	struct udc_data_dma	*last = NULL;
+	unsigned long txbytes;
+	unsigned create_new_chain = 0;
+	unsigned len;
+
+	VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n",
+	     bytes, buf_len);
+	dma_addr = DMA_DONT_USE;
+
+	/* unset L bit in first desc for OUT */
+	if (!ep->in)
+		req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L);
+
+	/* alloc only new desc's if not already available */
+	len = req->req.length / ep->ep.maxpacket;
+	if (req->req.length % ep->ep.maxpacket)
+		len++;
+
+	if (len > req->chain_len) {
+		/* shorter chain already allocated before */
+		if (req->chain_len > 1)
+			udc_free_dma_chain(ep->dev, req);
+		req->chain_len = len;
+		create_new_chain = 1;
+	}
+
+	td = req->td_data;
+	/* gen. required number of descriptors and buffers */
+	for (i = buf_len; i < bytes; i += buf_len) {
+		/* create or determine next desc. */
+		if (create_new_chain) {
+			td = pci_pool_alloc(ep->dev->data_requests,
+					    gfp_flags, &dma_addr);
+			if (!td)
+				return -ENOMEM;
+
+			td->status = 0;
+		} else if (i == buf_len) {
+			/* first td */
+			td = (struct udc_data_dma *)phys_to_virt(
+						req->td_data->next);
+			td->status = 0;
+		} else {
+			td = (struct udc_data_dma *)phys_to_virt(last->next);
+			td->status = 0;
+		}
+
+		if (td)
+			td->bufptr = req->req.dma + i; /* assign buffer */
+		else
+			break;
+
+		/* short packet ? */
+		if ((bytes - i) >= buf_len) {
+			txbytes = buf_len;
+		} else {
+			/* short packet */
+			txbytes = bytes - i;
+		}
+
+		/* link td and assign tx bytes */
+		if (i == buf_len) {
+			if (create_new_chain)
+				req->td_data->next = dma_addr;
+			/*
+			 * else
+			 *	req->td_data->next = virt_to_phys(td);
+			 */
+			/* write tx bytes */
+			if (ep->in) {
+				/* first desc */
+				req->td_data->status =
+					AMD_ADDBITS(req->td_data->status,
+						    ep->ep.maxpacket,
+						    UDC_DMA_IN_STS_TXBYTES);
+				/* second desc */
+				td->status = AMD_ADDBITS(td->status,
+							txbytes,
+							UDC_DMA_IN_STS_TXBYTES);
+			}
+		} else {
+			if (create_new_chain)
+				last->next = dma_addr;
+			/*
+			 * else
+			 *	last->next = virt_to_phys(td);
+			 */
+			if (ep->in) {
+				/* write tx bytes */
+				td->status = AMD_ADDBITS(td->status,
+							txbytes,
+							UDC_DMA_IN_STS_TXBYTES);
+			}
+		}
+		last = td;
+	}
+	/* set last bit */
+	if (td) {
+		td->status |= AMD_BIT(UDC_DMA_IN_STS_L);
+		/* last desc. points to itself */
+		req->td_data_last = td;
+	}
+
+	return 0;
+}
+
 /* create/re-init a DMA descriptor or a DMA descriptor chain */
 static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp)
 {
@@ -913,32 +1046,6 @@ __acquires(ep->dev->lock)
 	ep->halted = halted;
 }
 
-/* frees pci pool descriptors of a DMA chain */
-static int udc_free_dma_chain(struct udc *dev, struct udc_request *req)
-{
-
-	int ret_val = 0;
-	struct udc_data_dma	*td;
-	struct udc_data_dma	*td_last = NULL;
-	unsigned int i;
-
-	DBG(dev, "free chain req = %p\n", req);
-
-	/* do not free first desc., will be done by free for request */
-	td_last = req->td_data;
-	td = phys_to_virt(td_last->next);
-
-	for (i = 1; i < req->chain_len; i++) {
-
-		pci_pool_free(dev->data_requests, td,
-				(dma_addr_t) td_last->next);
-		td_last = td;
-		td = phys_to_virt(td_last->next);
-	}
-
-	return ret_val;
-}
-
 /* Iterates to the end of a DMA chain and returns last descriptor */
 static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req)
 {
@@ -975,125 +1082,6 @@ static u32 udc_get_ppbdu_rxbytes(struct udc_request *req)
 
 }
 
-/* Creates or re-inits a DMA chain */
-static int udc_create_dma_chain(
-	struct udc_ep *ep,
-	struct udc_request *req,
-	unsigned long buf_len, gfp_t gfp_flags
-)
-{
-	unsigned long bytes = req->req.length;
-	unsigned int i;
-	dma_addr_t dma_addr;
-	struct udc_data_dma	*td = NULL;
-	struct udc_data_dma	*last = NULL;
-	unsigned long txbytes;
-	unsigned create_new_chain = 0;
-	unsigned len;
-
-	VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n",
-			bytes, buf_len);
-	dma_addr = DMA_DONT_USE;
-
-	/* unset L bit in first desc for OUT */
-	if (!ep->in)
-		req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L);
-
-	/* alloc only new desc's if not already available */
-	len = req->req.length / ep->ep.maxpacket;
-	if (req->req.length % ep->ep.maxpacket)
-		len++;
-
-	if (len > req->chain_len) {
-		/* shorter chain already allocated before */
-		if (req->chain_len > 1)
-			udc_free_dma_chain(ep->dev, req);
-		req->chain_len = len;
-		create_new_chain = 1;
-	}
-
-	td = req->td_data;
-	/* gen. required number of descriptors and buffers */
-	for (i = buf_len; i < bytes; i += buf_len) {
-		/* create or determine next desc. */
-		if (create_new_chain) {
-
-			td = pci_pool_alloc(ep->dev->data_requests,
-					gfp_flags, &dma_addr);
-			if (!td)
-				return -ENOMEM;
-
-			td->status = 0;
-		} else if (i == buf_len) {
-			/* first td */
-			td = (struct udc_data_dma *) phys_to_virt(
-						req->td_data->next);
-			td->status = 0;
-		} else {
-			td = (struct udc_data_dma *) phys_to_virt(last->next);
-			td->status = 0;
-		}
-
-
-		if (td)
-			td->bufptr = req->req.dma + i; /* assign buffer */
-		else
-			break;
-
-		/* short packet ? */
-		if ((bytes - i) >= buf_len) {
-			txbytes = buf_len;
-		} else {
-			/* short packet */
-			txbytes = bytes - i;
-		}
-
-		/* link td and assign tx bytes */
-		if (i == buf_len) {
-			if (create_new_chain)
-				req->td_data->next = dma_addr;
-			/*
-			else
-				req->td_data->next = virt_to_phys(td);
-			*/
-			/* write tx bytes */
-			if (ep->in) {
-				/* first desc */
-				req->td_data->status =
-					AMD_ADDBITS(req->td_data->status,
-							ep->ep.maxpacket,
-							UDC_DMA_IN_STS_TXBYTES);
-				/* second desc */
-				td->status = AMD_ADDBITS(td->status,
-							txbytes,
-							UDC_DMA_IN_STS_TXBYTES);
-			}
-		} else {
-			if (create_new_chain)
-				last->next = dma_addr;
-			/*
-			else
-				last->next = virt_to_phys(td);
-			*/
-			if (ep->in) {
-				/* write tx bytes */
-				td->status = AMD_ADDBITS(td->status,
-							txbytes,
-							UDC_DMA_IN_STS_TXBYTES);
-			}
-		}
-		last = td;
-	}
-	/* set last bit */
-	if (td) {
-		td->status |= AMD_BIT(UDC_DMA_IN_STS_L);
-		/* last desc. points to itself */
-		req->td_data_last = td;
-	}
-
-	return 0;
-}
-
 /* Enabling RX DMA */
 static void udc_set_rde(struct udc *dev)
 {
@@ -1453,6 +1441,26 @@ static int udc_get_frame(struct usb_gadget *gadget)
 	return -EOPNOTSUPP;
 }
 
+/* Initiates a remote wakeup */
+static int udc_remote_wakeup(struct udc *dev)
+{
+	unsigned long flags;
+	u32 tmp;
+
+	DBG(dev, "UDC initiates remote wakeup\n");
+
+	spin_lock_irqsave(&dev->lock, flags);
+
+	tmp = readl(&dev->regs->ctl);
+	tmp |= AMD_BIT(UDC_DEVCTL_RES);
+	writel(tmp, &dev->regs->ctl);
+	tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES);
+	writel(tmp, &dev->regs->ctl);
+
+	spin_unlock_irqrestore(&dev->lock, flags);
+	return 0;
+}
+
 /* Remote wakeup gadget interface */
 static int udc_wakeup(struct usb_gadget *gadget)
 {
@@ -1498,33 +1506,6 @@ static void make_ep_lists(struct udc *dev)
 	dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE;
 }
 
-/* init registers at driver load time */
-static int startup_registers(struct udc *dev)
-{
-	u32 tmp;
-
-	/* init controller by soft reset */
-	udc_soft_reset(dev);
-
-	/* mask not needed interrupts */
-	udc_mask_unused_interrupts(dev);
-
-	/* put into initial config */
-	udc_basic_init(dev);
-	/* link up all endpoints */
-	udc_setup_endpoints(dev);
-
-	/* program speed */
-	tmp = readl(&dev->regs->cfg);
-	if (use_fullspeed)
-		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD);
-	else
-		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD);
-	writel(tmp, &dev->regs->cfg);
-
-	return 0;
-}
-
 /* Inits UDC context */
 static void udc_basic_init(struct udc *dev)
 {
@@ -1563,6 +1544,33 @@ static void udc_basic_init(struct udc *dev)
 	dev->data_ep_queued = 0;
 }
 
+/* init registers at driver load time */
+static int startup_registers(struct udc *dev)
+{
+	u32 tmp;
+
+	/* init controller by soft reset */
+	udc_soft_reset(dev);
+
+	/* mask not needed interrupts */
+	udc_mask_unused_interrupts(dev);
+
+	/* put into initial config */
+	udc_basic_init(dev);
+	/* link up all endpoints */
+	udc_setup_endpoints(dev);
+
+	/* program speed */
+	tmp = readl(&dev->regs->cfg);
+	if (use_fullspeed)
+		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD);
+	else
+		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD);
+	writel(tmp, &dev->regs->cfg);
+
+	return 0;
+}
+
 /* Sets initial endpoint parameters */
 static void udc_setup_endpoints(struct udc *dev)
 {
@@ -2177,7 +2185,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix)
 		}
 
 	/* DMA */
-	} else if (!ep->cancel_transfer && req != NULL) {
+	} else if (!ep->cancel_transfer && req) {
 		ret_val = IRQ_HANDLED;
 
 		/* check for DMA done */
@@ -3107,6 +3115,17 @@ static void udc_remove(struct udc *dev)
 	udc = NULL;
 }
 
+/* free all the dma pools */
+static void free_dma_pools(struct udc *dev)
+{
+	dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td,
+		      dev->ep[UDC_EP0OUT_IX].td_phys);
+	dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp,
+		      dev->ep[UDC_EP0OUT_IX].td_stp_dma);
+	dma_pool_destroy(dev->stp_requests);
+	dma_pool_destroy(dev->data_requests);
+}
+
 /* Reset all pci context */
 static void udc_pci_remove(struct pci_dev *pdev)
 {
@@ -3116,35 +3135,19 @@ static void udc_pci_remove(struct pci_dev *pdev)
 
 	usb_del_gadget_udc(&udc->gadget);
 	/* gadget driver must not be registered */
-	BUG_ON(dev->driver != NULL);
+	if (WARN_ON(dev->driver))
+		return;
 
 	/* dma pool cleanup */
-	if (dev->data_requests)
-		pci_pool_destroy(dev->data_requests);
-
-	if (dev->stp_requests) {
-		/* cleanup DMA desc's for ep0in */
-		pci_pool_free(dev->stp_requests,
-			dev->ep[UDC_EP0OUT_IX].td_stp,
-			dev->ep[UDC_EP0OUT_IX].td_stp_dma);
-		pci_pool_free(dev->stp_requests,
-			dev->ep[UDC_EP0OUT_IX].td,
-			dev->ep[UDC_EP0OUT_IX].td_phys);
-
-		pci_pool_destroy(dev->stp_requests);
-	}
+	free_dma_pools(dev);
 
 	/* reset controller */
 	writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg);
-	if (dev->irq_registered)
-		free_irq(pdev->irq, dev);
-	if (dev->virt_addr)
-		iounmap(dev->virt_addr);
-	if (dev->mem_region)
-		release_mem_region(pci_resource_start(pdev, 0),
-				pci_resource_len(pdev, 0));
-	if (dev->active)
-		pci_disable_device(pdev);
+	free_irq(pdev->irq, dev);
+	iounmap(dev->virt_addr);
+	release_mem_region(pci_resource_start(pdev, 0),
+			   pci_resource_len(pdev, 0));
+	pci_disable_device(pdev);
 
 	udc_remove(dev);
 }
@@ -3169,8 +3172,7 @@ static int init_dma_pools(struct udc *dev)
 		sizeof(struct udc_data_dma), 0, 0);
 	if (!dev->data_requests) {
 		DBG(dev, "can't get request data pool\n");
-		retval = -ENOMEM;
-		goto finished;
+		return -ENOMEM;
 	}
 
 	/* EP0 in dma regs = dev control regs */
@@ -3182,27 +3184,101 @@ static int init_dma_pools(struct udc *dev)
 	if (!dev->stp_requests) {
 		DBG(dev, "can't get stp request pool\n");
 		retval = -ENOMEM;
-		goto finished;
+		goto err_create_dma_pool;
 	}
 	/* setup */
 	td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
 				&dev->ep[UDC_EP0OUT_IX].td_stp_dma);
-	if (td_stp == NULL) {
+	if (!td_stp) {
 		retval = -ENOMEM;
-		goto finished;
+		goto err_alloc_dma;
 	}
 	dev->ep[UDC_EP0OUT_IX].td_stp = td_stp;
 
 	/* data: 0 packets !? */
 	td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
 				&dev->ep[UDC_EP0OUT_IX].td_phys);
-	if (td_data == NULL) {
+	if (!td_data) {
 		retval = -ENOMEM;
-		goto finished;
+		goto err_alloc_phys;
 	}
 	dev->ep[UDC_EP0OUT_IX].td = td_data;
 	return 0;
 
+err_alloc_phys:
+	dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp,
+		      dev->ep[UDC_EP0OUT_IX].td_stp_dma);
+err_alloc_dma:
+	dma_pool_destroy(dev->stp_requests);
+	dev->stp_requests = NULL;
+err_create_dma_pool:
+	dma_pool_destroy(dev->data_requests);
+	dev->data_requests = NULL;
+	return retval;
+}
+
+/* general probe */
+static int udc_probe(struct udc *dev)
+{
+	char		tmp[128];
+	u32		reg;
+	int		retval;
+
+	/* mark timer as not initialized */
+	udc_timer.data = 0;
+	udc_pollstall_timer.data = 0;
+
+	/* device struct setup */
+	dev->gadget.ops = &udc_ops;
+
+	dev_set_name(&dev->gadget.dev, "gadget");
+	dev->gadget.name = name;
+	dev->gadget.max_speed = USB_SPEED_HIGH;
+
+	/* init registers, interrupts, ... */
+	startup_registers(dev);
+
+	dev_info(&dev->pdev->dev, "%s\n", mod_desc);
+
+	snprintf(tmp, sizeof(tmp), "%d", dev->irq);
+	dev_info(&dev->pdev->dev,
+		 "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n",
+		 tmp, dev->phys_addr, dev->chiprev,
+		 (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1");
+	strcpy(tmp, UDC_DRIVER_VERSION_STRING);
+	if (dev->chiprev == UDC_HSA0_REV) {
+		dev_err(&dev->pdev->dev, "chip revision is A0; too old\n");
+		retval = -ENODEV;
+		goto finished;
+	}
+	dev_info(&dev->pdev->dev,
+		 "driver version: %s(for Geode5536 B1)\n", tmp);
+	udc = dev;
+
+	retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget,
+					    gadget_release);
+	if (retval)
+		goto finished;
+
+	/* timer init */
+	init_timer(&udc_timer);
+	udc_timer.function = udc_timer_function;
+	udc_timer.data = 1;
+	/* timer pollstall init */
+	init_timer(&udc_pollstall_timer);
+	udc_pollstall_timer.function = udc_pollstall_timer_function;
+	udc_pollstall_timer.data = 1;
+
+	/* set SD */
+	reg = readl(&dev->regs->ctl);
+	reg |= AMD_BIT(UDC_DEVCTL_SD);
+	writel(reg, &dev->regs->ctl);
+
+	/* print dev register info */
+	print_regs(dev);
+
+	return 0;
+
 finished:
 	return retval;
 }
@@ -3234,7 +3310,6 @@ static int udc_pci_probe(
 		retval = -ENODEV;
 		goto err_pcidev;
 	}
-	dev->active = 1;
 
 	/* PCI resource allocation */
 	resource = pci_resource_start(pdev, 0);
@@ -3245,10 +3320,9 @@ static int udc_pci_probe(
 		retval = -EBUSY;
 		goto err_memreg;
 	}
-	dev->mem_region = 1;
 
 	dev->virt_addr = ioremap_nocache(resource, len);
-	if (dev->virt_addr == NULL) {
+	if (!dev->virt_addr) {
 		dev_dbg(&pdev->dev, "start address cannot be mapped\n");
 		retval = -EFAULT;
 		goto err_ioremap;
@@ -3276,7 +3350,6 @@ static int udc_pci_probe(
 		retval = -EBUSY;
 		goto err_irq;
 	}
-	dev->irq_registered = 1;
 
 	pci_set_drvdata(pdev, dev);
 
@@ -3290,7 +3363,7 @@ static int udc_pci_probe(
 	if (use_dma) {
 		retval = init_dma_pools(dev);
 		if (retval != 0)
-			goto finished;
+			goto err_dma;
 	}
 
 	dev->phys_addr = resource;
@@ -3298,13 +3371,17 @@ static int udc_pci_probe(
 	dev->pdev = pdev;
 
 	/* general probing */
-	if (udc_probe(dev) == 0)
-		return 0;
-
-finished:
-	udc_pci_remove(pdev);
-	return retval;
+	if (udc_probe(dev)) {
+		retval = -ENODEV;
+		goto err_probe;
+	}
+	return 0;
 
+err_probe:
+	if (use_dma)
+		free_dma_pools(dev);
+err_dma:
+	free_irq(pdev->irq, dev);
 err_irq:
 	iounmap(dev->virt_addr);
 err_ioremap:
@@ -3316,92 +3393,6 @@ static int udc_pci_probe(
 	return retval;
 }
 
-/* general probe */
-static int udc_probe(struct udc *dev)
-{
-	char		tmp[128];
-	u32		reg;
-	int		retval;
-
-	/* mark timer as not initialized */
-	udc_timer.data = 0;
-	udc_pollstall_timer.data = 0;
-
-	/* device struct setup */
-	dev->gadget.ops = &udc_ops;
-
-	dev_set_name(&dev->gadget.dev, "gadget");
-	dev->gadget.name = name;
-	dev->gadget.max_speed = USB_SPEED_HIGH;
-
-	/* init registers, interrupts, ... */
-	startup_registers(dev);
-
-	dev_info(&dev->pdev->dev, "%s\n", mod_desc);
-
-	snprintf(tmp, sizeof tmp, "%d", dev->irq);
-	dev_info(&dev->pdev->dev,
-		"irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n",
-		tmp, dev->phys_addr, dev->chiprev,
-		(dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1");
-	strcpy(tmp, UDC_DRIVER_VERSION_STRING);
-	if (dev->chiprev == UDC_HSA0_REV) {
-		dev_err(&dev->pdev->dev, "chip revision is A0; too old\n");
-		retval = -ENODEV;
-		goto finished;
-	}
-	dev_info(&dev->pdev->dev,
-		"driver version: %s(for Geode5536 B1)\n", tmp);
-	udc = dev;
-
-	retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget,
-			gadget_release);
-	if (retval)
-		goto finished;
-
-	/* timer init */
-	init_timer(&udc_timer);
-	udc_timer.function = udc_timer_function;
-	udc_timer.data = 1;
-	/* timer pollstall init */
-	init_timer(&udc_pollstall_timer);
-	udc_pollstall_timer.function = udc_pollstall_timer_function;
-	udc_pollstall_timer.data = 1;
-
-	/* set SD */
-	reg = readl(&dev->regs->ctl);
-	reg |= AMD_BIT(UDC_DEVCTL_SD);
-	writel(reg, &dev->regs->ctl);
-
-	/* print dev register info */
-	print_regs(dev);
-
-	return 0;
-
-finished:
-	return retval;
-}
-
-/* Initiates a remote wakeup */
-static int udc_remote_wakeup(struct udc *dev)
-{
-	unsigned long flags;
-	u32 tmp;
-
-	DBG(dev, "UDC initiates remote wakeup\n");
-
-	spin_lock_irqsave(&dev->lock, flags);
-
-	tmp = readl(&dev->regs->ctl);
-	tmp |= AMD_BIT(UDC_DEVCTL_RES);
-	writel(tmp, &dev->regs->ctl);
-	tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES);
-	writel(tmp, &dev->regs->ctl);
-
-	spin_unlock_irqrestore(&dev->lock, flags);
-	return 0;
-}
-
 /* PCI device parameters */
 static const struct pci_device_id pci_id[] = {
 	{
diff --git a/drivers/usb/gadget/udc/amd5536udc.h b/drivers/usb/gadget/udc/amd5536udc.h
index 6744d3b83109e6717425a450b14ed41f35088f71..4638d707f1698940eea06131fe0baf0cfbb2032f 100644
--- a/drivers/usb/gadget/udc/amd5536udc.h
+++ b/drivers/usb/gadget/udc/amd5536udc.h
@@ -526,14 +526,11 @@ struct udc {
 	struct udc_ep			ep[UDC_EP_NUM];
 	struct usb_gadget_driver	*driver;
 	/* operational flags */
-	unsigned			active : 1,
-					stall_ep0in : 1,
+	unsigned			stall_ep0in : 1,
 					waiting_zlp_ack_ep0in : 1,
 					set_cfg_not_acked : 1,
-					irq_registered : 1,
 					data_ep_enabled : 1,
 					data_ep_queued : 1,
-					mem_region : 1,
 					sys_suspended : 1,
 					connected;
 
diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h
index 2679c8b217ccdbf829c8ce001d323c265e33f974..0a433e6b346bca3f170d83a497a3bfe68cb863b6 100644
--- a/drivers/usb/gadget/udc/at91_udc.h
+++ b/drivers/usb/gadget/udc/at91_udc.h
@@ -112,6 +112,14 @@ struct at91_udc_caps {
 	void (*pullup)(struct at91_udc *udc, int is_on);
 };
 
+struct at91_udc_data {
+	int	vbus_pin;		/* high == host powering us */
+	u8	vbus_active_low;	/* vbus polarity */
+	u8	vbus_polled;		/* Use polling, not interrupt */
+	int	pullup_pin;		/* active == D+ pulled up */
+	u8	pullup_active_low;	/* true == pullup_pin is active low */
+};
+
 /*
  * driver is non-SMP, and just blocks IRQs whenever it needs
  * access protection for chip registers or driver state
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 27af0f008b57dd0999241c3e72919e6635fd9014..dde44450dfa93f1fab90da1bd47fd501aaf554e8 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -833,10 +833,10 @@ static const struct usb_ep_ops dummy_ep_ops = {
 /* there are both host and device side versions of this call ... */
 static int dummy_g_get_frame(struct usb_gadget *_gadget)
 {
-	struct timeval	tv;
+	struct timespec64 ts64;
 
-	do_gettimeofday(&tv);
-	return tv.tv_usec / 1000;
+	ktime_get_ts64(&ts64);
+	return ts64.tv_nsec / NSEC_PER_MSEC;
 }
 
 static int dummy_wakeup(struct usb_gadget *_gadget)
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
index cf0ed42f5591c93065d6d9c5741dea6967ad4829..6706aef907f4bdb32b308f148612a2566c2eb3b9 100644
--- a/drivers/usb/gadget/udc/net2280.c
+++ b/drivers/usb/gadget/udc/net2280.c
@@ -1913,7 +1913,7 @@ static void defect7374_disable_data_eps(struct net2280 *dev)
 
 	for (i = 1; i < 5; i++) {
 		ep = &dev->ep[i];
-		writel(0, &ep->cfg->ep_cfg);
+		writel(i, &ep->cfg->ep_cfg);
 	}
 
 	/* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c
index e5f4c5274298684576ac33794da6d929249af797..7a04157ff5796883f8c9ec3835b43c16155fbc3d 100644
--- a/drivers/usb/gadget/udc/pch_udc.c
+++ b/drivers/usb/gadget/udc/pch_udc.c
@@ -330,7 +330,7 @@ struct pch_vbus_gpio_data {
  * @prot_stall:		protcol stall requested
  * @irq_registered:	irq registered with system
  * @mem_region:		device memory mapped
- * @registered:		driver regsitered with system
+ * @registered:		driver registered with system
  * @suspended:		driver in suspended state
  * @connected:		gadget driver associated
  * @vbus_session:	required vbus_session state
@@ -2747,18 +2747,18 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr)
 	if (dev_intr & UDC_DEVINT_US) {
 		if (dev->driver
 			&& dev->driver->suspend) {
-			spin_lock(&dev->lock);
-			dev->driver->suspend(&dev->gadget);
 			spin_unlock(&dev->lock);
+			dev->driver->suspend(&dev->gadget);
+			spin_lock(&dev->lock);
 		}
 
 		vbus = pch_vbus_gpio_get_value(dev);
 		if ((dev->vbus_session == 0)
 			&& (vbus != 1)) {
 			if (dev->driver && dev->driver->disconnect) {
-				spin_lock(&dev->lock);
-				dev->driver->disconnect(&dev->gadget);
 				spin_unlock(&dev->lock);
+				dev->driver->disconnect(&dev->gadget);
+				spin_lock(&dev->lock);
 			}
 			pch_udc_reconnect(dev);
 		} else if ((dev->vbus_session == 0)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 079991e283e9e0a1dd1abcaf5794aa6dbf1aceb8..3bb08870148f467de4869c133fa6adfef4602116 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -348,16 +348,6 @@ config USB_ISP1362_HCD
 	  To compile this driver as a module, choose M here: the
 	  module will be called isp1362-hcd.
 
-config USB_FUSBH200_HCD
-	tristate "FUSBH200 HCD support"
-	depends on USB
-	---help---
-	Faraday FUSBH200 is designed to meet USB2.0 EHCI specification
-	with minor modification.
-
-	To compile this driver as a module, choose M here: the
-	module will be called fusbh200-hcd.
-
 config USB_FOTG210_HCD
 	tristate "FOTG210 HCD support"
 	depends on USB
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 754efaa8ccf8fbebf2e2c591ec4c77ae83893952..e7558abc994d76be29a347ed6904bca36d3765de 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -28,9 +28,6 @@ ifneq ($(CONFIG_USB), )
 	obj-$(CONFIG_PCI)	+= pci-quirks.o
 endif
 
-obj-$(CONFIG_USB_XHCI_PCI)	+= xhci-pci.o
-obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
-
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
 obj-$(CONFIG_USB_EHCI_HCD_PLATFORM)	+= ehci-platform.o
@@ -65,6 +62,8 @@ obj-$(CONFIG_USB_OHCI_HCD_PXA27X)	+= ohci-pxa27x.o
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o
 obj-$(CONFIG_USB_XHCI_HCD)	+= xhci-hcd.o
+obj-$(CONFIG_USB_XHCI_PCI)	+= xhci-pci.o
+obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
 obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
 obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
@@ -75,6 +74,5 @@ obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
 obj-$(CONFIG_USB_EHCI_FSL)	+= ehci-fsl.o
 obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
-obj-$(CONFIG_USB_FUSBH200_HCD)	+= fusbh200-hcd.o
 obj-$(CONFIG_USB_FOTG210_HCD)	+= fotg210-hcd.o
 obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 275c92e53a5972615166310742b63af0a8d61cf5..c4f84c81de0194e33b9bad75e6aafd1c9074dd74 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -80,12 +80,12 @@ static int ehci_msm_probe(struct platform_device *pdev)
 		return  -ENOMEM;
 	}
 
-	hcd->irq = platform_get_irq(pdev, 0);
-	if (hcd->irq < 0) {
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
 		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
-		ret = hcd->irq;
 		goto put_hcd;
 	}
+	hcd->irq = ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index bfcbb9aa8816bb5a4c84bef1d525ca8d086c8c66..ee8d5faa01947cd6d2c8cf708273c0521762a797 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -224,7 +224,8 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
 	priv->phy = devm_phy_optional_get(&pdev->dev, "usb");
 	if (IS_ERR(priv->phy)) {
 		err = PTR_ERR(priv->phy);
-		goto err_phy_get;
+		if (err != -ENOSYS)
+			goto err_phy_get;
 	} else {
 		err = phy_init(priv->phy);
 		if (err)
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 5c3c0859868251233c7672baf9f2ea01c5b82364..bd7082f297bbe76b7db8c10ad091402c79f45786 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -19,6 +19,7 @@
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
@@ -162,8 +163,10 @@ static int ehci_platform_probe(struct platform_device *dev)
 
 	err = dma_coerce_mask_and_coherent(&dev->dev,
 		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
-	if (err)
+	if (err) {
+		dev_err(&dev->dev, "Error: DMA mask configuration failed\n");
 		return err;
+	}
 
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
@@ -385,6 +388,12 @@ static const struct of_device_id vt8500_ehci_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
 
+static const struct acpi_device_id ehci_acpi_match[] = {
+	{ "PNP0D20", 0 }, /* EHCI controller without debug */
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
+
 static const struct platform_device_id ehci_platform_table[] = {
 	{ "ehci-platform", 0 },
 	{ }
@@ -403,6 +412,7 @@ static struct platform_driver ehci_platform_driver = {
 		.name	= "ehci-platform",
 		.pm	= &ehci_platform_pm_ops,
 		.of_match_table = vt8500_ehci_ids,
+		.acpi_match_table = ACPI_PTR(ehci_acpi_match),
 	}
 };
 
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index 34e14746b92eab6280c50c19317a9fd80a5fb87a..3c4e5253955c336a89d507329cf687a3240410ec 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -149,6 +149,7 @@ static const struct of_device_id spear_ehci_id_table[] = {
 	{ .compatible = "st,spear600-ehci", },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, spear_ehci_id_table);
 
 static struct platform_driver spear_ehci_hcd_driver = {
 	.probe		= spear_ehci_hcd_drv_probe,
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 000ed80ab592a0ce731023386a3636d3bd920976..787f4e3d16d81989dd71e9061d25992f789e000d 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1,5 +1,4 @@
-/*
- * Faraday FOTG210 EHCI-like driver
+/* Faraday FOTG210 EHCI-like driver
  *
  * Copyright (c) 2013 Faraday Technology Corporation
  *
@@ -50,32 +49,29 @@
 #include <asm/irq.h>
 #include <asm/unaligned.h>
 
-/*-------------------------------------------------------------------------*/
 #define DRIVER_AUTHOR "Yuan-Hsin Chen"
 #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-
-static const char	hcd_name[] = "fotg210_hcd";
+static const char hcd_name[] = "fotg210_hcd";
 
 #undef FOTG210_URB_TRACE
-
 #define FOTG210_STATS
 
 /* magic numbers that can affect system performance */
-#define	FOTG210_TUNE_CERR		3 /* 0-3 qtd retries; 0 == don't stop */
-#define	FOTG210_TUNE_RL_HS		4 /* nak throttle; see 4.9 */
-#define	FOTG210_TUNE_RL_TT		0
-#define	FOTG210_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FOTG210_TUNE_MULT_TT	1
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
+#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
+#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
+#define FOTG210_TUNE_RL_TT	0
+#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
+#define FOTG210_TUNE_MULT_TT	1
+
+/* Some drivers think it's safe to schedule isochronous transfers more than 256
+ * ms into the future (partly as a result of an old bug in the scheduling
  * code).  In an attempt to avoid trouble, we will use a minimum scheduling
  * length of 512 frames instead of 256.
  */
-#define	FOTG210_TUNE_FLS		1 /* (medium) 512-frame schedule */
+#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
 
 /* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh;		/* 0 to 6 */
+static int log2_irq_thresh; /* 0 to 6 */
 module_param(log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
@@ -89,66 +85,57 @@ static unsigned int hird;
 module_param(hird, int, S_IRUGO);
 MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
+#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
 
 #include "fotg210.h"
 
-/*-------------------------------------------------------------------------*/
-
 #define fotg210_dbg(fotg210, fmt, args...) \
-	dev_dbg(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_err(fotg210, fmt, args...) \
-	dev_err(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_info(fotg210, fmt, args...) \
-	dev_info(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_warn(fotg210, fmt, args...) \
-	dev_warn(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
+/* check the values in the HCSPARAMS register (host controller _Structural_
+ * parameters) see EHCI spec, Table 2-4 for each value
  */
 static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
 
-	fotg210_dbg(fotg210,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS(params)
-		);
+	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
+			HCS_N_PORTS(params));
 }
 
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
+/* check the values in the HCCPARAMS register (host controller _Capability_
+ * parameters) see EHCI Spec, Table 2-5 for each value
+ */
 static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
 
-	fotg210_dbg(fotg210,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
+	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
+			params,
+			HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+			HCC_CANPARK(params) ? " park" : "");
 }
 
 static void __maybe_unused
 dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
 {
 	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fotg210, &qtd->hw_next),
-		hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-		hc32_to_cpup(fotg210, &qtd->hw_token),
-		hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
+			hc32_to_cpup(fotg210, &qtd->hw_next),
+			hc32_to_cpup(fotg210, &qtd->hw_alt_next),
+			hc32_to_cpup(fotg210, &qtd->hw_token),
+			hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
 	if (qtd->hw_buf[1])
 		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
+				hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
 }
 
 static void __maybe_unused
@@ -156,101 +143,100 @@ dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 
-	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
+	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
+			hw->hw_next, hw->hw_info1, hw->hw_info2,
+			hw->hw_current);
+
 	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
 }
 
 static void __maybe_unused
 dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
-	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-		itd->urb);
+	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
+			itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
+			itd->urb);
+
 	fotg210_dbg(fotg210,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+			"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+			hc32_to_cpu(fotg210, itd->hw_transaction[0]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[1]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[2]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[3]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[4]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[5]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[6]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+
 	fotg210_dbg(fotg210,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+			"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
+			hc32_to_cpu(fotg210, itd->hw_bufp[0]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[1]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[2]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[3]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[4]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[5]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+
 	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
+			itd->index[0], itd->index[1], itd->index[2],
+			itd->index[3], itd->index[4], itd->index[5],
+			itd->index[6], itd->index[7]);
 }
 
 static int __maybe_unused
 dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
 {
-	return scnprintf(buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
+			label, label[0] ? " " : "", status,
+			(status & STS_ASS) ? " Async" : "",
+			(status & STS_PSS) ? " Periodic" : "",
+			(status & STS_RECL) ? " Recl" : "",
+			(status & STS_HALT) ? " Halt" : "",
+			(status & STS_IAA) ? " IAA" : "",
+			(status & STS_FATAL) ? " FATAL" : "",
+			(status & STS_FLR) ? " FLR" : "",
+			(status & STS_PCD) ? " PCD" : "",
+			(status & STS_ERR) ? " ERR" : "",
+			(status & STS_INT) ? " INT" : "");
 }
 
 static int __maybe_unused
 dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
 {
-	return scnprintf(buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label[0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
+			label, label[0] ? " " : "", enable,
+			(enable & STS_IAA) ? " IAA" : "",
+			(enable & STS_FATAL) ? " FATAL" : "",
+			(enable & STS_FLR) ? " FLR" : "",
+			(enable & STS_PCD) ? " PCD" : "",
+			(enable & STS_ERR) ? " ERR" : "",
+			(enable & STS_INT) ? " INT" : "");
 }
 
 static const char *const fls_strings[] = { "1024", "512", "256", "??" };
 
-static int
-dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
+static int dbg_command_buf(char *buf, unsigned len, const char *label,
+		u32 command)
 {
 	return scnprintf(buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label[0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT(command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings[(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static char
-*dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
+			"%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
+			label, label[0] ? " " : "", command,
+			(command & CMD_PARK) ? " park" : "(park)",
+			CMD_PARK_CNT(command),
+			(command >> 16) & 0x3f,
+			(command & CMD_IAAD) ? " IAAD" : "",
+			(command & CMD_ASE) ? " Async" : "",
+			(command & CMD_PSE) ? " Periodic" : "",
+			fls_strings[(command >> 2) & 0x3],
+			(command & CMD_RESET) ? " Reset" : "",
+			(command & CMD_RUN) ? "RUN" : "HALT");
+}
+
+static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
+		u32 status)
+{
+	char *sig;
 
 	/* signaling state */
 	switch (status & (3 << 10)) {
@@ -268,44 +254,41 @@ static char
 		break;
 	}
 
-	scnprintf(buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
+	scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
+			label, label[0] ? " " : "", port, status,
+			status >> 25, /*device address */
+			sig,
+			(status & PORT_RESET) ? " RESET" : "",
+			(status & PORT_SUSPEND) ? " SUSPEND" : "",
+			(status & PORT_RESUME) ? " RESUME" : "",
+			(status & PORT_PEC) ? " PEC" : "",
+			(status & PORT_PE) ? " PE" : "",
+			(status & PORT_CSC) ? " CSC" : "",
+			(status & PORT_CONNECT) ? " CONNECT" : "");
+
 	return buf;
 }
 
 /* functions have the "wrong" filename when they're output... */
-#define dbg_status(fotg210, label, status) { \
-	char _buf[80]; \
-	dbg_status_buf(_buf, sizeof(_buf), label, status); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_status(fotg210, label, status) {			\
+	char _buf[80];						\
+	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 
-#define dbg_cmd(fotg210, label, command) { \
-	char _buf[80]; \
-	dbg_command_buf(_buf, sizeof(_buf), label, command); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_cmd(fotg210, label, command) {			\
+	char _buf[80];						\
+	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 
-#define dbg_port(fotg210, label, port, status) { \
-	char _buf[80]; \
-	fotg210_dbg(fotg210, "%s\n", dbg_port_buf(_buf, sizeof(_buf), label, port, status) ); \
+#define dbg_port(fotg210, label, port, status) {			       \
+	char _buf[80];							       \
+	fotg210_dbg(fotg210, "%s\n",					       \
+			dbg_port_buf(_buf, sizeof(_buf), label, port, status));\
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* troubleshooting help: expose state in debugfs */
-
 static int debug_async_open(struct inode *, struct file *);
 static int debug_periodic_open(struct inode *, struct file *);
 static int debug_registers_open(struct inode *, struct file *);
@@ -347,17 +330,22 @@ struct debug_buffer {
 	size_t alloc_size;
 };
 
-#define speed_char(info1)({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED:	\
-			tmp = 'f'; break; \
-		case QH_LOW_SPEED:	\
-			tmp = 'l'; break; \
-		case QH_HIGH_SPEED:	\
-			tmp = 'h'; break; \
-		default:		\
-			tmp = '?'; break; \
-		} tmp; })
+static inline char speed_char(u32 scratch)
+{
+	switch (scratch & (3 << 12)) {
+	case QH_FULL_SPEED:
+		return 'f';
+
+	case QH_LOW_SPEED:
+		return 'l';
+
+	case QH_HIGH_SPEED:
+		return 'h';
+
+	default:
+		return '?';
+	}
+}
 
 static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 {
@@ -373,33 +361,29 @@ static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 	return '/';
 }
 
-static void qh_lines(
-	struct fotg210_hcd *fotg210,
-	struct fotg210_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fotg210_qtd	*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FOTG210_LIST_END(fotg210);
-	struct fotg210_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
+static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
+		char **nextp, unsigned *sizep)
+{
+	u32 scratch;
+	u32 hw_curr;
+	struct fotg210_qtd *td;
+	unsigned temp;
+	unsigned size = *sizep;
+	char *next = *nextp;
+	char mark;
+	__le32 list_end = FOTG210_LIST_END(fotg210);
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	if (hw->hw_qtd_next == list_end) /* NEC does this */
 		mark = '@';
 	else
 		mark = token_mark(fotg210, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fotg210))
-				== fotg210->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
+	if (mark == '/') { /* qh_alt_next controls qh advance? */
+		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
+		    fotg210->async->hw->hw_alt_next)
+			mark = '#'; /* blocked */
 		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
+			mark = '.'; /* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 	}
 	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
@@ -462,6 +446,7 @@ static void qh_lines(
 	temp = snprintf(next, size, "\n");
 	if (size < temp)
 		temp = size;
+
 	size -= temp;
 	next += temp;
 
@@ -472,12 +457,12 @@ static void qh_lines(
 
 static ssize_t fill_async_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fotg210_qh		*qh;
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size;
+	char *next;
+	struct fotg210_qh *qh;
 
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -492,7 +477,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	 */
 	spin_lock_irqsave(&fotg210->lock, flags);
 	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
-	     qh = qh->qh_next.qh)
+			qh = qh->qh_next.qh)
 		qh_lines(fotg210, qh, &next, &size);
 	if (fotg210->async_unlink && size > 0) {
 		temp = scnprintf(next, size, "\nunlink =\n");
@@ -508,21 +493,50 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	return strlen(buf->output_buf);
 }
 
+/* count tds, get ep direction */
+static unsigned output_buf_tds_dir(char *buf, struct fotg210_hcd *fotg210,
+		struct fotg210_qh_hw *hw, struct fotg210_qh *qh, unsigned size)
+{
+	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
+	struct fotg210_qtd *qtd;
+	char *type = "";
+	unsigned temp = 0;
+
+	/* count tds, get ep direction */
+	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
+		temp++;
+		switch ((hc32_to_cpu(fotg210, qtd->hw_token) >> 8) & 0x03) {
+		case 0:
+			type = "out";
+			continue;
+		case 1:
+			type = "in";
+			continue;
+		}
+	}
+
+	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
+			speed_char(scratch), scratch & 0x007f,
+			(scratch >> 8) & 0x000f, type, qh->usecs,
+			qh->c_usecs, temp, (scratch >> 16) & 0x7ff);
+}
+
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd		*fotg210;
-	unsigned long		flags;
-	union fotg210_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
-
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	union fotg210_shadow p, *seen;
+	unsigned temp, size, seen_count;
+	char *next;
+	unsigned i;
+	__hc32 tag;
+
+	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
 	if (!seen)
 		return 0;
+
 	seen_count = 0;
 
 	hcd = bus_to_hcd(buf->bus);
@@ -542,6 +556,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 		p = fotg210->pshadow[i];
 		if (likely(!p.ptr))
 			continue;
+
 		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
 
 		temp = scnprintf(next, size, "%4d: ", i);
@@ -569,7 +584,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 						continue;
 					if (p.qh->qh_next.ptr) {
 						temp = scnprintf(next, size,
-							" ...");
+								" ...");
 						size -= temp;
 						next += temp;
 					}
@@ -577,38 +592,9 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				}
 				/* show more info the first time around */
 				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fotg210,
-							&hw->hw_info1);
-					struct fotg210_qtd	*qtd;
-					char		*type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry(qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fotg210,
-							qtd->hw_token) >> 8)) {
-						case 0:
-							type = "out";
-							continue;
-						case 1:
-							type = "in";
-							continue;
-						}
-					}
-
-					temp = scnprintf(next, size,
-						"(%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
-						speed_char(scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
+					temp = output_buf_tds_dir(next,
+							fotg210, hw,
+							p.qh, size);
 
 					if (seen_count < DBG_SCHED_LIMIT)
 						seen[seen_count++].qh = p.qh;
@@ -619,14 +605,14 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				break;
 			case Q_TYPE_FSTN:
 				temp = scnprintf(next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
+						" fstn-%8x/%p",
+						p.fstn->hw_prev, p.fstn);
 				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
 				p = p.fstn->fstn_next;
 				break;
 			case Q_TYPE_ITD:
 				temp = scnprintf(next, size,
-					" itd/%p", p.itd);
+						" itd/%p", p.itd);
 				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
 				p = p.itd->itd_next;
 				break;
@@ -663,13 +649,13 @@ static const char *rh_state_string(struct fotg210_hcd *fotg210)
 
 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch[80];
-	static const char	fmt[] = "%*s\n";
-	static const char	label[] = "";
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size, i;
+	char *next, scratch[80];
+	static const char fmt[] = "%*s\n";
+	static const char label[] = "";
 
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -680,26 +666,26 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 		size = scnprintf(next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED(no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
+				"bus %s, device %s\n"
+				"%s\n"
+				"SUSPENDED(no register access)\n",
+				hcd->self.controller->bus->name,
+				dev_name(hcd->self.controller),
+				hcd->product_desc);
 		goto done;
 	}
 
 	/* Capability Registers */
 	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-					      &fotg210->caps->hc_capbase));
+			&fotg210->caps->hc_capbase));
 	temp = scnprintf(next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fotg210));
+			"bus %s, device %s\n"
+			"%s\n"
+			"EHCI %x.%02x, rh state %s\n",
+			hcd->self.controller->bus->name,
+			dev_name(hcd->self.controller),
+			hcd->product_desc,
+			i >> 8, i & 0x0ff, rh_state_string(fotg210));
 	size -= temp;
 	next += temp;
 
@@ -747,14 +733,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 #ifdef FOTG210_STATS
 	temp = scnprintf(next, size,
-		"irq normal %ld err %ld iaa %ld(lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+			"irq normal %ld err %ld iaa %ld(lost %ld)\n",
+			fotg210->stats.normal, fotg210->stats.error,
+			fotg210->stats.iaa, fotg210->stats.lost_iaa);
 	size -= temp;
 	next += temp;
 
 	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+			fotg210->stats.complete, fotg210->stats.unlink);
 	size -= temp;
 	next += temp;
 #endif
@@ -765,8 +751,8 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 	return buf->alloc_size - size;
 }
 
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
+static struct debug_buffer
+*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
 {
 	struct debug_buffer *buf;
 
@@ -806,7 +792,7 @@ static int fill_buffer(struct debug_buffer *buf)
 }
 
 static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
+		size_t len, loff_t *offset)
 {
 	struct debug_buffer *buf = file->private_data;
 	int ret = 0;
@@ -822,7 +808,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
 	mutex_unlock(&buf->mutex);
 
 	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
+			buf->output_buf, buf->count);
 
 out:
 	return ret;
@@ -850,6 +836,7 @@ static int debug_async_open(struct inode *inode, struct file *file)
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
 	struct debug_buffer *buf;
+
 	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
 	if (!buf)
 		return -ENOMEM;
@@ -862,7 +849,7 @@ static int debug_periodic_open(struct inode *inode, struct file *file)
 static int debug_registers_open(struct inode *inode, struct file *file)
 {
 	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
+			fill_registers_buffer);
 
 	return file->private_data ? 0 : -ENOMEM;
 }
@@ -872,20 +859,20 @@ static inline void create_debug_files(struct fotg210_hcd *fotg210)
 	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
 
 	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
-						fotg210_debug_root);
+			fotg210_debug_root);
 	if (!fotg210->debug_dir)
 		return;
 
 	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_async_fops))
+			&debug_async_fops))
 		goto file_error;
 
 	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_periodic_fops))
+			&debug_periodic_fops))
 		goto file_error;
 
 	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
-						    &debug_registers_fops))
+			&debug_registers_fops))
 		goto file_error;
 
 	return;
@@ -899,10 +886,7 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
 	debugfs_remove_recursive(fotg210->debug_dir);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * handshake - spin reading hc until handshake completes or fails
+/* handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
  * @mask: bits to look at in result of read
  * @done: value of those bits when handshake succeeds
@@ -919,9 +903,9 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
 static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
+		u32 mask, u32 done, int usec)
 {
-	u32	result;
+	u32 result;
 
 	do {
 		result = fotg210_readl(fotg210, ptr);
@@ -936,13 +920,12 @@ static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
 	return -ETIMEDOUT;
 }
 
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
+/* Force HC to halt state from unknown (EHCI spec section 2.3).
  * Must be called with interrupts enabled and the lock not held.
  */
 static int fotg210_halt(struct fotg210_hcd *fotg210)
 {
-	u32	temp;
+	u32 temp;
 
 	spin_lock_irq(&fotg210->lock);
 
@@ -962,20 +945,20 @@ static int fotg210_halt(struct fotg210_hcd *fotg210)
 	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
 
 	return handshake(fotg210, &fotg210->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
+			STS_HALT, STS_HALT, 16 * 125);
 }
 
-/*
- * Reset a non-running (STS_HALT == 1) controller.
+/* Reset a non-running (STS_HALT == 1) controller.
  * Must be called with interrupts enabled and the lock not held.
  */
 static int fotg210_reset(struct fotg210_hcd *fotg210)
 {
-	int	retval;
-	u32	command = fotg210_readl(fotg210, &fotg210->regs->command);
+	int retval;
+	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
 
 	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
+	 * taken before and after a host controller reset
+	 */
 	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
 		fotg210->debug = NULL;
 
@@ -985,7 +968,7 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
 	fotg210->rh_state = FOTG210_RH_HALTED;
 	fotg210->next_statechange = jiffies;
 	retval = handshake(fotg210, &fotg210->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
+			CMD_RESET, 0, 250 * 1000);
 
 	if (retval)
 		return retval;
@@ -998,13 +981,12 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
 	return retval;
 }
 
-/*
- * Idle the controller (turn off the schedules).
+/* Idle the controller (turn off the schedules).
  * Must be called with interrupts enabled and the lock not held.
  */
 static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 {
-	u32	temp;
+	u32 temp;
 
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 		return;
@@ -1012,7 +994,7 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 	/* wait for any schedule enables/disables to take effect */
 	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
-		  16 * 125);
+			16 * 125);
 
 	/* then disable anything that's still active */
 	spin_lock_irq(&fotg210->lock);
@@ -1022,11 +1004,9 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 
 	/* hardware can take 16 microframes to turn off ... */
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
-		  16 * 125);
+			16 * 125);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void end_unlink_async(struct fotg210_hcd *fotg210);
 static void unlink_empty_async(struct fotg210_hcd *fotg210);
 static void fotg210_work(struct fotg210_hcd *fotg210);
@@ -1034,8 +1014,6 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 			      struct fotg210_qh *qh);
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
-/*-------------------------------------------------------------------------*/
-
 /* Set a bit in the USBCMD register */
 static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 {
@@ -1056,10 +1034,7 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 	fotg210_readl(fotg210, &fotg210->regs->command);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI timer support...  Now using hrtimers.
+/* EHCI timer support...  Now using hrtimers.
  *
  * Lots of different events are triggered from fotg210->hrtimer.  Whenever
  * the timer routine runs, it checks each possible event; events that are
@@ -1081,8 +1056,7 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
  * allow for an expiration range of 1 ms.
  */
 
-/*
- * Delay lengths for the hrtimer event types.
+/* Delay lengths for the hrtimer event types.
  * Keep this list sorted by delay length, in the same order as
  * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
  */
@@ -1103,7 +1077,7 @@ static unsigned event_delays_ns[] = {
 static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 		bool resched)
 {
-	ktime_t		*timeout = &fotg210->hr_timeouts[event];
+	ktime_t *timeout = &fotg210->hr_timeouts[event];
 
 	if (resched)
 		*timeout = ktime_add(ktime_get(),
@@ -1122,7 +1096,7 @@ static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
 static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 	/* Don't enable anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1136,7 +1110,7 @@ static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 		/* Poll again later, but give up after about 20 ms */
 		if (fotg210->ASS_poll_count++ < 20) {
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
-					     true);
+					true);
 			return;
 		}
 		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
@@ -1154,8 +1128,8 @@ static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 
 			/* Turn off the schedule after a while */
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_ASYNC,
-					     true);
+					FOTG210_HRTIMER_DISABLE_ASYNC,
+					true);
 		}
 	}
 }
@@ -1170,7 +1144,7 @@ static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
 /* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
 static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 	/* Don't do anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1184,7 +1158,7 @@ static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 		/* Poll again later, but give up after about 20 ms */
 		if (fotg210->PSS_poll_count++ < 20) {
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
-					     true);
+					true);
 			return;
 		}
 		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
@@ -1202,8 +1176,8 @@ static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 
 			/* Turn off the schedule after a while */
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_PERIODIC,
-					     true);
+					FOTG210_HRTIMER_DISABLE_PERIODIC,
+					true);
 		}
 	}
 }
@@ -1224,7 +1198,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 		if (fotg210->died_poll_count++ < 5) {
 			/* Try again later */
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_POLL_DEAD, true);
+					FOTG210_HRTIMER_POLL_DEAD, true);
 			return;
 		}
 		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
@@ -1243,7 +1217,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
 static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 {
-	bool		stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
 
 	/*
 	 * Process all the QHs on the intr_unlink list that were added
@@ -1254,7 +1228,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	 */
 	fotg210->intr_unlinking = true;
 	while (fotg210->intr_unlink) {
-		struct fotg210_qh	*qh = fotg210->intr_unlink;
+		struct fotg210_qh *qh = fotg210->intr_unlink;
 
 		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
 			break;
@@ -1266,7 +1240,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	/* Handle remaining entries later */
 	if (fotg210->intr_unlink) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
+				true);
 		++fotg210->intr_unlink_cycle;
 	}
 	fotg210->intr_unlinking = false;
@@ -1288,7 +1262,7 @@ static void start_free_itds(struct fotg210_hcd *fotg210)
 /* Wait for controller to stop using old iTDs and siTDs */
 static void end_free_itds(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_itd		*itd, *n;
+	struct fotg210_itd *itd, *n;
 
 	if (fotg210->rh_state < FOTG210_RH_RUNNING)
 		fotg210->last_itd_to_free = NULL;
@@ -1339,7 +1313,7 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
 		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
 			COUNT(fotg210->stats.lost_iaa);
 			fotg210_writel(fotg210, STS_IAA,
-				       &fotg210->regs->status);
+					&fotg210->regs->status);
 		}
 
 		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
@@ -1355,7 +1329,7 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 	/* Not needed if the controller isn't running or it's already enabled */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
 			(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
+			BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
 		return;
 
 	/*
@@ -1365,12 +1339,11 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
 			fotg210->async_count + fotg210->intr_count > 0))
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
-				     true);
+				true);
 }
 
 
-/*
- * Handler functions for the hrtimer event types.
+/* Handler functions for the hrtimer event types.
  * Keep this array in the same order as the event types indexed by
  * enum fotg210_hrtimer_event in fotg210.h.
  */
@@ -1391,10 +1364,10 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 {
 	struct fotg210_hcd *fotg210 =
 			container_of(t, struct fotg210_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
+	ktime_t now;
+	unsigned long events;
+	unsigned long flags;
+	unsigned e;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 
@@ -1418,50 +1391,37 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 	return HRTIMER_NORESTART;
 }
 
-/*-------------------------------------------------------------------------*/
-
-#define fotg210_bus_suspend	NULL
-#define fotg210_bus_resume	NULL
+#define fotg210_bus_suspend NULL
+#define fotg210_bus_resume NULL
 
-/*-------------------------------------------------------------------------*/
-
-static int check_reset_complete(
-	struct fotg210_hcd	*fotg210,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
+static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
+		u32 __iomem *status_reg, int port_status)
+{
 	if (!(port_status & PORT_CONNECT))
 		return port_status;
 
 	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
+	if (!(port_status & PORT_PE))
 		/* with integrated TT, there's nobody to hand it to! */
-		fotg210_dbg(fotg210,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
-		return port_status;
-	} else {
+		fotg210_dbg(fotg210, "Failed to enable port %d on root hub TT\n",
+				index + 1);
+	else
 		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-			index + 1);
-	}
+				index + 1);
 
 	return port_status;
 }
 
-/*-------------------------------------------------------------------------*/
-
 
 /* build "status change" packet (one or two bytes) from HC registers */
 
-static int
-fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
+static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp, status;
+	u32 mask;
+	int retval = 1;
+	unsigned long flags;
 
 	/* init status to no-changes */
 	buf[0] = 0;
@@ -1488,9 +1448,9 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	 * controller by the user.
 	 */
 
-	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend)
-			|| (fotg210->reset_done[0] && time_after_eq(
-				jiffies, fotg210->reset_done[0]))) {
+	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend) ||
+			(fotg210->reset_done[0] &&
+			time_after_eq(jiffies, fotg210->reset_done[0]))) {
 		buf[0] |= 1 << 1;
 		status = STS_PCD;
 	}
@@ -1499,15 +1459,11 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	return status ? retval : 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static void
-fotg210_hub_descriptor(
-	struct fotg210_hcd		*fotg210,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u16		temp;
+static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
+		struct usb_hub_descriptor *desc)
+{
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u16 temp;
 
 	desc->bDescriptorType = USB_DT_HUB;
 	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
@@ -1526,23 +1482,16 @@ fotg210_hub_descriptor(
 	desc->wHubCharacteristics = cpu_to_le16(temp);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int fotg210_hub_control(
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u32 __iomem	*status_reg = &fotg210->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
+static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+		u16 wIndex, char *buf, u16 wLength)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	u32 temp, temp1, status;
+	unsigned long flags;
+	int retval = 0;
+	unsigned selector;
 
 	/*
 	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -1605,7 +1554,7 @@ static int fotg210_hub_control(
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
 			fotg210_writel(fotg210, temp | OTGISR_OVC,
-				       &fotg210->regs->otgisr);
+					&fotg210->regs->otgisr);
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
@@ -1617,7 +1566,7 @@ static int fotg210_hub_control(
 		break;
 	case GetHubDescriptor:
 		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
-			buf);
+				buf);
 		break;
 	case GetHubStatus:
 		/* no hub-wide feature/status flags */
@@ -1663,16 +1612,16 @@ static int fotg210_hub_control(
 
 				/* stop resume signaling */
 				temp = fotg210_readl(fotg210, status_reg);
-				fotg210_writel(fotg210,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
+				fotg210_writel(fotg210, temp &
+						~(PORT_RWC_BITS | PORT_RESUME),
+						status_reg);
 				clear_bit(wIndex, &fotg210->resuming_ports);
 				retval = handshake(fotg210, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
+						PORT_RESUME, 0, 2000);/* 2ms */
 				if (retval != 0) {
 					fotg210_err(fotg210,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
+							"port %d resume error %d\n",
+							wIndex + 1, retval);
 					goto error;
 				}
 				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
@@ -1680,17 +1629,16 @@ static int fotg210_hub_control(
 		}
 
 		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
+		if ((temp & PORT_RESET) && time_after_eq(jiffies,
+				fotg210->reset_done[wIndex])) {
 			status |= USB_PORT_STAT_C_RESET << 16;
 			fotg210->reset_done[wIndex] = 0;
 			clear_bit(wIndex, &fotg210->resuming_ports);
 
 			/* force reset to complete */
 			fotg210_writel(fotg210,
-				       temp & ~(PORT_RWC_BITS | PORT_RESET),
-				       status_reg);
+					temp & ~(PORT_RWC_BITS | PORT_RESET),
+					status_reg);
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			 * this bit; seems too long to spin routinely...
 			 */
@@ -1698,7 +1646,7 @@ static int fotg210_hub_control(
 					PORT_RESET, 0, 1000);
 			if (retval != 0) {
 				fotg210_err(fotg210, "port %d reset error %d\n",
-					wIndex + 1, retval);
+						wIndex + 1, retval);
 				goto error;
 			}
 
@@ -1718,7 +1666,7 @@ static int fotg210_hub_control(
 			temp &= ~PORT_RWC_BITS;
 			fotg210_writel(fotg210, temp, status_reg);
 			fotg210_dbg(fotg210, "port %d --> companion\n",
-				    wIndex + 1);
+					wIndex + 1);
 			temp = fotg210_readl(fotg210, status_reg);
 		}
 
@@ -1788,7 +1736,7 @@ static int fotg210_hub_control(
 			 * mode if we have hostpc feature
 			 */
 			fotg210_writel(fotg210, temp | PORT_SUSPEND,
-				       status_reg);
+					status_reg);
 			set_bit(wIndex, &fotg210->suspended_ports);
 			break;
 		case USB_PORT_FEAT_RESET:
@@ -1866,9 +1814,8 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
 {
 	return 0;
 }
-/*-------------------------------------------------------------------------*/
-/*
- * There's basically three types of memory:
+
+/* There's basically three types of memory:
  *	- data used only by the HCD ... kmalloc is fine
  *	- async and periodic schedules, shared by HC and HCD ... these
  *	  need to use dma_pool or dma_alloc_coherent
@@ -1878,12 +1825,9 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
  * No memory seen by this driver is pageable.
  */
 
-/*-------------------------------------------------------------------------*/
-
 /* Allocate the key transfer structures from the previously allocated pool */
-
 static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd, dma_addr_t dma)
+		struct fotg210_qtd *qtd, dma_addr_t dma)
 {
 	memset(qtd, 0, sizeof(*qtd));
 	qtd->qtd_dma = dma;
@@ -1894,10 +1838,10 @@ static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
 }
 
 static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
-					     gfp_t flags)
+		gfp_t flags)
 {
-	struct fotg210_qtd		*qtd;
-	dma_addr_t		dma;
+	struct fotg210_qtd *qtd;
+	dma_addr_t dma;
 
 	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
 	if (qtd != NULL)
@@ -1907,7 +1851,7 @@ static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
 }
 
 static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd)
+		struct fotg210_qtd *qtd)
 {
 	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
 }
@@ -1927,10 +1871,10 @@ static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 }
 
 static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
-					   gfp_t flags)
+		gfp_t flags)
 {
-	struct fotg210_qh		*qh;
-	dma_addr_t		dma;
+	struct fotg210_qh *qh;
+	dma_addr_t dma;
 
 	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
 	if (!qh)
@@ -1958,8 +1902,6 @@ static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
 	return NULL;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* The queue heads and transfer descriptors are managed from pools tied
  * to each of the "per device" structures.
  * This is the initialisation and cleanup code.
@@ -1976,23 +1918,19 @@ static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
 	fotg210->dummy = NULL;
 
 	/* DMA consistent memory and pools */
-	if (fotg210->qtd_pool)
-		dma_pool_destroy(fotg210->qtd_pool);
+	dma_pool_destroy(fotg210->qtd_pool);
 	fotg210->qtd_pool = NULL;
 
-	if (fotg210->qh_pool) {
-		dma_pool_destroy(fotg210->qh_pool);
-		fotg210->qh_pool = NULL;
-	}
+	dma_pool_destroy(fotg210->qh_pool);
+	fotg210->qh_pool = NULL;
 
-	if (fotg210->itd_pool)
-		dma_pool_destroy(fotg210->itd_pool);
+	dma_pool_destroy(fotg210->itd_pool);
 	fotg210->itd_pool = NULL;
 
 	if (fotg210->periodic)
 		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(u32),
-			fotg210->periodic, fotg210->periodic_dma);
+				fotg210->periodic_size * sizeof(u32),
+				fotg210->periodic, fotg210->periodic_dma);
 	fotg210->periodic = NULL;
 
 	/* shadow periodic table */
@@ -2039,8 +1977,8 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 	/* Hardware periodic table */
 	fotg210->periodic = (__le32 *)
 		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(__le32),
-			&fotg210->periodic_dma, 0);
+				fotg210->periodic_size * sizeof(__le32),
+				&fotg210->periodic_dma, 0);
 	if (fotg210->periodic == NULL)
 		goto fail;
 
@@ -2049,7 +1987,7 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 
 	/* software shadow of hardware table */
 	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
-				   flags);
+			flags);
 	if (fotg210->pshadow != NULL)
 		return 0;
 
@@ -2058,9 +1996,7 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 	fotg210_mem_cleanup(fotg210);
 	return -ENOMEM;
 }
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
+/* EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
  *
  * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
  * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
@@ -2077,16 +2013,12 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
  * buffer low/full speed data so the host collects it at high speed.
  */
 
-/*-------------------------------------------------------------------------*/
-
 /* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
+static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
+		dma_addr_t buf, size_t len, int token, int maxpacket)
 {
-	int	i, count;
-	u64	addr = buf;
+	int i, count;
+	u64 addr = buf;
 
 	/* one buffer entry per 4K ... first might be short or unaligned */
 	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
@@ -2121,11 +2053,8 @@ qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
 	return count;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-	  struct fotg210_qtd *qtd)
+static inline void qh_update(struct fotg210_hcd *fotg210,
+		struct fotg210_qh *qh, struct fotg210_qtd *qtd)
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 
@@ -2141,7 +2070,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
 	 * ever clear it.
 	 */
 	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
+		unsigned is_out, epnum;
 
 		is_out = qh->is_out;
 		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
@@ -2158,8 +2087,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
  * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
  * recovery (including urb dequeue) would need software changes to a QH...
  */
-static void
-qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 	struct fotg210_qtd *qtd;
 
@@ -2185,16 +2113,14 @@ qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		qh_update(fotg210, qh, qtd);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
 static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 		struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh = ep->hcpriv;
+	unsigned long flags;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	qh->clearing_tt = 0;
@@ -2205,8 +2131,7 @@ static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 }
 
 static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-				    struct fotg210_qh *qh,
-				    struct urb *urb, u32 token)
+		struct fotg210_qh *qh, struct urb *urb, u32 token)
 {
 
 	/* If an async split transaction gets an error or is unlinked,
@@ -2217,27 +2142,24 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 	 */
 	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
 		struct usb_device *tt = urb->dev->tt->hub;
+
 		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
+				"clear tt buffer port %d, a%d ep%d t%08x\n",
+				urb->dev->ttport, urb->dev->devnum,
+				usb_pipeendpoint(urb->pipe), token);
 
 		if (urb->dev->tt->hub !=
-		    fotg210_to_hcd(fotg210)->self.root_hub) {
+				fotg210_to_hcd(fotg210)->self.root_hub) {
 			if (usb_hub_clear_tt_buffer(urb) == 0)
 				qh->clearing_tt = 1;
 		}
 	}
 }
 
-static int qtd_copy_status(
-	struct fotg210_hcd *fotg210,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
+static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
+		size_t length, u32 token)
 {
-	int	status = -EINPROGRESS;
+	int status = -EINPROGRESS;
 
 	/* count IN/OUT bytes, not SETUP (even short packets) */
 	if (likely(QTD_PID(token) != 2))
@@ -2274,32 +2196,32 @@ static int qtd_copy_status(
 		} else if (token & QTD_STS_XACT) {
 			/* timeout, bad CRC, wrong PID, etc */
 			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
+					urb->dev->devpath,
+					usb_pipeendpoint(urb->pipe),
+					usb_pipein(urb->pipe) ? "in" : "out");
 			status = -EPROTO;
 		} else {	/* unknown */
 			status = -EPROTO;
 		}
 
 		fotg210_dbg(fotg210,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice(urb->pipe),
-			usb_pipeendpoint(urb->pipe),
-			usb_pipein(urb->pipe) ? "in" : "out",
-			token, status);
+				"dev%d ep%d%s qtd token %08x --> status %d\n",
+				usb_pipedevice(urb->pipe),
+				usb_pipeendpoint(urb->pipe),
+				usb_pipein(urb->pipe) ? "in" : "out",
+				token, status);
 	}
 
 	return status;
 }
 
-static void
-fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb, int status)
+static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
+		int status)
 __releases(fotg210->lock)
 __acquires(fotg210->lock)
 {
 	if (likely(urb->hcpriv != NULL)) {
-		struct fotg210_qh	*qh = (struct fotg210_qh *) urb->hcpriv;
+		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
 		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
@@ -2320,12 +2242,12 @@ __acquires(fotg210->lock)
 
 #ifdef FOTG210_URB_TRACE
 	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
+			"%s %s urb %p ep%d%s status %d len %d/%d\n",
+			__func__, urb->dev->devpath, urb,
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			status,
+			urb->actual_length, urb->transfer_buffer_length);
 #endif
 
 	/* complete() can reenter this HCD */
@@ -2337,21 +2259,20 @@ __acquires(fotg210->lock)
 
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
+/* Process and free completed qtds for a qh, returning URBs to drivers.
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  */
-static unsigned
-qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static unsigned qh_completions(struct fotg210_hcd *fotg210,
+		struct fotg210_qh *qh)
 {
-	struct fotg210_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fotg210_qh_hw	*hw = qh->hw;
+	struct fotg210_qtd *last, *end = qh->dummy;
+	struct list_head *entry, *tmp;
+	int last_status;
+	int stopped;
+	unsigned count = 0;
+	u8 state;
+	struct fotg210_qh_hw *hw = qh->hw;
 
 	if (unlikely(list_empty(&qh->qtd_list)))
 		return count;
@@ -2370,7 +2291,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	qh->qh_state = QH_STATE_COMPLETING;
 	stopped = (state == QH_STATE_IDLE);
 
- rescan:
+rescan:
 	last = NULL;
 	last_status = -EINPROGRESS;
 	qh->needs_rescan = 0;
@@ -2381,9 +2302,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	 * if queue is stopped, handles unlinks.
 	 */
 	list_for_each_safe(entry, tmp, &qh->qtd_list) {
-		struct fotg210_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
+		struct fotg210_qtd *qtd;
+		struct urb *urb;
+		u32 token = 0;
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		urb = qtd->urb;
@@ -2392,7 +2313,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		if (last) {
 			if (likely(last->urb != urb)) {
 				fotg210_urb_done(fotg210, last->urb,
-						 last_status);
+						last_status);
 				count++;
 				last_status = -EINPROGRESS;
 			}
@@ -2409,20 +2330,17 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		token = hc32_to_cpu(fotg210, qtd->hw_token);
 
 		/* always clean up qtds the hc de-activated */
- retry_xacterr:
+retry_xacterr:
 		if ((token & QTD_STS_ACTIVE) == 0) {
 
 			/* Report Data Buffer Error: non-fatal but useful */
 			if (token & QTD_STS_DBE)
 				fotg210_dbg(fotg210,
 					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
+					urb, usb_endpoint_num(&urb->ep->desc),
 					usb_endpoint_dir_in(&urb->ep->desc)
 						? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
+					urb->transfer_buffer_length, qtd, qh);
 
 			/* on STALL, error, and short reads this urb must
 			 * complete and all its qtds must be recycled.
@@ -2433,12 +2351,14 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 * reach the software xacterr limit
 				 */
 				if ((token & QTD_STS_XACT) &&
-					QTD_CERR(token) == 0 &&
-					++qh->xacterrs < QH_XACTERR_MAX &&
-					!urb->unlinked) {
+						QTD_CERR(token) == 0 &&
+						++qh->xacterrs < QH_XACTERR_MAX &&
+						!urb->unlinked) {
 					fotg210_dbg(fotg210,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
+						"detected XactErr len %zu/%zu retry %d\n",
+						qtd->length - QTD_LENGTH(token),
+						qtd->length,
+						qh->xacterrs);
 
 					/* reset the token in the qtd and the
 					 * qh overlay (which still contains
@@ -2466,9 +2386,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 			 * URB_SHORT_NOT_OK was set so the driver submitting
 			 * the urbs could clean it up.
 			 */
-			} else if (IS_SHORT_READ(token)
-					&& !(qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210))) {
+			} else if (IS_SHORT_READ(token) &&
+					!(qtd->hw_alt_next &
+					FOTG210_LIST_END(fotg210))) {
 				stopped = 1;
 			}
 
@@ -2492,9 +2412,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				continue;
 
 			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fotg210, qtd->qtd_dma)
-						== hw->hw_current) {
+			if (state == QH_STATE_IDLE &&
+					cpu_to_hc32(fotg210, qtd->qtd_dma)
+					== hw->hw_current) {
 				token = hc32_to_cpu(fotg210, hw->hw_token);
 
 				/* An unlink may leave an incomplete
@@ -2502,7 +2422,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 * We have to clear it.
 				 */
 				fotg210_clear_tt_buffer(fotg210, qh, urb,
-							token);
+						token);
 			}
 		}
 
@@ -2516,9 +2436,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		if (last_status == -EINPROGRESS) {
 			last_status = qtd_copy_status(fotg210, urb,
 					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210)))
+			if (last_status == -EREMOTEIO &&
+					(qtd->hw_alt_next &
+					FOTG210_LIST_END(fotg210)))
 				last_status = -EINPROGRESS;
 
 			/* As part of low/full-speed endpoint-halt processing
@@ -2537,7 +2457,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 */
 				if (last_status != -EPIPE)
 					fotg210_clear_tt_buffer(fotg210, qh,
-								urb, token);
+							urb, token);
 			}
 		}
 
@@ -2615,26 +2535,21 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	return count;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 /* ... and packet size, for any kind of endpoint descriptor */
 #define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
 
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
+/* reverse of qh_urb_transaction:  free a list of TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
  */
-static void qtd_list_free(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
+static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list)
+{
+	struct list_head *entry, *temp;
 
 	list_for_each_safe(entry, temp, qtd_list) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		list_del(&qtd->qtd_list);
@@ -2642,23 +2557,18 @@ static void qtd_list_free(
 	}
 }
 
-/*
- * create a list of filled qtds for this URB; won't link into qh.
+/* create a list of filled qtds for this URB; won't link into qh.
  */
-static struct list_head *
-qh_urb_transaction(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fotg210_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
+static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
+		struct urb *urb, struct list_head *head, gfp_t flags)
+{
+	struct fotg210_qtd *qtd, *qtd_prev;
+	dma_addr_t buf;
+	int len, this_sg_len, maxpacket;
+	int is_input;
+	u32 token;
+	int i;
+	struct scatterlist *sg;
 
 	/*
 	 * URBs map to sequences of QTDs:  one logical transaction
@@ -2768,8 +2678,8 @@ qh_urb_transaction(
 	 * have the alt_next mechanism keep the queue running after the
 	 * last data qtd (the only one, for control and most other cases).
 	 */
-	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol(urb->pipe)))
+	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 ||
+			usb_pipecontrol(urb->pipe)))
 		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
 
 	/*
@@ -2778,7 +2688,7 @@ qh_urb_transaction(
 	 * (zero length).
 	 */
 	if (likely(urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
+		int one_more = 0;
 
 		if (usb_pipecontrol(urb->pipe)) {
 			one_more = 1;
@@ -2813,9 +2723,7 @@ qh_urb_transaction(
 	return NULL;
 }
 
-/*-------------------------------------------------------------------------*/
-/*
- * Would be best to create all qh's from config descriptors,
+/* Would be best to create all qh's from config descriptors,
  * when each interface/altsetting is established.  Unlink
  * any previous qh and cancel its urbs first; endpoints are
  * implicitly reset then (data toggle too).
@@ -2823,26 +2731,22 @@ qh_urb_transaction(
 */
 
 
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
+/* Each QH holds a qtd list; a QH is used for everything except iso.
  *
  * For interrupt urbs, the scheduler must set the microframe scheduling
  * mask(s) each time the QH gets scheduled.  For highspeed, that's
  * just one microframe in the s-mask.  For split interrupt transactions
  * there are additional complications: c-mask, maybe FSTNs.
  */
-static struct fotg210_qh *
-qh_make(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fotg210_qh		*qh = fotg210_qh_alloc(fotg210, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fotg210_qh_hw	*hw;
+static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
+		gfp_t flags)
+{
+	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
+	u32 info1 = 0, info2 = 0;
+	int is_input, type;
+	int maxp = 0;
+	struct usb_tt *tt = urb->dev->tt;
+	struct fotg210_qh_hw *hw;
 
 	if (!qh)
 		return qh;
@@ -2862,7 +2766,7 @@ qh_make(
 	 */
 	if (max_packet(maxp) > 1024) {
 		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
-			    max_packet(maxp));
+				max_packet(maxp));
 		goto done;
 	}
 
@@ -2896,7 +2800,7 @@ qh_make(
 				urb->interval = qh->period << 3;
 			}
 		} else {
-			int		think_time;
+			int think_time;
 
 			/* gap is f(FS/LS transfer times) */
 			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
@@ -2986,7 +2890,7 @@ qh_make(
 		break;
 	default:
 		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
+				urb->dev->speed);
 done:
 		qh_destroy(fotg210, qh);
 		return NULL;
@@ -3005,8 +2909,6 @@ qh_make(
 	return qh;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_async(struct fotg210_hcd *fotg210)
 {
 	if (fotg210->async_count++)
@@ -3036,8 +2938,8 @@ static void disable_async(struct fotg210_hcd *fotg210)
 
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	__hc32		dma = QH_NEXT(fotg210, qh->qh_dma);
-	struct fotg210_qh	*head;
+	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
+	struct fotg210_qh *head;
 
 	/* Don't link a QH if there's a Clear-TT-Buffer pending */
 	if (unlikely(qh->clearing_tt))
@@ -3064,24 +2966,17 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	enable_async(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
+/* For control/bulk/interrupt, return QH with these TDs appended.
  * Allocates and initializes the QH if necessary.
  * Returns null if it can't allocate a QH it needs to.
  * If the QH has TDs (urbs) already, that's great.
  */
-static struct fotg210_qh *qh_append_tds(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
+static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
+		struct urb *urb, struct list_head *qtd_list,
+		int epnum, void **ptr)
 {
-	struct fotg210_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
+	struct fotg210_qh *qh = NULL;
+	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
 
 	qh = (struct fotg210_qh *) *ptr;
 	if (unlikely(qh == NULL)) {
@@ -3090,7 +2985,7 @@ static struct fotg210_qh *qh_append_tds(
 		*ptr = qh;
 	}
 	if (likely(qh != NULL)) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 		if (unlikely(list_empty(qtd_list)))
 			qtd = NULL;
@@ -3109,9 +3004,9 @@ static struct fotg210_qh *qh_append_tds(
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
 		if (likely(qtd != NULL)) {
-			struct fotg210_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
+			struct fotg210_qtd *dummy;
+			dma_addr_t dma;
+			__hc32 token;
 
 			/* to avoid racing the HC, use the dummy td instead of
 			 * the first td of our list (becomes new dummy).  both
@@ -3150,32 +3045,28 @@ static struct fotg210_qh *qh_append_tds(
 	return qh;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh = NULL;
-	int			rc;
+static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list, gfp_t mem_flags)
+{
+	int epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh = NULL;
+	int rc;
 
 	epnum = urb->ep->desc.bEndpointAddress;
 
 #ifdef FOTG210_URB_TRACE
 	{
 		struct fotg210_qtd *qtd;
+
 		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
 		fotg210_dbg(fotg210,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
+				"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+				__func__, urb->dev->devpath, urb,
+				epnum & 0x0f, (epnum & USB_DIR_IN)
+					? "in" : "out",
+				urb->transfer_buffer_length,
+				qtd, urb->ep->hcpriv);
 	}
 #endif
 
@@ -3200,19 +3091,17 @@ submit_async(
 	 */
 	if (likely(qh->qh_state == QH_STATE_IDLE))
 		qh_link_async(fotg210, qh);
- done:
+done:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	if (unlikely(qh == NULL))
 		qtd_list_free(fotg210, urb, qtd_list);
 	return rc;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void single_unlink_async(struct fotg210_hcd *fotg210,
-				struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
-	struct fotg210_qh		*prev;
+	struct fotg210_qh *prev;
 
 	/* Add to the end of the list of QHs waiting for the next IAAD */
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3260,7 +3149,7 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 				&fotg210->regs->command);
 		fotg210_readl(fotg210, &fotg210->regs->command);
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
-				     true);
+				true);
 	}
 }
 
@@ -3268,10 +3157,10 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 
 static void end_unlink_async(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 	/* Process the idle QHs */
- restart:
+restart:
 	fotg210->async_unlinking = true;
 	while (fotg210->async_iaa) {
 		qh = fotg210->async_iaa;
@@ -3326,7 +3215,7 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 	/* QHs that haven't been empty for long enough will be handled later */
 	if (check_unlinks_later) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
-				     true);
+				true);
 		++fotg210->async_unlink_cycle;
 	}
 }
@@ -3335,7 +3224,7 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 /* caller must own fotg210->lock */
 
 static void start_unlink_async(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 	/*
 	 * If the QH isn't linked then there's nothing we can do
@@ -3352,18 +3241,16 @@ static void start_unlink_async(struct fotg210_hcd *fotg210,
 	start_iaa_cycle(fotg210, false);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void scan_async(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
-	bool			check_unlinks_later = false;
+	struct fotg210_qh *qh;
+	bool check_unlinks_later = false;
 
 	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
 	while (fotg210->qh_scan_next) {
 		qh = fotg210->qh_scan_next;
 		fotg210->qh_scan_next = qh->qh_next.qh;
- rescan:
+rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
@@ -3395,15 +3282,13 @@ static void scan_async(struct fotg210_hcd *fotg210)
 	 */
 	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
 			!(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
+			BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
 		fotg210_enable_event(fotg210,
-				     FOTG210_HRTIMER_ASYNC_UNLINKS, true);
+				FOTG210_HRTIMER_ASYNC_UNLINKS, true);
 		++fotg210->async_unlink_cycle;
 	}
 }
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
+/* EHCI scheduled transaction support:  interrupt, iso, split iso
  * These are called "periodic" transactions in the EHCI spec.
  *
  * Note that for interrupt transfers, the QH/QTD manipulation is shared
@@ -3414,19 +3299,14 @@ static void scan_async(struct fotg210_hcd *fotg210)
  * It keeps track of every ITD (or SITD) that's linked, and holds enough
  * pre-calculated schedule data to make appending to the queue be quick.
  */
-
 static int fotg210_get_frame(struct usb_hcd *hcd);
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
+/* periodic_next_shadow - return "next" pointer on shadow list
  * @periodic: host pointer to qh/itd
  * @tag: hardware tag for type of this record
  */
-static union fotg210_shadow *
-periodic_next_shadow(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
+		union fotg210_shadow *periodic, __hc32 tag)
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	case Q_TYPE_QH:
@@ -3438,9 +3318,8 @@ periodic_next_shadow(struct fotg210_hcd *fotg210,
 	}
 }
 
-static __hc32 *
-shadow_next_periodic(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
+		union fotg210_shadow *periodic, __hc32 tag)
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	/* our fotg210_shadow.qh is actually software part */
@@ -3454,11 +3333,11 @@ shadow_next_periodic(struct fotg210_hcd *fotg210,
 
 /* caller must hold fotg210->lock */
 static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
-			    void *ptr)
+		void *ptr)
 {
-	union fotg210_shadow	*prev_p = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev_p;
+	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev_p;
 
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	while (here.ptr && here.ptr != ptr) {
@@ -3479,17 +3358,17 @@ static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 			Q_NEXT_TYPE(fotg210, *hw_p));
 
 	*hw_p = *shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
+			Q_NEXT_TYPE(fotg210, *hw_p));
 }
 
 /* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
+static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
+		unsigned frame, unsigned uframe)
 {
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	*q = &fotg210->pshadow[frame];
-	unsigned		usecs = 0;
-	struct fotg210_qh_hw	*hw;
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow *q = &fotg210->pshadow[frame];
+	unsigned usecs = 0;
+	struct fotg210_qh_hw *hw;
 
 	while (q->ptr) {
 		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
@@ -3526,12 +3405,10 @@ periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
 	}
 	if (usecs > fotg210->uframe_periodic_max)
 		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
+				frame * 8 + uframe, usecs);
 	return usecs;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
 {
 	if (!dev1->tt || !dev2->tt)
@@ -3548,13 +3425,8 @@ static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
  * for a periodic transfer starting at the specified frame, using
  * all the uframes in the mask.
  */
-static int tt_no_collision(
-	struct fotg210_hcd		*fotg210,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
+static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
+		struct usb_device *dev, unsigned frame, u32 uf_mask)
 {
 	if (period == 0)	/* error */
 		return 0;
@@ -3564,9 +3436,9 @@ static int tt_no_collision(
 	 * calling convention doesn't make that distinction.
 	 */
 	for (; frame < fotg210->periodic_size; frame += period) {
-		union fotg210_shadow	here;
-		__hc32			type;
-		struct fotg210_qh_hw	*hw;
+		union fotg210_shadow here;
+		__hc32 type;
+		struct fotg210_qh_hw *hw;
 
 		here = fotg210->pshadow[frame];
 		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
@@ -3579,7 +3451,7 @@ static int tt_no_collision(
 			case Q_TYPE_QH:
 				hw = here.qh->hw;
 				if (same_tt(dev, here.qh->dev)) {
-					u32		mask;
+					u32 mask;
 
 					mask = hc32_to_cpu(fotg210,
 							hw->hw_info2);
@@ -3594,8 +3466,8 @@ static int tt_no_collision(
 			/* case Q_TYPE_FSTN: */
 			default:
 				fotg210_dbg(fotg210,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
+						"periodic frame %d bogus type %d\n",
+						frame, type);
 			}
 
 			/* collision or error */
@@ -3607,8 +3479,6 @@ static int tt_no_collision(
 	return 1;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_periodic(struct fotg210_hcd *fotg210)
 {
 	if (fotg210->periodic_count++)
@@ -3632,8 +3502,6 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
 	fotg210_poll_PSS(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* periodic schedule slots have iso tds (normal or split) first, then a
  * sparse tree for active interrupt transfers.
  *
@@ -3642,24 +3510,24 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
  */
 static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	unsigned	i;
-	unsigned	period = qh->period;
+	unsigned i;
+	unsigned period = qh->period;
 
 	dev_dbg(&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fotg210, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
+			"link qh%d-%04x/%p start %d [%d/%d us]\n", period,
+			hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+			(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
+			qh->c_usecs);
 
 	/* high bandwidth, or otherwise every microframe */
 	if (period == 0)
 		period = 1;
 
 	for (i = qh->start; i < fotg210->periodic_size; i += period) {
-		union fotg210_shadow	*prev = &fotg210->pshadow[i];
-		__hc32			*hw_p = &fotg210->periodic[i];
-		union fotg210_shadow	here = *prev;
-		__hc32			type = 0;
+		union fotg210_shadow *prev = &fotg210->pshadow[i];
+		__hc32 *hw_p = &fotg210->periodic[i];
+		union fotg210_shadow here = *prev;
+		__hc32 type = 0;
 
 		/* skip the iso nodes at list head */
 		while (here.ptr) {
@@ -3707,10 +3575,10 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 }
 
 static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
-	unsigned	i;
-	unsigned	period;
+	unsigned i;
+	unsigned period;
 
 	/*
 	 * If qh is for a low/full-speed device, simply unlinking it
@@ -3741,10 +3609,10 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 		: (qh->usecs * 8);
 
 	dev_dbg(&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-		(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs);
+			"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+			qh->period, hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+			(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
+			qh->c_usecs);
 
 	/* qh->qh_next still "live" to HC */
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3757,7 +3625,7 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 }
 
 static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 	/* If the QH isn't linked then there's nothing we can do
 	 * unless we were called during a giveback, in which case
@@ -3794,15 +3662,15 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 		fotg210_handle_intr_unlinks(fotg210);
 	else if (fotg210->intr_unlink == qh) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
+				true);
 		++fotg210->intr_unlink_cycle;
 	}
 }
 
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	struct fotg210_qh_hw	*hw = qh->hw;
-	int			rc;
+	struct fotg210_qh_hw *hw = qh->hw;
+	int rc;
 
 	qh->qh_state = QH_STATE_IDLE;
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3811,7 +3679,7 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 
 	/* reschedule QH iff another request is queued */
 	if (!list_empty(&qh->qtd_list) &&
-	    fotg210->rh_state == FOTG210_RH_RUNNING) {
+			fotg210->rh_state == FOTG210_RH_RUNNING) {
 		rc = qh_schedule(fotg210, qh);
 
 		/* An error here likely indicates handshake failure
@@ -3830,16 +3698,10 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	disable_periodic(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int check_period(
-	struct fotg210_hcd *fotg210,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
+static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned uframe, unsigned period, unsigned usecs)
+{
+	int claimed;
 
 	/* complete split running into next frame?
 	 * given FSTN support, we could sometimes check...
@@ -3857,7 +3719,7 @@ static int check_period(
 		do {
 			for (uframe = 0; uframe < 7; uframe++) {
 				claimed = periodic_usecs(fotg210, frame,
-							 uframe);
+						uframe);
 				if (claimed > usecs)
 					return 0;
 			}
@@ -3876,16 +3738,11 @@ static int check_period(
 	return 1;
 }
 
-static int check_intr_schedule(
-	struct fotg210_hcd		*fotg210,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fotg210_qh	*qh,
-	__hc32			*c_maskp
-)
+static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned uframe, const struct fotg210_qh *qh, __hc32 *c_maskp)
 {
-	int		retval = -ENOSPC;
-	u8		mask = 0;
+	int retval = -ENOSPC;
+	u8 mask = 0;
 
 	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
 		goto done;
@@ -3911,10 +3768,10 @@ static int check_intr_schedule(
 	mask |= 1 << uframe;
 	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
+				qh->period, qh->c_usecs))
 			goto done;
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
+				qh->period, qh->c_usecs))
 			goto done;
 		retval = 0;
 	}
@@ -3927,11 +3784,11 @@ static int check_intr_schedule(
  */
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fotg210_qh_hw	*hw = qh->hw;
+	int status;
+	unsigned uframe;
+	__hc32 c_mask;
+	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
+	struct fotg210_qh_hw *hw = qh->hw;
 
 	qh_refresh(fotg210, qh);
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3954,7 +3811,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	if (status) {
 		/* "normal" case, uframing flexible except with splits */
 		if (qh->period) {
-			int		i;
+			int i;
 
 			for (i = qh->period; status && i > 0; --i) {
 				frame = ++fotg210->random_frame % qh->period;
@@ -3971,7 +3828,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		} else {
 			frame = 0;
 			status = check_intr_schedule(fotg210, 0, 0, qh,
-						     &c_mask);
+					&c_mask);
 		}
 		if (status)
 			goto done;
@@ -3992,17 +3849,14 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	return status;
 }
 
-static int intr_submit(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh;
-	int			status;
-	struct list_head	empty;
+static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list, gfp_t mem_flags)
+{
+	unsigned epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh;
+	int status;
+	struct list_head empty;
 
 	/* get endpoint and transfer/schedule data */
 	epnum = urb->ep->desc.bEndpointAddress;
@@ -4050,11 +3904,11 @@ static int intr_submit(
 
 static void scan_intr(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-				 &fotg210->intr_qh_list, intr_node) {
- rescan:
+			&fotg210->intr_qh_list, intr_node) {
+rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
@@ -4069,7 +3923,7 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 			temp = qh_completions(fotg210, qh);
 			if (unlikely(qh->needs_rescan ||
 					(list_empty(&qh->qtd_list) &&
-					 qh->qh_state == QH_STATE_LINKED)))
+					qh->qh_state == QH_STATE_LINKED)))
 				start_unlink_intr(fotg210, qh);
 			else if (temp != 0)
 				goto rescan;
@@ -4077,12 +3931,9 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 	}
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_stream ops work with both ITD and SITD */
 
-static struct fotg210_iso_stream *
-iso_stream_alloc(gfp_t mem_flags)
+static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
 {
 	struct fotg210_iso_stream *stream;
 
@@ -4095,20 +3946,15 @@ iso_stream_alloc(gfp_t mem_flags)
 	return stream;
 }
 
-static void
-iso_stream_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
+static void iso_stream_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_stream *stream, struct usb_device *dev,
+		int pipe, unsigned interval)
 {
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned		multi;
+	u32 buf1;
+	unsigned epnum, maxp;
+	int is_input;
+	long bandwidth;
+	unsigned multi;
 
 	/*
 	 * this might be a "high bandwidth" highspeed endpoint,
@@ -4153,13 +3999,13 @@ iso_stream_init(
 	stream->maxp = maxp;
 }
 
-static struct fotg210_iso_stream *
-iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
+static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
+		struct urb *urb)
 {
-	unsigned		epnum;
-	struct fotg210_iso_stream	*stream;
+	unsigned epnum;
+	struct fotg210_iso_stream *stream;
 	struct usb_host_endpoint *ep;
-	unsigned long		flags;
+	unsigned long flags;
 
 	epnum = usb_pipeendpoint(urb->pipe);
 	if (usb_pipein(urb->pipe))
@@ -4182,8 +4028,8 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	/* if dev->ep[epnum] is a QH, hw is set */
 	} else if (unlikely(stream->hw != NULL)) {
 		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
+				urb->dev->devpath, epnum,
+				usb_pipein(urb->pipe) ? "in" : "out");
 		stream = NULL;
 	}
 
@@ -4191,15 +4037,13 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	return stream;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_sched ops can be ITD-only or SITD-only */
 
-static struct fotg210_iso_sched *
-iso_sched_alloc(unsigned packets, gfp_t mem_flags)
+static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
+		gfp_t mem_flags)
 {
-	struct fotg210_iso_sched	*iso_sched;
-	int			size = sizeof(*iso_sched);
+	struct fotg210_iso_sched *iso_sched;
+	int size = sizeof(*iso_sched);
 
 	size += packets * sizeof(struct fotg210_iso_packet);
 	iso_sched = kzalloc(size, mem_flags);
@@ -4209,16 +4053,12 @@ iso_sched_alloc(unsigned packets, gfp_t mem_flags)
 	return iso_sched;
 }
 
-static inline void
-itd_sched_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_sched	*iso_sched,
-	struct fotg210_iso_stream	*stream,
-	struct urb		*urb
-)
+static inline void itd_sched_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_sched *iso_sched,
+		struct fotg210_iso_stream *stream, struct urb *urb)
 {
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
+	unsigned i;
+	dma_addr_t dma = urb->transfer_dma;
 
 	/* how many uframes are needed for these transfers */
 	iso_sched->span = urb->number_of_packets * stream->interval;
@@ -4227,10 +4067,10 @@ itd_sched_init(
 	 * when we fit new itds into the schedule.
 	 */
 	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fotg210_iso_packet	*uframe = &iso_sched->packet[i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
+		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
+		unsigned length;
+		dma_addr_t buf;
+		u32 trans;
 
 		length = urb->iso_frame_desc[i].length;
 		buf = dma + urb->iso_frame_desc[i].offset;
@@ -4251,11 +4091,8 @@ itd_sched_init(
 	}
 }
 
-static void
-iso_sched_free(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_iso_sched	*iso_sched
-)
+static void iso_sched_free(struct fotg210_iso_stream *stream,
+		struct fotg210_iso_sched *iso_sched)
 {
 	if (!iso_sched)
 		return;
@@ -4264,20 +4101,15 @@ iso_sched_free(
 	kfree(iso_sched);
 }
 
-static int
-itd_urb_transaction(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
+static int itd_urb_transaction(struct fotg210_iso_stream *stream,
+		struct fotg210_hcd *fotg210, struct urb *urb, gfp_t mem_flags)
 {
-	struct fotg210_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fotg210_iso_sched	*sched;
-	unsigned long		flags;
+	struct fotg210_itd *itd;
+	dma_addr_t itd_dma;
+	int i;
+	unsigned num_itds;
+	struct fotg210_iso_sched *sched;
+	unsigned long flags;
 
 	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
 	if (unlikely(sched == NULL))
@@ -4306,7 +4138,7 @@ itd_urb_transaction(
 			list_del(&itd->itd_list);
 			itd_dma = itd->itd_dma;
 		} else {
- alloc_itd:
+alloc_itd:
 			spin_unlock_irqrestore(&fotg210->lock, flags);
 			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
 					&itd_dma);
@@ -4330,16 +4162,8 @@ itd_urb_transaction(
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok(
-	struct fotg210_hcd		*fotg210,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
+static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
+		u8 usecs, u32 period)
 {
 	uframe %= period;
 	do {
@@ -4354,8 +4178,7 @@ itd_slot_ok(
 	return 1;
 }
 
-/*
- * This scheduler plans almost as far into the future as it has actual
+/* This scheduler plans almost as far into the future as it has actual
  * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
  * "as small as possible" to be cache-friendlier.)  That limits the size
  * transfers you can stream reliably; avoid more than 64 msec per urb.
@@ -4365,19 +4188,15 @@ itd_slot_ok(
  * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
 
-#define SCHEDULE_SLOP	80	/* microframes */
+#define SCHEDULE_SLOP 80 /* microframes */
 
-static int
-iso_stream_schedule(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct fotg210_iso_stream	*stream
-)
+static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct fotg210_iso_stream *stream)
 {
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fotg210->periodic_size << 3;
-	struct fotg210_iso_sched	*sched = urb->hcpriv;
+	u32 now, next, start, period, span;
+	int status;
+	unsigned mod = fotg210->periodic_size << 3;
+	struct fotg210_iso_sched *sched = urb->hcpriv;
 
 	period = urb->interval;
 	span = sched->span;
@@ -4396,7 +4215,7 @@ iso_stream_schedule(
 	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 */
 	if (likely(!list_empty(&stream->td_list))) {
-		u32	excess;
+		u32 excess;
 
 		/* For high speed devices, allow scheduling within the
 		 * isochronous scheduling threshold.  For full speed devices
@@ -4435,6 +4254,7 @@ iso_stream_schedule(
 	 */
 	else {
 		int done = 0;
+
 		start = SCHEDULE_SLOP + (now & ~0x07);
 
 		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
@@ -4457,15 +4277,15 @@ iso_stream_schedule(
 		/* no room in the schedule */
 		if (!done) {
 			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
+					urb, now, now + mod);
 			status = -ENOSPC;
 			goto fail;
 		}
 	}
 
 	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
+	if (unlikely(start - now + span - period >=
+			mod - 2 * SCHEDULE_SLOP)) {
 		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
 				urb, start - now, span - period,
 				mod - 2 * SCHEDULE_SLOP);
@@ -4485,17 +4305,14 @@ iso_stream_schedule(
 		fotg210->next_frame = now >> 3;
 	return 0;
 
- fail:
+fail:
 	iso_sched_free(stream, sched);
 	urb->hcpriv = NULL;
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
-		struct fotg210_itd *itd)
+static inline void itd_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_stream *stream, struct fotg210_itd *itd)
 {
 	int i;
 
@@ -4511,17 +4328,12 @@ itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
 	/* All other fields are filled when scheduling */
 }
 
-static inline void
-itd_patch(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_itd		*itd,
-	struct fotg210_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
+static inline void itd_patch(struct fotg210_hcd *fotg210,
+		struct fotg210_itd *itd, struct fotg210_iso_sched *iso_sched,
+		unsigned index, u16 uframe)
 {
-	struct fotg210_iso_packet	*uf = &iso_sched->packet[index];
-	unsigned		pg = itd->pg;
+	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
+	unsigned pg = itd->pg;
 
 	uframe &= 0x07;
 	itd->index[uframe] = index;
@@ -4533,7 +4345,7 @@ itd_patch(
 
 	/* iso_frame_desc[].offset must be strictly increasing */
 	if (unlikely(uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
+		u64 bufp = uf->bufp + 4096;
 
 		itd->pg = ++pg;
 		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
@@ -4541,13 +4353,13 @@ itd_patch(
 	}
 }
 
-static inline void
-itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
+static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
+		struct fotg210_itd *itd)
 {
-	union fotg210_shadow	*prev = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev;
-	__hc32			type = 0;
+	union fotg210_shadow *prev = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev;
+	__hc32 type = 0;
 
 	/* skip any iso nodes which might belong to previous microframes */
 	while (here.ptr) {
@@ -4568,17 +4380,13 @@ itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fotg210_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fotg210_iso_sched	*iso_sched = urb->hcpriv;
-	struct fotg210_itd		*itd;
+static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
+		unsigned mod, struct fotg210_iso_stream *stream)
+{
+	int packet;
+	unsigned next_uframe, uframe, frame;
+	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
+	struct fotg210_itd *itd;
 
 	next_uframe = stream->next_uframe & (mod - 1);
 
@@ -4621,7 +4429,7 @@ static void itd_link_urb(
 		if (((next_uframe >> 3) != frame)
 				|| packet == urb->number_of_packets) {
 			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
-				 itd);
+					itd);
 			itd = NULL;
 		}
 	}
@@ -4635,8 +4443,8 @@ static void itd_link_urb(
 	enable_periodic(fotg210);
 }
 
-#define	ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-		  FOTG210_ISOC_XACTERR)
+#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
+		FOTG210_ISOC_XACTERR)
 
 /* Process and recycle a completed ITD.  Return true iff its urb completed,
  * and hence its completion callback probably added things to the hardware
@@ -4650,14 +4458,14 @@ static void itd_link_urb(
  */
 static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fotg210_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
+	struct urb *urb = itd->urb;
+	struct usb_iso_packet_descriptor *desc;
+	u32 t;
+	unsigned uframe;
+	int urb_index = -1;
+	struct fotg210_iso_stream *stream = itd->stream;
+	struct usb_device *dev;
+	bool retval = false;
 
 	/* for each uframe with a packet */
 	for (uframe = 0; uframe < 8; uframe++) {
@@ -4702,8 +4510,8 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 		goto done;
 
 	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
+	 * list_for_each_entry (itd, &stream->td_list, itd_list)
+	 *	BUG_ON (itd->urb == urb);
 	 */
 
 	/* give urb back to the driver; completion often (re)submits */
@@ -4740,14 +4548,12 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 	return retval;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-	gfp_t mem_flags)
+		gfp_t mem_flags)
 {
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fotg210_iso_stream	*stream;
+	int status = -EINVAL;
+	unsigned long flags;
+	struct fotg210_iso_stream *stream;
 
 	/* Get iso_stream head */
 	stream = iso_stream_find(fotg210, urb);
@@ -4756,22 +4562,22 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		return -ENOMEM;
 	}
 	if (unlikely(urb->interval != stream->interval &&
-		      fotg210_port_speed(fotg210, 0) ==
-				USB_PORT_STAT_HIGH_SPEED)) {
-			fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
+			fotg210_port_speed(fotg210, 0) ==
+			USB_PORT_STAT_HIGH_SPEED)) {
+		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
 				stream->interval, urb->interval);
-			goto done;
+		goto done;
 	}
 
 #ifdef FOTG210_URB_TRACE
 	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
+			"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
+			__func__, urb->dev->devpath, urb,
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			urb->transfer_buffer_length,
+			urb->number_of_packets, urb->interval,
+			stream);
 #endif
 
 	/* allocate ITDs w/o locking anything */
@@ -4795,19 +4601,87 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
 	else
 		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
- done_not_linked:
+done_not_linked:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
- done:
+done:
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
+static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned now_frame, bool live)
+{
+	unsigned uf;
+	bool modified;
+	union fotg210_shadow q, *q_p;
+	__hc32 type, *hw_p;
+
+	/* scan each element in frame's queue for completions */
+	q_p = &fotg210->pshadow[frame];
+	hw_p = &fotg210->periodic[frame];
+	q.ptr = q_p->ptr;
+	type = Q_NEXT_TYPE(fotg210, *hw_p);
+	modified = false;
+
+	while (q.ptr) {
+		switch (hc32_to_cpu(fotg210, type)) {
+		case Q_TYPE_ITD:
+			/* If this ITD is still active, leave it for
+			 * later processing ... check the next entry.
+			 * No need to check for activity unless the
+			 * frame is current.
+			 */
+			if (frame == now_frame && live) {
+				rmb();
+				for (uf = 0; uf < 8; uf++) {
+					if (q.itd->hw_transaction[uf] &
+							ITD_ACTIVE(fotg210))
+						break;
+				}
+				if (uf < 8) {
+					q_p = &q.itd->itd_next;
+					hw_p = &q.itd->hw_next;
+					type = Q_NEXT_TYPE(fotg210,
+							q.itd->hw_next);
+					q = *q_p;
+					break;
+				}
+			}
+
+			/* Take finished ITDs out of the schedule
+			 * and process them:  recycle, maybe report
+			 * URB completion.  HC won't cache the
+			 * pointer for much longer, if at all.
+			 */
+			*q_p = q.itd->itd_next;
+			*hw_p = q.itd->hw_next;
+			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
+			wmb();
+			modified = itd_complete(fotg210, q.itd);
+			q = *q_p;
+			break;
+		default:
+			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
+					type, frame, q.ptr);
+			/* FALL THROUGH */
+		case Q_TYPE_QH:
+		case Q_TYPE_FSTN:
+			/* End of the iTDs and siTDs */
+			q.ptr = NULL;
+			break;
+		}
+
+		/* assume completion callbacks modify the queue */
+		if (unlikely(modified && fotg210->isoc_count > 0))
+			return -EINVAL;
+	}
+	return 0;
+}
 
 static void scan_isoc(struct fotg210_hcd *fotg210)
 {
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fotg210->periodic_size - 1;
-	bool		modified, live;
+	unsigned uf, now_frame, frame, ret;
+	unsigned fmask = fotg210->periodic_size - 1;
+	bool live;
 
 	/*
 	 * When running, scan from last scan point up to "now"
@@ -4826,69 +4700,10 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 
 	frame = fotg210->next_frame;
 	for (;;) {
-		union fotg210_shadow	q, *q_p;
-		__hc32			type, *hw_p;
-
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fotg210->pshadow[frame];
-		hw_p = &fotg210->periodic[frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fotg210, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fotg210, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fotg210))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fotg210,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-				wmb();
-				modified = itd_complete(fotg210, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fotg210->isoc_count > 0))
-				goto restart;
-		}
+		ret = 1;
+		while (ret != 0)
+			ret = scan_frame_queue(fotg210, frame,
+					now_frame, live);
 
 		/* Stop when we have reached the current frame */
 		if (frame == now_frame)
@@ -4897,16 +4712,14 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 	}
 	fotg210->next_frame = now_frame;
 }
-/*-------------------------------------------------------------------------*/
-/*
- * Display / Set uframe_periodic_max
+
+/* Display / Set uframe_periodic_max
  */
 static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+		struct device_attribute *attr, char *buf)
 {
-	struct fotg210_hcd		*fotg210;
-	int			n;
+	struct fotg210_hcd *fotg210;
+	int n;
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
@@ -4915,15 +4728,14 @@ static ssize_t show_uframe_periodic_max(struct device *dev,
 
 
 static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
+		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct fotg210_hcd	*fotg210;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
+	struct fotg210_hcd *fotg210;
+	unsigned uframe_periodic_max;
+	unsigned frame, uframe;
+	unsigned short allocated_max;
+	unsigned long flags;
+	ssize_t ret;
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
@@ -4931,7 +4743,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 
 	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
 		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
-			     uframe_periodic_max);
+				uframe_periodic_max);
 		return -EINVAL;
 	}
 
@@ -4954,22 +4766,22 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 		for (frame = 0; frame < fotg210->periodic_size; ++frame)
 			for (uframe = 0; uframe < 7; ++uframe)
 				allocated_max = max(allocated_max,
-						    periodic_usecs(fotg210, frame, uframe));
+						periodic_usecs(fotg210, frame,
+						uframe));
 
 		if (allocated_max > uframe_periodic_max) {
 			fotg210_info(fotg210,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
-				allocated_max, uframe_periodic_max);
+					"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
+					allocated_max, uframe_periodic_max);
 			goto out_unlock;
 		}
 	}
 
 	/* increasing is always ok */
 
-	fotg210_info(fotg210, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
-		     100 * uframe_periodic_max/125, uframe_periodic_max);
+	fotg210_info(fotg210,
+			"setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
+			100 * uframe_periodic_max/125, uframe_periodic_max);
 
 	if (uframe_periodic_max != 100)
 		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
@@ -4987,8 +4799,8 @@ static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
 
 static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
-	int	i = 0;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	int i = 0;
 
 	if (i)
 		goto out;
@@ -5000,12 +4812,10 @@ static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
 
 static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
 
 	device_remove_file(controller, &dev_attr_uframe_periodic_max);
 }
-/*-------------------------------------------------------------------------*/
-
 /* On some systems, leaving remote wakeup enabled prevents system shutdown.
  * The firmware seems to think that powering off is a wakeup event!
  * This routine turns off remote wakeup and everything else, on all ports.
@@ -5017,8 +4827,7 @@ static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
 	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
 }
 
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
+/* Halt HC, turn off all ports, and let the BIOS use the companion controllers.
  * Must be called with interrupts enabled and the lock not held.
  */
 static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
@@ -5037,7 +4846,7 @@ static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
  */
 static void fotg210_shutdown(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 	spin_lock_irq(&fotg210->lock);
 	fotg210->shutdown = true;
@@ -5050,10 +4859,7 @@ static void fotg210_shutdown(struct usb_hcd *hcd)
 	hrtimer_cancel(&fotg210->hrtimer);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * fotg210_work is called from some interrupts, timers, and so on.
+/* fotg210_work is called from some interrupts, timers, and so on.
  * it calls driver completion functions, after dropping fotg210->lock.
  */
 static void fotg210_work(struct fotg210_hcd *fotg210)
@@ -5068,7 +4874,7 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	}
 	fotg210->scanning = true;
 
- rescan:
+rescan:
 	fotg210->need_rescan = false;
 	if (fotg210->async_count)
 		scan_async(fotg210);
@@ -5087,12 +4893,11 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	turn_on_io_watchdog(fotg210);
 }
 
-/*
- * Called when the fotg210_hcd module is removed.
+/* Called when the fotg210_hcd module is removed.
  */
 static void fotg210_stop(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 	fotg210_dbg(fotg210, "stop\n");
 
@@ -5116,26 +4921,26 @@ static void fotg210_stop(struct usb_hcd *hcd)
 	spin_unlock_irq(&fotg210->lock);
 	fotg210_mem_cleanup(fotg210);
 
-#ifdef	FOTG210_STATS
+#ifdef FOTG210_STATS
 	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+			fotg210->stats.normal, fotg210->stats.error,
+			fotg210->stats.iaa, fotg210->stats.lost_iaa);
 	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+			fotg210->stats.complete, fotg210->stats.unlink);
 #endif
 
 	dbg_status(fotg210, "fotg210_stop completed",
-		    fotg210_readl(fotg210, &fotg210->regs->status));
+			fotg210_readl(fotg210, &fotg210->regs->status));
 }
 
 /* one-time init, only for memory state */
 static int hcd_fotg210_init(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fotg210_qh_hw	*hw;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	int retval;
+	u32 hcc_params;
+	struct fotg210_qh_hw *hw;
 
 	spin_lock_init(&fotg210->lock);
 
@@ -5238,18 +5043,18 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 /* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
 static int fotg210_run(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	u32			hcc_params;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	u32 hcc_params;
 
 	hcd->uses_new_polling = 1;
 
 	/* EHCI spec section 4.1 */
 
 	fotg210_writel(fotg210, fotg210->periodic_dma,
-		       &fotg210->regs->frame_list);
+			&fotg210->regs->frame_list);
 	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-		       &fotg210->regs->async_next);
+			&fotg210->regs->async_next);
 
 	/*
 	 * hcc_params controls whether fotg210->regs->segment must (!!!)
@@ -5292,19 +5097,19 @@ static int fotg210_run(struct usb_hcd *hcd)
 	fotg210->rh_state = FOTG210_RH_RUNNING;
 	/* unblock posted writes */
 	fotg210_readl(fotg210, &fotg210->regs->command);
-	msleep(5);
+	usleep_range(5000, 10000);
 	up_write(&ehci_cf_port_reset_rwsem);
 	fotg210->last_periodic_enable = ktime_get_real();
 
 	temp = HC_VERSION(fotg210,
-			  fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+			fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
 	fotg210_info(fotg210,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fotg210->sbrn & 0xf0)>>4), (fotg210->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
+			"USB %x.%x started, EHCI %x.%02x\n",
+			((fotg210->sbrn & 0xf0) >> 4), (fotg210->sbrn & 0x0f),
+			temp >> 8, temp & 0xff);
 
 	fotg210_writel(fotg210, INTR_MASK,
-		    &fotg210->regs->intr_enable); /* Turn On Interrupts */
+			&fotg210->regs->intr_enable); /* Turn On Interrupts */
 
 	/* GRR this is run-once init(), being done every time the HC starts.
 	 * So long as they're part of class devices, we can't do it init()
@@ -5322,14 +5127,14 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	int retval;
 
 	fotg210->regs = (void __iomem *)fotg210->caps +
-	    HC_LENGTH(fotg210,
-		      fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+			HC_LENGTH(fotg210,
+			fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
 	dbg_hcs_params(fotg210, "reset");
 	dbg_hcc_params(fotg210, "reset");
 
 	/* cache this readonly data; minimize chip reads */
 	fotg210->hcs_params = fotg210_readl(fotg210,
-					    &fotg210->caps->hcs_params);
+			&fotg210->caps->hcs_params);
 
 	fotg210->sbrn = HCD_USB2;
 
@@ -5347,13 +5152,11 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 status, masked_status, pcd_status = 0, cmd;
+	int bh;
 
 	spin_lock(&fotg210->lock);
 
@@ -5373,7 +5176,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 	/* Shared IRQ? */
 	if (!masked_status ||
-	    unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
+			unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
 		spin_unlock(&fotg210->lock);
 		return IRQ_NONE;
 	}
@@ -5440,7 +5243,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 		if (test_bit(0, &fotg210->suspended_ports) &&
 				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
+				!(pstatus & PORT_SUSPEND)) &&
 				(pstatus & PORT_PE) &&
 				fotg210->reset_done[0] == 0) {
 
@@ -5469,7 +5272,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 		fotg210->rh_state = FOTG210_RH_STOPPING;
 		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
 		fotg210_writel(fotg210, fotg210->command,
-			       &fotg210->regs->command);
+				&fotg210->regs->command);
 		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
 		fotg210_handle_controller_death(fotg210);
 
@@ -5485,10 +5288,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 	return IRQ_HANDLED;
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * non-error returns are a promise to giveback() the urb later
+/* non-error returns are a promise to giveback() the urb later
  * we drop ownership so next owner (or urb unlink) can get it
  *
  * urb + dev is in hcd.self.controller.urb_list
@@ -5499,13 +5299,11 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
  * NOTE:  control, bulk, and interrupt share the same code to append TDs
  * to a (possibly active) QH, and the same QH scanning code.
  */
-static int fotg210_urb_enqueue(
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct list_head	qtd_list;
+static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+		gfp_t mem_flags)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct list_head qtd_list;
 
 	INIT_LIST_HEAD(&qtd_list);
 
@@ -5539,10 +5337,10 @@ static int fotg210_urb_enqueue(
 
 static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	unsigned long		flags;
-	int			rc;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
@@ -5603,16 +5401,14 @@ static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 	return rc;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* bulk qh holds the data toggle */
 
-static void
-fotg210_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_disable(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	unsigned long		flags;
-	struct fotg210_qh		*qh, *tmp;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	unsigned long flags;
+	struct fotg210_qh *qh, *tmp;
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
@@ -5627,7 +5423,7 @@ fotg210_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 	 * accelerate iso completions ... so spin a while.
 	 */
 	if (qh->hw == NULL) {
-		struct fotg210_iso_stream	*stream = ep->hcpriv;
+		struct fotg210_iso_stream *stream = ep->hcpriv;
 
 		if (!list_empty(&stream->td_list))
 			goto idle_timeout;
@@ -5671,24 +5467,24 @@ fotg210_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 		 * that's not our job.  just leak this memory.
 		 */
 		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty(&qh->qtd_list) ? "" : "(has tds)");
+				qh, ep->desc.bEndpointAddress, qh->qh_state,
+				list_empty(&qh->qtd_list) ? "" : "(has tds)");
 		break;
 	}
- done:
+done:
 	ep->hcpriv = NULL;
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 }
 
-static void
-fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_reset(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	int eptype = usb_endpoint_type(&ep->desc);
+	int epnum = usb_endpoint_num(&ep->desc);
+	int is_out = usb_endpoint_dir_out(&ep->desc);
+	unsigned long flags;
 
 	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
 		return;
@@ -5723,15 +5519,13 @@ fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 
 static int fotg210_get_frame(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
 	return (fotg210_read_frame_index(fotg210) >> 3) %
 		fotg210->periodic_size;
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
+/* 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 fotg210 driver exclusive access to those.
@@ -5791,7 +5585,7 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
 	u32 value;
 
 	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-		  &fotg210->regs->gmir);
+			&fotg210->regs->gmir);
 
 	value = ioread32(&fotg210->regs->otgcsr);
 	value &= ~OTGCSR_A_BUS_DROP;
@@ -5808,12 +5602,12 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
  */
 static int fotg210_hcd_probe(struct platform_device *pdev)
 {
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd			*hcd;
-	struct resource			*res;
-	int				irq;
-	int				retval = -ENODEV;
-	struct fotg210_hcd		*fotg210;
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int retval = -ENODEV;
+	struct fotg210_hcd *fotg210;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -5822,9 +5616,8 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
+		dev_err(dev, "Found HC with no IRQ. Check %s setup!\n",
+				dev_name(dev));
 		return -ENODEV;
 	}
 
@@ -5883,8 +5676,8 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
  */
 static int fotg210_hcd_remove(struct platform_device *pdev)
 {
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
 	if (!hcd)
 		return 0;
@@ -5914,12 +5707,12 @@ static int __init fotg210_hcd_init(void)
 	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
 			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
+		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
 
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),
-		 sizeof(struct fotg210_itd));
+			hcd_name, sizeof(struct fotg210_qh),
+			sizeof(struct fotg210_qtd),
+			sizeof(struct fotg210_itd));
 
 	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
 	if (!fotg210_debug_root) {
@@ -5932,7 +5725,6 @@ static int __init fotg210_hcd_init(void)
 		goto clean;
 	return retval;
 
-	platform_driver_unregister(&fotg210_hcd_driver);
 clean:
 	debugfs_remove(fotg210_debug_root);
 	fotg210_debug_root = NULL;
diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h
index 3bad17859cd72aebabd07750693e5bfe1b9bb78c..b5cfa7aeb277c783a9931931e4d902e40c92bf3b 100644
--- a/drivers/usb/host/fotg210.h
+++ b/drivers/usb/host/fotg210.h
@@ -137,19 +137,25 @@ struct fotg210_hcd {			/* one per controller */
 	/* per root hub port */
 	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
 
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
+	/* bit vectors (one bit per port)
+	 * which ports were already suspended at the start of a bus suspend
+	 */
+	unsigned long		bus_suspended;
+
+	/* which ports are edicated to the companion controller */
+	unsigned long		companion_ports;
+
+	/* which ports are owned by the companion during a bus suspend */
+	unsigned long		owned_ports;
+
+	/* which ports have the change-suspend feature turned on */
+	unsigned long		port_c_suspend;
+
+	/* which ports are suspended */
+	unsigned long		suspended_ports;
+
+	/* which ports have started to resume */
+	unsigned long		resuming_ports;
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
@@ -585,10 +591,10 @@ struct fotg210_fstn {
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
 #define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup);
+		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
 
 #define fotg210_prepare_ports_for_controller_resume(fotg210)		\
-		fotg210_adjust_port_wakeup_flags(fotg210, false, false);
+		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 534c4c5d278a31838f9afe7a7421a4397aa3d431..0c382652a3991fdd26cd5316b2eab9720d72b010 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -351,6 +351,7 @@ static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
 #endif
 	{},
 };
+MODULE_DEVICE_TABLE(of, fsl_usb2_mph_dr_of_match);
 
 static struct platform_driver fsl_usb2_mph_dr_driver = {
 	.driver = {
diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c
deleted file mode 100644
index 1fd8718a9f117aa863788d534d7f5e2256c32ee3..0000000000000000000000000000000000000000
--- a/drivers/usb/host/fusbh200-hcd.c
+++ /dev/null
@@ -1,5894 +0,0 @@
-/*
- * Faraday FUSBH200 EHCI-like driver
- *
- * Copyright (c) 2013 Faraday Technology Corporation
- *
- * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
- * 	   Feng-Hsin Chiang <john453@faraday-tech.com>
- * 	   Po-Yu Chuang <ratbert.chuang@gmail.com>
- *
- * Most of code borrowed from the Linux-3.7 EHCI driver
- *
- * 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/module.h>
-#include <linux/device.h>
-#include <linux/dmapool.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/hrtimer.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/unaligned.h>
-
-/*-------------------------------------------------------------------------*/
-#define DRIVER_AUTHOR "Yuan-Hsin Chen"
-#define DRIVER_DESC "FUSBH200 Host Controller (EHCI) Driver"
-
-static const char	hcd_name [] = "fusbh200_hcd";
-
-#undef FUSBH200_URB_TRACE
-
-/* magic numbers that can affect system performance */
-#define	FUSBH200_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
-#define	FUSBH200_TUNE_RL_HS		4	/* nak throttle; see 4.9 */
-#define	FUSBH200_TUNE_RL_TT		0
-#define	FUSBH200_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FUSBH200_TUNE_MULT_TT	1
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
- * code).  In an attempt to avoid trouble, we will use a minimum scheduling
- * length of 512 frames instead of 256.
- */
-#define	FUSBH200_TUNE_FLS		1	/* (medium) 512-frame schedule */
-
-/* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh = 0;		// 0 to 6
-module_param (log2_irq_thresh, int, S_IRUGO);
-MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-
-/* initial park setting:  slower than hw default */
-static unsigned park = 0;
-module_param (park, uint, S_IRUGO);
-MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
-
-/* for link power management(LPM) feature */
-static unsigned int hird;
-module_param(hird, int, S_IRUGO);
-MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
-
-#include "fusbh200.h"
-
-/*-------------------------------------------------------------------------*/
-
-#define fusbh200_dbg(fusbh200, fmt, args...) \
-	dev_dbg (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_err(fusbh200, fmt, args...) \
-	dev_err (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_info(fusbh200, fmt, args...) \
-	dev_info (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_warn(fusbh200, fmt, args...) \
-	dev_warn (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
- */
-static void dbg_hcs_params (struct fusbh200_hcd *fusbh200, char *label)
-{
-	u32	params = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-
-	fusbh200_dbg (fusbh200,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS (params)
-		);
-}
-
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
-static void dbg_hcc_params (struct fusbh200_hcd *fusbh200, char *label)
-{
-	u32	params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	fusbh200_dbg (fusbh200,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
-}
-
-static void __maybe_unused
-dbg_qtd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd)
-{
-	fusbh200_dbg(fusbh200, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fusbh200, &qtd->hw_next),
-		hc32_to_cpup(fusbh200, &qtd->hw_alt_next),
-		hc32_to_cpup(fusbh200, &qtd->hw_token),
-		hc32_to_cpup(fusbh200, &qtd->hw_buf [0]));
-	if (qtd->hw_buf [1])
-		fusbh200_dbg(fusbh200, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[1]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[2]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[3]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[4]));
-}
-
-static void __maybe_unused
-dbg_qh (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh_hw *hw = qh->hw;
-
-	fusbh200_dbg (fusbh200, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
-	dbg_qtd("overlay", fusbh200, (struct fusbh200_qtd *) &hw->hw_qtd_next);
-}
-
-static void __maybe_unused
-dbg_itd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd)
-{
-	fusbh200_dbg (fusbh200, "%s [%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fusbh200, itd->hw_next),
-		itd->urb);
-	fusbh200_dbg (fusbh200,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fusbh200, itd->hw_transaction[0]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[1]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[2]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[3]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[4]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[5]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[6]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[7]));
-	fusbh200_dbg (fusbh200,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fusbh200, itd->hw_bufp[0]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[1]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[2]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[3]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[4]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[5]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[6]));
-	fusbh200_dbg (fusbh200, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
-}
-
-static int __maybe_unused
-dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
-{
-	return scnprintf (buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label [0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
-}
-
-static int __maybe_unused
-dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
-{
-	return scnprintf (buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label [0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
-}
-
-static const char *const fls_strings [] =
-    { "1024", "512", "256", "??" };
-
-static int
-dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
-{
-	return scnprintf (buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label [0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT (command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings [(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static int
-dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
-
-	/* signaling state */
-	switch (status & (3 << 10)) {
-	case 0 << 10: sig = "se0"; break;
-	case 1 << 10: sig = "k"; break;		/* low speed */
-	case 2 << 10: sig = "j"; break;
-	default: sig = "?"; break;
-	}
-
-	return scnprintf (buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label [0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
-}
-
-/* functions have the "wrong" filename when they're output... */
-#define dbg_status(fusbh200, label, status) { \
-	char _buf [80]; \
-	dbg_status_buf (_buf, sizeof _buf, label, status); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-#define dbg_cmd(fusbh200, label, command) { \
-	char _buf [80]; \
-	dbg_command_buf (_buf, sizeof _buf, label, command); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-#define dbg_port(fusbh200, label, port, status) { \
-	char _buf [80]; \
-	dbg_port_buf (_buf, sizeof _buf, label, port, status); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* troubleshooting help: expose state in debugfs */
-
-static int debug_async_open(struct inode *, struct file *);
-static int debug_periodic_open(struct inode *, struct file *);
-static int debug_registers_open(struct inode *, struct file *);
-static int debug_async_open(struct inode *, struct file *);
-
-static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
-static int debug_close(struct inode *, struct file *);
-
-static const struct file_operations debug_async_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_async_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_periodic_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_periodic_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_registers_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_registers_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-
-static struct dentry *fusbh200_debug_root;
-
-struct debug_buffer {
-	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
-	struct usb_bus *bus;
-	struct mutex mutex;	/* protect filling of buffer */
-	size_t count;		/* number of characters filled into buffer */
-	char *output_buf;
-	size_t alloc_size;
-};
-
-#define speed_char(info1) ({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED: tmp = 'f'; break; \
-		case QH_LOW_SPEED:  tmp = 'l'; break; \
-		case QH_HIGH_SPEED: tmp = 'h'; break; \
-		default: tmp = '?'; break; \
-		} tmp; })
-
-static inline char token_mark(struct fusbh200_hcd *fusbh200, __hc32 token)
-{
-	__u32 v = hc32_to_cpu(fusbh200, token);
-
-	if (v & QTD_STS_ACTIVE)
-		return '*';
-	if (v & QTD_STS_HALT)
-		return '-';
-	if (!IS_SHORT_READ (v))
-		return ' ';
-	/* tries to advance through hw_alt_next */
-	return '/';
-}
-
-static void qh_lines (
-	struct fusbh200_hcd *fusbh200,
-	struct fusbh200_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fusbh200_qtd		*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FUSBH200_LIST_END(fusbh200);
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
-		mark = '@';
-	else
-		mark = token_mark(fusbh200, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fusbh200))
-				== fusbh200->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
-		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
-		/* else alt_next points to some other qtd */
-	}
-	scratch = hc32_to_cpup(fusbh200, &hw->hw_info1);
-	hw_curr = (mark == '*') ? hc32_to_cpup(fusbh200, &hw->hw_current) : 0;
-	temp = scnprintf (next, size,
-			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
-			qh, scratch & 0x007f,
-			speed_char (scratch),
-			(scratch >> 8) & 0x000f,
-			scratch, hc32_to_cpup(fusbh200, &hw->hw_info2),
-			hc32_to_cpup(fusbh200, &hw->hw_token), mark,
-			(cpu_to_hc32(fusbh200, QTD_TOGGLE) & hw->hw_token)
-				? "data1" : "data0",
-			(hc32_to_cpup(fusbh200, &hw->hw_alt_next) >> 1) & 0x0f);
-	size -= temp;
-	next += temp;
-
-	/* hc may be modifying the list as we read it ... */
-	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-		scratch = hc32_to_cpup(fusbh200, &td->hw_token);
-		mark = ' ';
-		if (hw_curr == td->qtd_dma)
-			mark = '*';
-		else if (hw->hw_qtd_next == cpu_to_hc32(fusbh200, td->qtd_dma))
-			mark = '+';
-		else if (QTD_LENGTH (scratch)) {
-			if (td->hw_alt_next == fusbh200->async->hw->hw_alt_next)
-				mark = '#';
-			else if (td->hw_alt_next != list_end)
-				mark = '/';
-		}
-		temp = snprintf (next, size,
-				"\n\t%p%c%s len=%d %08x urb %p",
-				td, mark, ({ char *tmp;
-				 switch ((scratch>>8)&0x03) {
-				 case 0: tmp = "out"; break;
-				 case 1: tmp = "in"; break;
-				 case 2: tmp = "setup"; break;
-				 default: tmp = "?"; break;
-				 } tmp;}),
-				(scratch >> 16) & 0x7fff,
-				scratch,
-				td->urb);
-		if (size < temp)
-			temp = size;
-		size -= temp;
-		next += temp;
-		if (temp == size)
-			goto done;
-	}
-
-	temp = snprintf (next, size, "\n");
-	if (size < temp)
-		temp = size;
-	size -= temp;
-	next += temp;
-
-done:
-	*sizep = size;
-	*nextp = next;
-}
-
-static ssize_t fill_async_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd	*fusbh200;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fusbh200_qh		*qh;
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	*next = 0;
-
-	/* dumps a snapshot of the async schedule.
-	 * usually empty except for long-term bulk reads, or head.
-	 * one QH per line, and TDs we know about
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (qh = fusbh200->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
-		qh_lines (fusbh200, qh, &next, &size);
-	if (fusbh200->async_unlink && size > 0) {
-		temp = scnprintf(next, size, "\nunlink =\n");
-		size -= temp;
-		next += temp;
-
-		for (qh = fusbh200->async_unlink; size > 0 && qh;
-				qh = qh->unlink_next)
-			qh_lines (fusbh200, qh, &next, &size);
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	return strlen(buf->output_buf);
-}
-
-#define DBG_SCHED_LIMIT 64
-static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd		*fusbh200;
-	unsigned long		flags;
-	union fusbh200_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
-
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC);
-	if (!seen)
-		return 0;
-	seen_count = 0;
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	temp = scnprintf (next, size, "size = %d\n", fusbh200->periodic_size);
-	size -= temp;
-	next += temp;
-
-	/* dump a snapshot of the periodic schedule.
-	 * iso changes, interrupt usually doesn't.
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (i = 0; i < fusbh200->periodic_size; i++) {
-		p = fusbh200->pshadow [i];
-		if (likely (!p.ptr))
-			continue;
-		tag = Q_NEXT_TYPE(fusbh200, fusbh200->periodic [i]);
-
-		temp = scnprintf (next, size, "%4d: ", i);
-		size -= temp;
-		next += temp;
-
-		do {
-			struct fusbh200_qh_hw *hw;
-
-			switch (hc32_to_cpu(fusbh200, tag)) {
-			case Q_TYPE_QH:
-				hw = p.qh->hw;
-				temp = scnprintf (next, size, " qh%d-%04x/%p",
-						p.qh->period,
-						hc32_to_cpup(fusbh200,
-							&hw->hw_info2)
-							/* uframe masks */
-							& (QH_CMASK | QH_SMASK),
-						p.qh);
-				size -= temp;
-				next += temp;
-				/* don't repeat what follows this qh */
-				for (temp = 0; temp < seen_count; temp++) {
-					if (seen [temp].ptr != p.ptr)
-						continue;
-					if (p.qh->qh_next.ptr) {
-						temp = scnprintf (next, size,
-							" ...");
-						size -= temp;
-						next += temp;
-					}
-					break;
-				}
-				/* show more info the first time around */
-				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fusbh200,
-							&hw->hw_info1);
-					struct fusbh200_qtd	*qtd;
-					char		*type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry (qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fusbh200,
-							qtd->hw_token) >> 8)) {
-						case 0: type = "out"; continue;
-						case 1: type = "in"; continue;
-						}
-					}
-
-					temp = scnprintf (next, size,
-						" (%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
-						speed_char (scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
-
-					if (seen_count < DBG_SCHED_LIMIT)
-						seen [seen_count++].qh = p.qh;
-				} else
-					temp = 0;
-				tag = Q_NEXT_TYPE(fusbh200, hw->hw_next);
-				p = p.qh->qh_next;
-				break;
-			case Q_TYPE_FSTN:
-				temp = scnprintf (next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
-				tag = Q_NEXT_TYPE(fusbh200, p.fstn->hw_next);
-				p = p.fstn->fstn_next;
-				break;
-			case Q_TYPE_ITD:
-				temp = scnprintf (next, size,
-					" itd/%p", p.itd);
-				tag = Q_NEXT_TYPE(fusbh200, p.itd->hw_next);
-				p = p.itd->itd_next;
-				break;
-			}
-			size -= temp;
-			next += temp;
-		} while (p.ptr);
-
-		temp = scnprintf (next, size, "\n");
-		size -= temp;
-		next += temp;
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	kfree (seen);
-
-	return buf->alloc_size - size;
-}
-#undef DBG_SCHED_LIMIT
-
-static const char *rh_state_string(struct fusbh200_hcd *fusbh200)
-{
-	switch (fusbh200->rh_state) {
-	case FUSBH200_RH_HALTED:
-		return "halted";
-	case FUSBH200_RH_SUSPENDED:
-		return "suspended";
-	case FUSBH200_RH_RUNNING:
-		return "running";
-	case FUSBH200_RH_STOPPING:
-		return "stopping";
-	}
-	return "?";
-}
-
-static ssize_t fill_registers_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd	*fusbh200;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch [80];
-	static char		fmt [] = "%*s\n";
-	static char		label [] = "";
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	if (!HCD_HW_ACCESSIBLE(hcd)) {
-		size = scnprintf (next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED (no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
-		goto done;
-	}
-
-	/* Capability Registers */
-	i = HC_VERSION(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	temp = scnprintf (next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fusbh200));
-	size -= temp;
-	next += temp;
-
-	// FIXME interpret both types of params
-	i = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-	temp = scnprintf (next, size, "structural params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	i = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-	temp = scnprintf (next, size, "capability params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	/* Operational Registers */
-	temp = dbg_status_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->status));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_command_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->command));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_intr_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->intr_enable));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf (next, size, "uframe %04x\n",
-			fusbh200_read_frame_index(fusbh200));
-	size -= temp;
-	next += temp;
-
-	if (fusbh200->async_unlink) {
-		temp = scnprintf(next, size, "async unlink qh %p\n",
-				fusbh200->async_unlink);
-		size -= temp;
-		next += temp;
-	}
-
-	temp = scnprintf (next, size,
-		"irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,
-		fusbh200->stats.lost_iaa);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf (next, size, "complete %ld unlink %ld\n",
-		fusbh200->stats.complete, fusbh200->stats.unlink);
-	size -= temp;
-	next += temp;
-
-done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	return buf->alloc_size - size;
-}
-
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
-{
-	struct debug_buffer *buf;
-
-	buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
-
-	if (buf) {
-		buf->bus = bus;
-		buf->fill_func = fill_func;
-		mutex_init(&buf->mutex);
-		buf->alloc_size = PAGE_SIZE;
-	}
-
-	return buf;
-}
-
-static int fill_buffer(struct debug_buffer *buf)
-{
-	int ret = 0;
-
-	if (!buf->output_buf)
-		buf->output_buf = vmalloc(buf->alloc_size);
-
-	if (!buf->output_buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = buf->fill_func(buf);
-
-	if (ret >= 0) {
-		buf->count = ret;
-		ret = 0;
-	}
-
-out:
-	return ret;
-}
-
-static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
-{
-	struct debug_buffer *buf = file->private_data;
-	int ret = 0;
-
-	mutex_lock(&buf->mutex);
-	if (buf->count == 0) {
-		ret = fill_buffer(buf);
-		if (ret != 0) {
-			mutex_unlock(&buf->mutex);
-			goto out;
-		}
-	}
-	mutex_unlock(&buf->mutex);
-
-	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
-
-out:
-	return ret;
-
-}
-
-static int debug_close(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf = file->private_data;
-
-	if (buf) {
-		vfree(buf->output_buf);
-		kfree(buf);
-	}
-
-	return 0;
-}
-static int debug_async_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static int debug_periodic_open(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf;
-	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
-	if (!buf)
-		return -ENOMEM;
-
-	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
-	file->private_data = buf;
-	return 0;
-}
-
-static int debug_registers_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static inline void create_debug_files (struct fusbh200_hcd *fusbh200)
-{
-	struct usb_bus *bus = &fusbh200_to_hcd(fusbh200)->self;
-
-	fusbh200->debug_dir = debugfs_create_dir(bus->bus_name, fusbh200_debug_root);
-	if (!fusbh200->debug_dir)
-		return;
-
-	if (!debugfs_create_file("async", S_IRUGO, fusbh200->debug_dir, bus,
-						&debug_async_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("periodic", S_IRUGO, fusbh200->debug_dir, bus,
-						&debug_periodic_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("registers", S_IRUGO, fusbh200->debug_dir, bus,
-						    &debug_registers_fops))
-		goto file_error;
-
-	return;
-
-file_error:
-	debugfs_remove_recursive(fusbh200->debug_dir);
-}
-
-static inline void remove_debug_files (struct fusbh200_hcd *fusbh200)
-{
-	debugfs_remove_recursive(fusbh200->debug_dir);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * handshake - spin reading hc until handshake completes or fails
- * @ptr: address of hc register to be read
- * @mask: bits to look at in result of read
- * @done: value of those bits when handshake succeeds
- * @usec: timeout in microseconds
- *
- * Returns negative errno, or zero on success
- *
- * Success happens when the "mask" bits have the specified value (hardware
- * handshake done).  There are two failure modes:  "usec" have passed (major
- * hardware flakeout), or the register reads as all-ones (hardware removed).
- *
- * That last failure should_only happen in cases like physical cardbus eject
- * before driver shutdown. But it also seems to be caused by bugs in cardbus
- * bridge shutdown:  shutting down the bridge before the devices using it.
- */
-static int handshake (struct fusbh200_hcd *fusbh200, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
-{
-	u32	result;
-
-	do {
-		result = fusbh200_readl(fusbh200, ptr);
-		if (result == ~(u32)0)		/* card removed */
-			return -ENODEV;
-		result &= mask;
-		if (result == done)
-			return 0;
-		udelay (1);
-		usec--;
-	} while (usec > 0);
-	return -ETIMEDOUT;
-}
-
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fusbh200_halt (struct fusbh200_hcd *fusbh200)
-{
-	u32	temp;
-
-	spin_lock_irq(&fusbh200->lock);
-
-	/* disable any irqs left enabled by previous code */
-	fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-
-	/*
-	 * This routine gets called during probe before fusbh200->command
-	 * has been initialized, so we can't rely on its value.
-	 */
-	fusbh200->command &= ~CMD_RUN;
-	temp = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-	temp &= ~(CMD_RUN | CMD_IAAD);
-	fusbh200_writel(fusbh200, temp, &fusbh200->regs->command);
-
-	spin_unlock_irq(&fusbh200->lock);
-	synchronize_irq(fusbh200_to_hcd(fusbh200)->irq);
-
-	return handshake(fusbh200, &fusbh200->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
-}
-
-/*
- * Reset a non-running (STS_HALT == 1) controller.
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fusbh200_reset (struct fusbh200_hcd *fusbh200)
-{
-	int	retval;
-	u32	command = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-
-	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
-	if (fusbh200->debug && !dbgp_reset_prep(fusbh200_to_hcd(fusbh200)))
-		fusbh200->debug = NULL;
-
-	command |= CMD_RESET;
-	dbg_cmd (fusbh200, "reset", command);
-	fusbh200_writel(fusbh200, command, &fusbh200->regs->command);
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200->next_statechange = jiffies;
-	retval = handshake (fusbh200, &fusbh200->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
-
-	if (retval)
-		return retval;
-
-	if (fusbh200->debug)
-		dbgp_external_startup(fusbh200_to_hcd(fusbh200));
-
-	fusbh200->port_c_suspend = fusbh200->suspended_ports =
-			fusbh200->resuming_ports = 0;
-	return retval;
-}
-
-/*
- * Idle the controller (turn off the schedules).
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fusbh200_quiesce (struct fusbh200_hcd *fusbh200)
-{
-	u32	temp;
-
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	/* wait for any schedule enables/disables to take effect */
-	temp = (fusbh200->command << 10) & (STS_ASS | STS_PSS);
-	handshake(fusbh200, &fusbh200->regs->status, STS_ASS | STS_PSS, temp, 16 * 125);
-
-	/* then disable anything that's still active */
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->command &= ~(CMD_ASE | CMD_PSE);
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-	spin_unlock_irq(&fusbh200->lock);
-
-	/* hardware can take 16 microframes to turn off ... */
-	handshake(fusbh200, &fusbh200->regs->status, STS_ASS | STS_PSS, 0, 16 * 125);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void end_unlink_async(struct fusbh200_hcd *fusbh200);
-static void unlink_empty_async(struct fusbh200_hcd *fusbh200);
-static void fusbh200_work(struct fusbh200_hcd *fusbh200);
-static void start_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-static void end_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-/*-------------------------------------------------------------------------*/
-
-/* Set a bit in the USBCMD register */
-static void fusbh200_set_command_bit(struct fusbh200_hcd *fusbh200, u32 bit)
-{
-	fusbh200->command |= bit;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-
-	/* unblock posted write */
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);
-}
-
-/* Clear a bit in the USBCMD register */
-static void fusbh200_clear_command_bit(struct fusbh200_hcd *fusbh200, u32 bit)
-{
-	fusbh200->command &= ~bit;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-
-	/* unblock posted write */
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI timer support...  Now using hrtimers.
- *
- * Lots of different events are triggered from fusbh200->hrtimer.  Whenever
- * the timer routine runs, it checks each possible event; events that are
- * currently enabled and whose expiration time has passed get handled.
- * The set of enabled events is stored as a collection of bitflags in
- * fusbh200->enabled_hrtimer_events, and they are numbered in order of
- * increasing delay values (ranging between 1 ms and 100 ms).
- *
- * Rather than implementing a sorted list or tree of all pending events,
- * we keep track only of the lowest-numbered pending event, in
- * fusbh200->next_hrtimer_event.  Whenever fusbh200->hrtimer gets restarted, its
- * expiration time is set to the timeout value for this event.
- *
- * As a result, events might not get handled right away; the actual delay
- * could be anywhere up to twice the requested delay.  This doesn't
- * matter, because none of the events are especially time-critical.  The
- * ones that matter most all have a delay of 1 ms, so they will be
- * handled after 2 ms at most, which is okay.  In addition to this, we
- * allow for an expiration range of 1 ms.
- */
-
-/*
- * Delay lengths for the hrtimer event types.
- * Keep this list sorted by delay length, in the same order as
- * the event types indexed by enum fusbh200_hrtimer_event in fusbh200.h.
- */
-static unsigned event_delays_ns[] = {
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_ASS */
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_PSS */
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_DEAD */
-	1125 * NSEC_PER_USEC,	/* FUSBH200_HRTIMER_UNLINK_INTR */
-	2 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_FREE_ITDS */
-	6 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_ASYNC_UNLINKS */
-	10 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_IAA_WATCHDOG */
-	10 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_DISABLE_PERIODIC */
-	15 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_DISABLE_ASYNC */
-	100 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_IO_WATCHDOG */
-};
-
-/* Enable a pending hrtimer event */
-static void fusbh200_enable_event(struct fusbh200_hcd *fusbh200, unsigned event,
-		bool resched)
-{
-	ktime_t		*timeout = &fusbh200->hr_timeouts[event];
-
-	if (resched)
-		*timeout = ktime_add(ktime_get(),
-				ktime_set(0, event_delays_ns[event]));
-	fusbh200->enabled_hrtimer_events |= (1 << event);
-
-	/* Track only the lowest-numbered pending event */
-	if (event < fusbh200->next_hrtimer_event) {
-		fusbh200->next_hrtimer_event = event;
-		hrtimer_start_range_ns(&fusbh200->hrtimer, *timeout,
-				NSEC_PER_MSEC, HRTIMER_MODE_ABS);
-	}
-}
-
-
-/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
-static void fusbh200_poll_ASS(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	actual, want;
-
-	/* Don't enable anything if the controller isn't running (e.g., died) */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	want = (fusbh200->command & CMD_ASE) ? STS_ASS : 0;
-	actual = fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_ASS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fusbh200->ASS_poll_count++ < 20) {
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_ASS, true);
-			return;
-		}
-		fusbh200_dbg(fusbh200, "Waited too long for the async schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fusbh200->ASS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fusbh200->async_count > 0)
-			fusbh200_set_command_bit(fusbh200, CMD_ASE);
-
-	} else {		/* Running */
-		if (fusbh200->async_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_DISABLE_ASYNC,
-					true);
-		}
-	}
-}
-
-/* Turn off the async schedule after a brief delay */
-static void fusbh200_disable_ASE(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_clear_command_bit(fusbh200, CMD_ASE);
-}
-
-
-/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
-static void fusbh200_poll_PSS(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	actual, want;
-
-	/* Don't do anything if the controller isn't running (e.g., died) */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	want = (fusbh200->command & CMD_PSE) ? STS_PSS : 0;
-	actual = fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_PSS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fusbh200->PSS_poll_count++ < 20) {
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_PSS, true);
-			return;
-		}
-		fusbh200_dbg(fusbh200, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fusbh200->PSS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fusbh200->periodic_count > 0)
-			fusbh200_set_command_bit(fusbh200, CMD_PSE);
-
-	} else {		/* Running */
-		if (fusbh200->periodic_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_DISABLE_PERIODIC,
-					true);
-		}
-	}
-}
-
-/* Turn off the periodic schedule after a brief delay */
-static void fusbh200_disable_PSE(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_clear_command_bit(fusbh200, CMD_PSE);
-}
-
-
-/* Poll the STS_HALT status bit; see when a dead controller stops */
-static void fusbh200_handle_controller_death(struct fusbh200_hcd *fusbh200)
-{
-	if (!(fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_HALT)) {
-
-		/* Give up after a few milliseconds */
-		if (fusbh200->died_poll_count++ < 5) {
-			/* Try again later */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_DEAD, true);
-			return;
-		}
-		fusbh200_warn(fusbh200, "Waited too long for the controller to stop, giving up\n");
-	}
-
-	/* Clean up the mess */
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-	fusbh200_work(fusbh200);
-	end_unlink_async(fusbh200);
-
-	/* Not in process context, so don't try to reset the controller */
-}
-
-
-/* Handle unlinked interrupt QHs once they are gone from the hardware */
-static void fusbh200_handle_intr_unlinks(struct fusbh200_hcd *fusbh200)
-{
-	bool		stopped = (fusbh200->rh_state < FUSBH200_RH_RUNNING);
-
-	/*
-	 * Process all the QHs on the intr_unlink list that were added
-	 * before the current unlink cycle began.  The list is in
-	 * temporal order, so stop when we reach the first entry in the
-	 * current cycle.  But if the root hub isn't running then
-	 * process all the QHs on the list.
-	 */
-	fusbh200->intr_unlinking = true;
-	while (fusbh200->intr_unlink) {
-		struct fusbh200_qh	*qh = fusbh200->intr_unlink;
-
-		if (!stopped && qh->unlink_cycle == fusbh200->intr_unlink_cycle)
-			break;
-		fusbh200->intr_unlink = qh->unlink_next;
-		qh->unlink_next = NULL;
-		end_unlink_intr(fusbh200, qh);
-	}
-
-	/* Handle remaining entries later */
-	if (fusbh200->intr_unlink) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_UNLINK_INTR, true);
-		++fusbh200->intr_unlink_cycle;
-	}
-	fusbh200->intr_unlinking = false;
-}
-
-
-/* Start another free-iTDs/siTDs cycle */
-static void start_free_itds(struct fusbh200_hcd *fusbh200)
-{
-	if (!(fusbh200->enabled_hrtimer_events & BIT(FUSBH200_HRTIMER_FREE_ITDS))) {
-		fusbh200->last_itd_to_free = list_entry(
-				fusbh200->cached_itd_list.prev,
-				struct fusbh200_itd, itd_list);
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_FREE_ITDS, true);
-	}
-}
-
-/* Wait for controller to stop using old iTDs and siTDs */
-static void end_free_itds(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_itd		*itd, *n;
-
-	if (fusbh200->rh_state < FUSBH200_RH_RUNNING) {
-		fusbh200->last_itd_to_free = NULL;
-	}
-
-	list_for_each_entry_safe(itd, n, &fusbh200->cached_itd_list, itd_list) {
-		list_del(&itd->itd_list);
-		dma_pool_free(fusbh200->itd_pool, itd, itd->itd_dma);
-		if (itd == fusbh200->last_itd_to_free)
-			break;
-	}
-
-	if (!list_empty(&fusbh200->cached_itd_list))
-		start_free_itds(fusbh200);
-}
-
-
-/* Handle lost (or very late) IAA interrupts */
-static void fusbh200_iaa_watchdog(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	/*
-	 * Lost IAA irqs wedge things badly; seen first with a vt8235.
-	 * So we need this watchdog, but must protect it against both
-	 * (a) SMP races against real IAA firing and retriggering, and
-	 * (b) clean HC shutdown, when IAA watchdog was pending.
-	 */
-	if (fusbh200->async_iaa) {
-		u32 cmd, status;
-
-		/* If we get here, IAA is *REALLY* late.  It's barely
-		 * conceivable that the system is so busy that CMD_IAAD
-		 * is still legitimately set, so let's be sure it's
-		 * clear before we read STS_IAA.  (The HC should clear
-		 * CMD_IAAD when it sets STS_IAA.)
-		 */
-		cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-
-		/*
-		 * If IAA is set here it either legitimately triggered
-		 * after the watchdog timer expired (_way_ late, so we'll
-		 * still count it as lost) ... or a silicon erratum:
-		 * - VIA seems to set IAA without triggering the IRQ;
-		 * - IAAD potentially cleared without setting IAA.
-		 */
-		status = fusbh200_readl(fusbh200, &fusbh200->regs->status);
-		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-			COUNT(fusbh200->stats.lost_iaa);
-			fusbh200_writel(fusbh200, STS_IAA, &fusbh200->regs->status);
-		}
-
-		fusbh200_dbg(fusbh200, "IAA watchdog: status %x cmd %x\n",
-				status, cmd);
-		end_unlink_async(fusbh200);
-	}
-}
-
-
-/* Enable the I/O watchdog, if appropriate */
-static void turn_on_io_watchdog(struct fusbh200_hcd *fusbh200)
-{
-	/* Not needed if the controller isn't running or it's already enabled */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING ||
-			(fusbh200->enabled_hrtimer_events &
-				BIT(FUSBH200_HRTIMER_IO_WATCHDOG)))
-		return;
-
-	/*
-	 * Isochronous transfers always need the watchdog.
-	 * For other sorts we use it only if the flag is set.
-	 */
-	if (fusbh200->isoc_count > 0 || (fusbh200->need_io_watchdog &&
-			fusbh200->async_count + fusbh200->intr_count > 0))
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_IO_WATCHDOG, true);
-}
-
-
-/*
- * Handler functions for the hrtimer event types.
- * Keep this array in the same order as the event types indexed by
- * enum fusbh200_hrtimer_event in fusbh200.h.
- */
-static void (*event_handlers[])(struct fusbh200_hcd *) = {
-	fusbh200_poll_ASS,			/* FUSBH200_HRTIMER_POLL_ASS */
-	fusbh200_poll_PSS,			/* FUSBH200_HRTIMER_POLL_PSS */
-	fusbh200_handle_controller_death,	/* FUSBH200_HRTIMER_POLL_DEAD */
-	fusbh200_handle_intr_unlinks,	/* FUSBH200_HRTIMER_UNLINK_INTR */
-	end_free_itds,			/* FUSBH200_HRTIMER_FREE_ITDS */
-	unlink_empty_async,		/* FUSBH200_HRTIMER_ASYNC_UNLINKS */
-	fusbh200_iaa_watchdog,		/* FUSBH200_HRTIMER_IAA_WATCHDOG */
-	fusbh200_disable_PSE,		/* FUSBH200_HRTIMER_DISABLE_PERIODIC */
-	fusbh200_disable_ASE,		/* FUSBH200_HRTIMER_DISABLE_ASYNC */
-	fusbh200_work,			/* FUSBH200_HRTIMER_IO_WATCHDOG */
-};
-
-static enum hrtimer_restart fusbh200_hrtimer_func(struct hrtimer *t)
-{
-	struct fusbh200_hcd	*fusbh200 = container_of(t, struct fusbh200_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-
-	events = fusbh200->enabled_hrtimer_events;
-	fusbh200->enabled_hrtimer_events = 0;
-	fusbh200->next_hrtimer_event = FUSBH200_HRTIMER_NO_EVENT;
-
-	/*
-	 * Check each pending event.  If its time has expired, handle
-	 * the event; otherwise re-enable it.
-	 */
-	now = ktime_get();
-	for_each_set_bit(e, &events, FUSBH200_HRTIMER_NUM_EVENTS) {
-		if (now.tv64 >= fusbh200->hr_timeouts[e].tv64)
-			event_handlers[e](fusbh200);
-		else
-			fusbh200_enable_event(fusbh200, e, false);
-	}
-
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-	return HRTIMER_NORESTART;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define fusbh200_bus_suspend	NULL
-#define fusbh200_bus_resume	NULL
-
-/*-------------------------------------------------------------------------*/
-
-static int check_reset_complete (
-	struct fusbh200_hcd	*fusbh200,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
-	if (!(port_status & PORT_CONNECT))
-		return port_status;
-
-	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
-		/* with integrated TT, there's nobody to hand it to! */
-		fusbh200_dbg (fusbh200,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
-		return port_status;
-	} else {
-		fusbh200_dbg(fusbh200, "port %d reset complete, port enabled\n",
-			index + 1);
-	}
-
-	return port_status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-
-/* build "status change" packet (one or two bytes) from HC registers */
-
-static int
-fusbh200_hub_status_data (struct usb_hcd *hcd, char *buf)
-{
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
-
-	/* init status to no-changes */
-	buf [0] = 0;
-
-	/* Inform the core about resumes-in-progress by returning
-	 * a non-zero value even if there are no status changes.
-	 */
-	status = fusbh200->resuming_ports;
-
-	mask = PORT_CSC | PORT_PEC;
-	// PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
-
-	/* no hub change reports (bit 0) for now (power, ...) */
-
-	/* port N changes (bit N)? */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	temp = fusbh200_readl(fusbh200, &fusbh200->regs->port_status);
-
-	/*
-	 * Return status information even for ports with OWNER set.
-	 * Otherwise hub_wq wouldn't see the disconnect event when a
-	 * high-speed device is switched over to the companion
-	 * controller by the user.
-	 */
-
-	if ((temp & mask) != 0 || test_bit(0, &fusbh200->port_c_suspend)
-			|| (fusbh200->reset_done[0] && time_after_eq(
-				jiffies, fusbh200->reset_done[0]))) {
-		buf [0] |= 1 << 1;
-		status = STS_PCD;
-	}
-	/* FIXME autosuspend idle root hubs */
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return status ? retval : 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void
-fusbh200_hub_descriptor (
-	struct fusbh200_hcd		*fusbh200,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS (fusbh200->hcs_params);
-	u16		temp;
-
-	desc->bDescriptorType = USB_DT_HUB;
-	desc->bPwrOn2PwrGood = 10;	/* fusbh200 1.0, 2.3.9 says 20ms max */
-	desc->bHubContrCurrent = 0;
-
-	desc->bNbrPorts = ports;
-	temp = 1 + (ports / 8);
-	desc->bDescLength = 7 + 2 * temp;
-
-	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
-	memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
-	memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
-
-	temp = HUB_CHAR_INDV_PORT_OCPM;	/* per-port overcurrent reporting */
-	temp |= HUB_CHAR_NO_LPSM;	/* no power switching */
-	desc->wHubCharacteristics = cpu_to_le16(temp);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int fusbh200_hub_control (
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200 (hcd);
-	int		ports = HCS_N_PORTS (fusbh200->hcs_params);
-	u32 __iomem	*status_reg = &fusbh200->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
-
-	/*
-	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
-	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
-	 * (track current state ourselves) ... blink for diagnostics,
-	 * power, "this is the one", etc.  EHCI spec supports this.
-	 */
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	switch (typeReq) {
-	case ClearHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case ClearPortFeature:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fusbh200_readl(fusbh200, status_reg);
-		temp &= ~PORT_RWC_BITS;
-
-		/*
-		 * Even if OWNER is set, so the port is owned by the
-		 * companion controller, hub_wq needs to be able to clear
-		 * the port-change status bits (especially
-		 * USB_PORT_STAT_C_CONNECTION).
-		 */
-
-		switch (wValue) {
-		case USB_PORT_FEAT_ENABLE:
-			fusbh200_writel(fusbh200, temp & ~PORT_PE, status_reg);
-			break;
-		case USB_PORT_FEAT_C_ENABLE:
-			fusbh200_writel(fusbh200, temp | PORT_PEC, status_reg);
-			break;
-		case USB_PORT_FEAT_SUSPEND:
-			if (temp & PORT_RESET)
-				goto error;
-			if (!(temp & PORT_SUSPEND))
-				break;
-			if ((temp & PORT_PE) == 0)
-				goto error;
-
-			fusbh200_writel(fusbh200, temp | PORT_RESUME, status_reg);
-			fusbh200->reset_done[wIndex] = jiffies
-					+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
-			break;
-		case USB_PORT_FEAT_C_SUSPEND:
-			clear_bit(wIndex, &fusbh200->port_c_suspend);
-			break;
-		case USB_PORT_FEAT_C_CONNECTION:
-			fusbh200_writel(fusbh200, temp | PORT_CSC, status_reg);
-			break;
-		case USB_PORT_FEAT_C_OVER_CURRENT:
-			fusbh200_writel(fusbh200, temp | BMISR_OVC, &fusbh200->regs->bmisr);
-			break;
-		case USB_PORT_FEAT_C_RESET:
-			/* GetPortStatus clears reset */
-			break;
-		default:
-			goto error;
-		}
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted write */
-		break;
-	case GetHubDescriptor:
-		fusbh200_hub_descriptor (fusbh200, (struct usb_hub_descriptor *)
-			buf);
-		break;
-	case GetHubStatus:
-		/* no hub-wide feature/status flags */
-		memset (buf, 0, 4);
-		//cpu_to_le32s ((u32 *) buf);
-		break;
-	case GetPortStatus:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		status = 0;
-		temp = fusbh200_readl(fusbh200, status_reg);
-
-		// wPortChange bits
-		if (temp & PORT_CSC)
-			status |= USB_PORT_STAT_C_CONNECTION << 16;
-		if (temp & PORT_PEC)
-			status |= USB_PORT_STAT_C_ENABLE << 16;
-
-		temp1 = fusbh200_readl(fusbh200, &fusbh200->regs->bmisr);
-		if (temp1 & BMISR_OVC)
-			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
-
-		/* whoever resumes must GetPortStatus to complete it!! */
-		if (temp & PORT_RESUME) {
-
-			/* Remote Wakeup received? */
-			if (!fusbh200->reset_done[wIndex]) {
-				/* resume signaling for 20 msec */
-				fusbh200->reset_done[wIndex] = jiffies
-						+ msecs_to_jiffies(20);
-				/* check the port again */
-				mod_timer(&fusbh200_to_hcd(fusbh200)->rh_timer,
-						fusbh200->reset_done[wIndex]);
-			}
-
-			/* resume completed? */
-			else if (time_after_eq(jiffies,
-					fusbh200->reset_done[wIndex])) {
-				clear_bit(wIndex, &fusbh200->suspended_ports);
-				set_bit(wIndex, &fusbh200->port_c_suspend);
-				fusbh200->reset_done[wIndex] = 0;
-
-				/* stop resume signaling */
-				temp = fusbh200_readl(fusbh200, status_reg);
-				fusbh200_writel(fusbh200,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
-				clear_bit(wIndex, &fusbh200->resuming_ports);
-				retval = handshake(fusbh200, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
-				if (retval != 0) {
-					fusbh200_err(fusbh200,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
-					goto error;
-				}
-				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
-			}
-		}
-
-		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fusbh200->reset_done[wIndex])) {
-			status |= USB_PORT_STAT_C_RESET << 16;
-			fusbh200->reset_done [wIndex] = 0;
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-
-			/* force reset to complete */
-			fusbh200_writel(fusbh200, temp & ~(PORT_RWC_BITS | PORT_RESET),
-					status_reg);
-			/* REVISIT:  some hardware needs 550+ usec to clear
-			 * this bit; seems too long to spin routinely...
-			 */
-			retval = handshake(fusbh200, status_reg,
-					PORT_RESET, 0, 1000);
-			if (retval != 0) {
-				fusbh200_err (fusbh200, "port %d reset error %d\n",
-					wIndex + 1, retval);
-				goto error;
-			}
-
-			/* see what we found out */
-			temp = check_reset_complete (fusbh200, wIndex, status_reg,
-					fusbh200_readl(fusbh200, status_reg));
-		}
-
-		if (!(temp & (PORT_RESUME|PORT_RESET))) {
-			fusbh200->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-		}
-
-		/* transfer dedicated ports to the companion hc */
-		if ((temp & PORT_CONNECT) &&
-				test_bit(wIndex, &fusbh200->companion_ports)) {
-			temp &= ~PORT_RWC_BITS;
-			fusbh200_writel(fusbh200, temp, status_reg);
-			fusbh200_dbg(fusbh200, "port %d --> companion\n", wIndex + 1);
-			temp = fusbh200_readl(fusbh200, status_reg);
-		}
-
-		/*
-		 * Even if OWNER is set, there's no harm letting hub_wq
-		 * see the wPortStatus values (they should all be 0 except
-		 * for PORT_POWER anyway).
-		 */
-
-		if (temp & PORT_CONNECT) {
-			status |= USB_PORT_STAT_CONNECTION;
-			status |= fusbh200_port_speed(fusbh200, temp);
-		}
-		if (temp & PORT_PE)
-			status |= USB_PORT_STAT_ENABLE;
-
-		/* maybe the port was unsuspended without our knowledge */
-		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
-			status |= USB_PORT_STAT_SUSPEND;
-		} else if (test_bit(wIndex, &fusbh200->suspended_ports)) {
-			clear_bit(wIndex, &fusbh200->suspended_ports);
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-			fusbh200->reset_done[wIndex] = 0;
-			if (temp & PORT_PE)
-				set_bit(wIndex, &fusbh200->port_c_suspend);
-		}
-
-		temp1 = fusbh200_readl(fusbh200, &fusbh200->regs->bmisr);
-		if (temp1 & BMISR_OVC)
-			status |= USB_PORT_STAT_OVERCURRENT;
-		if (temp & PORT_RESET)
-			status |= USB_PORT_STAT_RESET;
-		if (test_bit(wIndex, &fusbh200->port_c_suspend))
-			status |= USB_PORT_STAT_C_SUSPEND << 16;
-
-		if (status & ~0xffff)	/* only if wPortChange is interesting */
-			dbg_port(fusbh200, "GetStatus", wIndex + 1, temp);
-		put_unaligned_le32(status, buf);
-		break;
-	case SetHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case SetPortFeature:
-		selector = wIndex >> 8;
-		wIndex &= 0xff;
-
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fusbh200_readl(fusbh200, status_reg);
-		temp &= ~PORT_RWC_BITS;
-		switch (wValue) {
-		case USB_PORT_FEAT_SUSPEND:
-			if ((temp & PORT_PE) == 0
-					|| (temp & PORT_RESET) != 0)
-				goto error;
-
-			/* After above check the port must be connected.
-			 * Set appropriate bit thus could put phy into low power
-			 * mode if we have hostpc feature
-			 */
-			fusbh200_writel(fusbh200, temp | PORT_SUSPEND, status_reg);
-			set_bit(wIndex, &fusbh200->suspended_ports);
-			break;
-		case USB_PORT_FEAT_RESET:
-			if (temp & PORT_RESUME)
-				goto error;
-			/* line status bits may report this as low speed,
-			 * which can be fine if this root hub has a
-			 * transaction translator built in.
-			 */
-			fusbh200_dbg(fusbh200, "port %d reset\n", wIndex + 1);
-			temp |= PORT_RESET;
-			temp &= ~PORT_PE;
-
-			/*
-			 * caller must wait, then call GetPortStatus
-			 * usb 2.0 spec says 50 ms resets on root
-			 */
-			fusbh200->reset_done [wIndex] = jiffies
-					+ msecs_to_jiffies (50);
-			fusbh200_writel(fusbh200, temp, status_reg);
-			break;
-
-		/* For downstream facing ports (these):  one hub port is put
-		 * into test mode according to USB2 11.24.2.13, then the hub
-		 * must be reset (which for root hub now means rmmod+modprobe,
-		 * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
-		 * about the EHCI-specific stuff.
-		 */
-		case USB_PORT_FEAT_TEST:
-			if (!selector || selector > 5)
-				goto error;
-			spin_unlock_irqrestore(&fusbh200->lock, flags);
-			fusbh200_quiesce(fusbh200);
-			spin_lock_irqsave(&fusbh200->lock, flags);
-
-			/* Put all enabled ports into suspend */
-			temp = fusbh200_readl(fusbh200, status_reg) & ~PORT_RWC_BITS;
-			if (temp & PORT_PE)
-				fusbh200_writel(fusbh200, temp | PORT_SUSPEND,
-						status_reg);
-
-			spin_unlock_irqrestore(&fusbh200->lock, flags);
-			fusbh200_halt(fusbh200);
-			spin_lock_irqsave(&fusbh200->lock, flags);
-
-			temp = fusbh200_readl(fusbh200, status_reg);
-			temp |= selector << 16;
-			fusbh200_writel(fusbh200, temp, status_reg);
-			break;
-
-		default:
-			goto error;
-		}
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted writes */
-		break;
-
-	default:
-error:
-		/* "stall" on error */
-		retval = -EPIPE;
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return retval;
-}
-
-static void __maybe_unused fusbh200_relinquish_port(struct usb_hcd *hcd,
-		int portnum)
-{
-	return;
-}
-
-static int __maybe_unused fusbh200_port_handed_over(struct usb_hcd *hcd,
-		int portnum)
-{
-	return 0;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * There's basically three types of memory:
- *	- data used only by the HCD ... kmalloc is fine
- *	- async and periodic schedules, shared by HC and HCD ... these
- *	  need to use dma_pool or dma_alloc_coherent
- *	- driver buffers, read/written by HC ... single shot DMA mapped
- *
- * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
- * No memory seen by this driver is pageable.
- */
-
-/*-------------------------------------------------------------------------*/
-
-/* Allocate the key transfer structures from the previously allocated pool */
-
-static inline void fusbh200_qtd_init(struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd,
-				  dma_addr_t dma)
-{
-	memset (qtd, 0, sizeof *qtd);
-	qtd->qtd_dma = dma;
-	qtd->hw_token = cpu_to_hc32(fusbh200, QTD_STS_HALT);
-	qtd->hw_next = FUSBH200_LIST_END(fusbh200);
-	qtd->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-	INIT_LIST_HEAD (&qtd->qtd_list);
-}
-
-static struct fusbh200_qtd *fusbh200_qtd_alloc (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	struct fusbh200_qtd		*qtd;
-	dma_addr_t		dma;
-
-	qtd = dma_pool_alloc (fusbh200->qtd_pool, flags, &dma);
-	if (qtd != NULL) {
-		fusbh200_qtd_init(fusbh200, qtd, dma);
-	}
-	return qtd;
-}
-
-static inline void fusbh200_qtd_free (struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd)
-{
-	dma_pool_free (fusbh200->qtd_pool, qtd, qtd->qtd_dma);
-}
-
-
-static void qh_destroy(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/* clean qtds first, and know this is not linked */
-	if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
-		fusbh200_dbg (fusbh200, "unused qh not empty!\n");
-		BUG ();
-	}
-	if (qh->dummy)
-		fusbh200_qtd_free (fusbh200, qh->dummy);
-	dma_pool_free(fusbh200->qh_pool, qh->hw, qh->qh_dma);
-	kfree(qh);
-}
-
-static struct fusbh200_qh *fusbh200_qh_alloc (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	struct fusbh200_qh		*qh;
-	dma_addr_t		dma;
-
-	qh = kzalloc(sizeof *qh, GFP_ATOMIC);
-	if (!qh)
-		goto done;
-	qh->hw = (struct fusbh200_qh_hw *)
-		dma_pool_alloc(fusbh200->qh_pool, flags, &dma);
-	if (!qh->hw)
-		goto fail;
-	memset(qh->hw, 0, sizeof *qh->hw);
-	qh->qh_dma = dma;
-	// INIT_LIST_HEAD (&qh->qh_list);
-	INIT_LIST_HEAD (&qh->qtd_list);
-
-	/* dummy td enables safe urb queuing */
-	qh->dummy = fusbh200_qtd_alloc (fusbh200, flags);
-	if (qh->dummy == NULL) {
-		fusbh200_dbg (fusbh200, "no dummy td\n");
-		goto fail1;
-	}
-done:
-	return qh;
-fail1:
-	dma_pool_free(fusbh200->qh_pool, qh->hw, qh->qh_dma);
-fail:
-	kfree(qh);
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* The queue heads and transfer descriptors are managed from pools tied
- * to each of the "per device" structures.
- * This is the initialisation and cleanup code.
- */
-
-static void fusbh200_mem_cleanup (struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->async)
-		qh_destroy(fusbh200, fusbh200->async);
-	fusbh200->async = NULL;
-
-	if (fusbh200->dummy)
-		qh_destroy(fusbh200, fusbh200->dummy);
-	fusbh200->dummy = NULL;
-
-	/* DMA consistent memory and pools */
-	if (fusbh200->qtd_pool)
-		dma_pool_destroy (fusbh200->qtd_pool);
-	fusbh200->qtd_pool = NULL;
-
-	if (fusbh200->qh_pool) {
-		dma_pool_destroy (fusbh200->qh_pool);
-		fusbh200->qh_pool = NULL;
-	}
-
-	if (fusbh200->itd_pool)
-		dma_pool_destroy (fusbh200->itd_pool);
-	fusbh200->itd_pool = NULL;
-
-	if (fusbh200->periodic)
-		dma_free_coherent (fusbh200_to_hcd(fusbh200)->self.controller,
-			fusbh200->periodic_size * sizeof (u32),
-			fusbh200->periodic, fusbh200->periodic_dma);
-	fusbh200->periodic = NULL;
-
-	/* shadow periodic table */
-	kfree(fusbh200->pshadow);
-	fusbh200->pshadow = NULL;
-}
-
-/* remember to add cleanup code (above) if you add anything here */
-static int fusbh200_mem_init (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	int i;
-
-	/* QTDs for control/bulk/intr transfers */
-	fusbh200->qtd_pool = dma_pool_create ("fusbh200_qtd",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof (struct fusbh200_qtd),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->qtd_pool) {
-		goto fail;
-	}
-
-	/* QHs for control/bulk/intr transfers */
-	fusbh200->qh_pool = dma_pool_create ("fusbh200_qh",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof(struct fusbh200_qh_hw),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->qh_pool) {
-		goto fail;
-	}
-	fusbh200->async = fusbh200_qh_alloc (fusbh200, flags);
-	if (!fusbh200->async) {
-		goto fail;
-	}
-
-	/* ITD for high speed ISO transfers */
-	fusbh200->itd_pool = dma_pool_create ("fusbh200_itd",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof (struct fusbh200_itd),
-			64 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->itd_pool) {
-		goto fail;
-	}
-
-	/* Hardware periodic table */
-	fusbh200->periodic = (__le32 *)
-		dma_alloc_coherent (fusbh200_to_hcd(fusbh200)->self.controller,
-			fusbh200->periodic_size * sizeof(__le32),
-			&fusbh200->periodic_dma, 0);
-	if (fusbh200->periodic == NULL) {
-		goto fail;
-	}
-
-		for (i = 0; i < fusbh200->periodic_size; i++)
-			fusbh200->periodic[i] = FUSBH200_LIST_END(fusbh200);
-
-	/* software shadow of hardware table */
-	fusbh200->pshadow = kcalloc(fusbh200->periodic_size, sizeof(void *), flags);
-	if (fusbh200->pshadow != NULL)
-		return 0;
-
-fail:
-	fusbh200_dbg (fusbh200, "couldn't init memory\n");
-	fusbh200_mem_cleanup (fusbh200);
-	return -ENOMEM;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
- *
- * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
- * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
- * buffers needed for the larger number).  We use one QH per endpoint, queue
- * multiple urbs (all three types) per endpoint.  URBs may need several qtds.
- *
- * ISO traffic uses "ISO TD" (itd) records, and (along with
- * interrupts) needs careful scheduling.  Performance improvements can be
- * an ongoing challenge.  That's in "ehci-sched.c".
- *
- * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
- * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
- * (b) special fields in qh entries or (c) split iso entries.  TTs will
- * buffer low/full speed data so the host collects it at high speed.
- */
-
-/*-------------------------------------------------------------------------*/
-
-/* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
-{
-	int	i, count;
-	u64	addr = buf;
-
-	/* one buffer entry per 4K ... first might be short or unaligned */
-	qtd->hw_buf[0] = cpu_to_hc32(fusbh200, (u32)addr);
-	qtd->hw_buf_hi[0] = cpu_to_hc32(fusbh200, (u32)(addr >> 32));
-	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
-	if (likely (len < count))		/* ... iff needed */
-		count = len;
-	else {
-		buf +=  0x1000;
-		buf &= ~0x0fff;
-
-		/* per-qtd limit: from 16K to 20K (best alignment) */
-		for (i = 1; count < len && i < 5; i++) {
-			addr = buf;
-			qtd->hw_buf[i] = cpu_to_hc32(fusbh200, (u32)addr);
-			qtd->hw_buf_hi[i] = cpu_to_hc32(fusbh200,
-					(u32)(addr >> 32));
-			buf += 0x1000;
-			if ((count + 0x1000) < len)
-				count += 0x1000;
-			else
-				count = len;
-		}
-
-		/* short packets may only terminate transfers */
-		if (count != len)
-			count -= (count % maxpacket);
-	}
-	qtd->hw_token = cpu_to_hc32(fusbh200, (count << 16) | token);
-	qtd->length = count;
-
-	return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh, struct fusbh200_qtd *qtd)
-{
-	struct fusbh200_qh_hw *hw = qh->hw;
-
-	/* writes to an active overlay are unsafe */
-	BUG_ON(qh->qh_state != QH_STATE_IDLE);
-
-	hw->hw_qtd_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-	hw->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-
-	/* Except for control endpoints, we make hardware maintain data
-	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
-	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
-	 * ever clear it.
-	 */
-	if (!(hw->hw_info1 & cpu_to_hc32(fusbh200, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
-
-		is_out = qh->is_out;
-		epnum = (hc32_to_cpup(fusbh200, &hw->hw_info1) >> 8) & 0x0f;
-		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
-			hw->hw_token &= ~cpu_to_hc32(fusbh200, QTD_TOGGLE);
-			usb_settoggle (qh->dev, epnum, is_out, 1);
-		}
-	}
-
-	hw->hw_token &= cpu_to_hc32(fusbh200, QTD_TOGGLE | QTD_STS_PING);
-}
-
-/* if it weren't for a common silicon quirk (writing the dummy into the qh
- * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
- * recovery (including urb dequeue) would need software changes to a QH...
- */
-static void
-qh_refresh (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qtd *qtd;
-
-	if (list_empty (&qh->qtd_list))
-		qtd = qh->dummy;
-	else {
-		qtd = list_entry (qh->qtd_list.next,
-				struct fusbh200_qtd, qtd_list);
-		/*
-		 * first qtd may already be partially processed.
-		 * If we come here during unlink, the QH overlay region
-		 * might have reference to the just unlinked qtd. The
-		 * qtd is updated in qh_completions(). Update the QH
-		 * overlay here.
-		 */
-		if (cpu_to_hc32(fusbh200, qtd->qtd_dma) == qh->hw->hw_current) {
-			qh->hw->hw_qtd_next = qtd->hw_next;
-			qtd = NULL;
-		}
-	}
-
-	if (qtd)
-		qh_update (fusbh200, qh, qtd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void qh_link_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-static void fusbh200_clear_tt_buffer_complete(struct usb_hcd *hcd,
-		struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	struct fusbh200_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-	qh->clearing_tt = 0;
-	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-			&& fusbh200->rh_state == FUSBH200_RH_RUNNING)
-		qh_link_async(fusbh200, qh);
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-}
-
-static void fusbh200_clear_tt_buffer(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh,
-		struct urb *urb, u32 token)
-{
-
-	/* If an async split transaction gets an error or is unlinked,
-	 * the TT buffer may be left in an indeterminate state.  We
-	 * have to clear the TT buffer.
-	 *
-	 * Note: this routine is never called for Isochronous transfers.
-	 */
-	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
-		struct usb_device *tt = urb->dev->tt->hub;
-
-		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
-
-		if (urb->dev->tt->hub !=
-		    fusbh200_to_hcd(fusbh200)->self.root_hub) {
-			if (usb_hub_clear_tt_buffer(urb) == 0)
-				qh->clearing_tt = 1;
-		}
-	}
-}
-
-static int qtd_copy_status (
-	struct fusbh200_hcd *fusbh200,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
-{
-	int	status = -EINPROGRESS;
-
-	/* count IN/OUT bytes, not SETUP (even short packets) */
-	if (likely (QTD_PID (token) != 2))
-		urb->actual_length += length - QTD_LENGTH (token);
-
-	/* don't modify error codes */
-	if (unlikely(urb->unlinked))
-		return status;
-
-	/* force cleanup after short read; not always an error */
-	if (unlikely (IS_SHORT_READ (token)))
-		status = -EREMOTEIO;
-
-	/* serious "can't proceed" faults reported by the hardware */
-	if (token & QTD_STS_HALT) {
-		if (token & QTD_STS_BABBLE) {
-			/* FIXME "must" disable babbling device's port too */
-			status = -EOVERFLOW;
-		/* CERR nonzero + halt --> stall */
-		} else if (QTD_CERR(token)) {
-			status = -EPIPE;
-
-		/* In theory, more than one of the following bits can be set
-		 * since they are sticky and the transaction is retried.
-		 * Which to test first is rather arbitrary.
-		 */
-		} else if (token & QTD_STS_MMF) {
-			/* fs/ls interrupt xfer missed the complete-split */
-			status = -EPROTO;
-		} else if (token & QTD_STS_DBE) {
-			status = (QTD_PID (token) == 1) /* IN ? */
-				? -ENOSR  /* hc couldn't read data */
-				: -ECOMM; /* hc couldn't write data */
-		} else if (token & QTD_STS_XACT) {
-			/* timeout, bad CRC, wrong PID, etc */
-			fusbh200_dbg(fusbh200, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
-			status = -EPROTO;
-		} else {	/* unknown */
-			status = -EPROTO;
-		}
-
-		fusbh200_dbg(fusbh200,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice (urb->pipe),
-			usb_pipeendpoint (urb->pipe),
-			usb_pipein (urb->pipe) ? "in" : "out",
-			token, status);
-	}
-
-	return status;
-}
-
-static void
-fusbh200_urb_done(struct fusbh200_hcd *fusbh200, struct urb *urb, int status)
-__releases(fusbh200->lock)
-__acquires(fusbh200->lock)
-{
-	if (likely (urb->hcpriv != NULL)) {
-		struct fusbh200_qh	*qh = (struct fusbh200_qh *) urb->hcpriv;
-
-		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw->hw_info2 & cpu_to_hc32(fusbh200, QH_SMASK)) != 0) {
-
-			/* ... update hc-wide periodic stats (for usbfs) */
-			fusbh200_to_hcd(fusbh200)->self.bandwidth_int_reqs--;
-		}
-	}
-
-	if (unlikely(urb->unlinked)) {
-		COUNT(fusbh200->stats.unlink);
-	} else {
-		/* report non-error and short read status as zero */
-		if (status == -EINPROGRESS || status == -EREMOTEIO)
-			status = 0;
-		COUNT(fusbh200->stats.complete);
-	}
-
-#ifdef FUSBH200_URB_TRACE
-	fusbh200_dbg (fusbh200,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
-#endif
-
-	/* complete() can reenter this HCD */
-	usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-	spin_unlock (&fusbh200->lock);
-	usb_hcd_giveback_urb(fusbh200_to_hcd(fusbh200), urb, status);
-	spin_lock (&fusbh200->lock);
-}
-
-static int qh_schedule (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
- * Chases up to qh->hw_current.  Returns number of completions called,
- * indicating how much "real" work we did.
- */
-static unsigned
-qh_completions (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	if (unlikely (list_empty (&qh->qtd_list)))
-		return count;
-
-	/* completions (or tasks on other cpus) must never clobber HALT
-	 * till we've gone through and cleaned everything up, even when
-	 * they add urbs to this qh's queue or mark them for unlinking.
-	 *
-	 * NOTE:  unlinking expects to be done in queue order.
-	 *
-	 * It's a bug for qh->qh_state to be anything other than
-	 * QH_STATE_IDLE, unless our caller is scan_async() or
-	 * scan_intr().
-	 */
-	state = qh->qh_state;
-	qh->qh_state = QH_STATE_COMPLETING;
-	stopped = (state == QH_STATE_IDLE);
-
- rescan:
-	last = NULL;
-	last_status = -EINPROGRESS;
-	qh->needs_rescan = 0;
-
-	/* remove de-activated QTDs from front of queue.
-	 * after faults (including short reads), cleanup this urb
-	 * then let the queue advance.
-	 * if queue is stopped, handles unlinks.
-	 */
-	list_for_each_safe (entry, tmp, &qh->qtd_list) {
-		struct fusbh200_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
-
-		qtd = list_entry (entry, struct fusbh200_qtd, qtd_list);
-		urb = qtd->urb;
-
-		/* clean up any state from previous QTD ...*/
-		if (last) {
-			if (likely (last->urb != urb)) {
-				fusbh200_urb_done(fusbh200, last->urb, last_status);
-				count++;
-				last_status = -EINPROGRESS;
-			}
-			fusbh200_qtd_free (fusbh200, last);
-			last = NULL;
-		}
-
-		/* ignore urbs submitted during completions we reported */
-		if (qtd == end)
-			break;
-
-		/* hardware copies qtd out of qh overlay */
-		rmb ();
-		token = hc32_to_cpu(fusbh200, qtd->hw_token);
-
-		/* always clean up qtds the hc de-activated */
- retry_xacterr:
-		if ((token & QTD_STS_ACTIVE) == 0) {
-
-			/* Report Data Buffer Error: non-fatal but useful */
-			if (token & QTD_STS_DBE)
-				fusbh200_dbg(fusbh200,
-					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
-					usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
-
-			/* on STALL, error, and short reads this urb must
-			 * complete and all its qtds must be recycled.
-			 */
-			if ((token & QTD_STS_HALT) != 0) {
-
-				/* retry transaction errors until we
-				 * reach the software xacterr limit
-				 */
-				if ((token & QTD_STS_XACT) &&
-						QTD_CERR(token) == 0 &&
-						++qh->xacterrs < QH_XACTERR_MAX &&
-						!urb->unlinked) {
-					fusbh200_dbg(fusbh200,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
-
-					/* reset the token in the qtd and the
-					 * qh overlay (which still contains
-					 * the qtd) so that we pick up from
-					 * where we left off
-					 */
-					token &= ~QTD_STS_HALT;
-					token |= QTD_STS_ACTIVE |
-							(FUSBH200_TUNE_CERR << 10);
-					qtd->hw_token = cpu_to_hc32(fusbh200,
-							token);
-					wmb();
-					hw->hw_token = cpu_to_hc32(fusbh200,
-							token);
-					goto retry_xacterr;
-				}
-				stopped = 1;
-
-			/* magic dummy for some short reads; qh won't advance.
-			 * that silicon quirk can kick in with this dummy too.
-			 *
-			 * other short reads won't stop the queue, including
-			 * control transfers (status stage handles that) or
-			 * most other single-qtd reads ... the queue stops if
-			 * URB_SHORT_NOT_OK was set so the driver submitting
-			 * the urbs could clean it up.
-			 */
-			} else if (IS_SHORT_READ (token)
-					&& !(qtd->hw_alt_next
-						& FUSBH200_LIST_END(fusbh200))) {
-				stopped = 1;
-			}
-
-		/* stop scanning when we reach qtds the hc is using */
-		} else if (likely (!stopped
-				&& fusbh200->rh_state >= FUSBH200_RH_RUNNING)) {
-			break;
-
-		/* scan the whole queue for unlinks whenever it stops */
-		} else {
-			stopped = 1;
-
-			/* cancel everything if we halt, suspend, etc */
-			if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-				last_status = -ESHUTDOWN;
-
-			/* this qtd is active; skip it unless a previous qtd
-			 * for its urb faulted, or its urb was canceled.
-			 */
-			else if (last_status == -EINPROGRESS && !urb->unlinked)
-				continue;
-
-			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fusbh200, qtd->qtd_dma)
-						== hw->hw_current) {
-				token = hc32_to_cpu(fusbh200, hw->hw_token);
-
-				/* An unlink may leave an incomplete
-				 * async transaction in the TT buffer.
-				 * We have to clear it.
-				 */
-				fusbh200_clear_tt_buffer(fusbh200, qh, urb, token);
-			}
-		}
-
-		/* unless we already know the urb's status, collect qtd status
-		 * and update count of bytes transferred.  in common short read
-		 * cases with only one data qtd (including control transfers),
-		 * queue processing won't halt.  but with two or more qtds (for
-		 * example, with a 32 KB transfer), when the first qtd gets a
-		 * short read the second must be removed by hand.
-		 */
-		if (last_status == -EINPROGRESS) {
-			last_status = qtd_copy_status(fusbh200, urb,
-					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FUSBH200_LIST_END(fusbh200)))
-				last_status = -EINPROGRESS;
-
-			/* As part of low/full-speed endpoint-halt processing
-			 * we must clear the TT buffer (11.17.5).
-			 */
-			if (unlikely(last_status != -EINPROGRESS &&
-					last_status != -EREMOTEIO)) {
-				/* The TT's in some hubs malfunction when they
-				 * receive this request following a STALL (they
-				 * stop sending isochronous packets).  Since a
-				 * STALL can't leave the TT buffer in a busy
-				 * state (if you believe Figures 11-48 - 11-51
-				 * in the USB 2.0 spec), we won't clear the TT
-				 * buffer in this case.  Strictly speaking this
-				 * is a violation of the spec.
-				 */
-				if (last_status != -EPIPE)
-					fusbh200_clear_tt_buffer(fusbh200, qh, urb,
-							token);
-			}
-		}
-
-		/* if we're removing something not at the queue head,
-		 * patch the hardware queue pointer.
-		 */
-		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
-			last = list_entry (qtd->qtd_list.prev,
-					struct fusbh200_qtd, qtd_list);
-			last->hw_next = qtd->hw_next;
-		}
-
-		/* remove qtd; it's recycled after possible urb completion */
-		list_del (&qtd->qtd_list);
-		last = qtd;
-
-		/* reinit the xacterr counter for the next qtd */
-		qh->xacterrs = 0;
-	}
-
-	/* last urb's completion might still need calling */
-	if (likely (last != NULL)) {
-		fusbh200_urb_done(fusbh200, last->urb, last_status);
-		count++;
-		fusbh200_qtd_free (fusbh200, last);
-	}
-
-	/* Do we need to rescan for URBs dequeued during a giveback? */
-	if (unlikely(qh->needs_rescan)) {
-		/* If the QH is already unlinked, do the rescan now. */
-		if (state == QH_STATE_IDLE)
-			goto rescan;
-
-		/* Otherwise we have to wait until the QH is fully unlinked.
-		 * Our caller will start an unlink if qh->needs_rescan is
-		 * set.  But if an unlink has already started, nothing needs
-		 * to be done.
-		 */
-		if (state != QH_STATE_LINKED)
-			qh->needs_rescan = 0;
-	}
-
-	/* restore original state; caller must unlink or relink */
-	qh->qh_state = state;
-
-	/* be sure the hardware's done with the qh before refreshing
-	 * it after fault cleanup, or recovering from silicon wrongly
-	 * overlaying the dummy qtd (which reduces DMA chatter).
-	 */
-	if (stopped != 0 || hw->hw_qtd_next == FUSBH200_LIST_END(fusbh200)) {
-		switch (state) {
-		case QH_STATE_IDLE:
-			qh_refresh(fusbh200, qh);
-			break;
-		case QH_STATE_LINKED:
-			/* We won't refresh a QH that's linked (after the HC
-			 * stopped the queue).  That avoids a race:
-			 *  - HC reads first part of QH;
-			 *  - CPU updates that first part and the token;
-			 *  - HC reads rest of that QH, including token
-			 * Result:  HC gets an inconsistent image, and then
-			 * DMAs to/from the wrong memory (corrupting it).
-			 *
-			 * That should be rare for interrupt transfers,
-			 * except maybe high bandwidth ...
-			 */
-
-			/* Tell the caller to start an unlink */
-			qh->needs_rescan = 1;
-			break;
-		/* otherwise, unlink already started */
-		}
-	}
-
-	return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-// ... and packet size, for any kind of endpoint descriptor
-#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
-
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
- * used for cleanup after errors, before HC sees an URB's TDs.
- */
-static void qtd_list_free (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
-
-	list_for_each_safe (entry, temp, qtd_list) {
-		struct fusbh200_qtd	*qtd;
-
-		qtd = list_entry (entry, struct fusbh200_qtd, qtd_list);
-		list_del (&qtd->qtd_list);
-		fusbh200_qtd_free (fusbh200, qtd);
-	}
-}
-
-/*
- * create a list of filled qtds for this URB; won't link into qh.
- */
-static struct list_head *
-qh_urb_transaction (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fusbh200_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
-
-	/*
-	 * URBs map to sequences of QTDs:  one logical transaction
-	 */
-	qtd = fusbh200_qtd_alloc (fusbh200, flags);
-	if (unlikely (!qtd))
-		return NULL;
-	list_add_tail (&qtd->qtd_list, head);
-	qtd->urb = urb;
-
-	token = QTD_STS_ACTIVE;
-	token |= (FUSBH200_TUNE_CERR << 10);
-	/* for split transactions, SplitXState initialized to zero */
-
-	len = urb->transfer_buffer_length;
-	is_input = usb_pipein (urb->pipe);
-	if (usb_pipecontrol (urb->pipe)) {
-		/* SETUP pid */
-		qtd_fill(fusbh200, qtd, urb->setup_dma,
-				sizeof (struct usb_ctrlrequest),
-				token | (2 /* "setup" */ << 8), 8);
-
-		/* ... and always at least one more pid */
-		token ^= QTD_TOGGLE;
-		qtd_prev = qtd;
-		qtd = fusbh200_qtd_alloc (fusbh200, flags);
-		if (unlikely (!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-		list_add_tail (&qtd->qtd_list, head);
-
-		/* for zero length DATA stages, STATUS is always IN */
-		if (len == 0)
-			token |= (1 /* "in" */ << 8);
-	}
-
-	/*
-	 * data transfer stage:  buffer setup
-	 */
-	i = urb->num_mapped_sgs;
-	if (len > 0 && i > 0) {
-		sg = urb->sg;
-		buf = sg_dma_address(sg);
-
-		/* urb->transfer_buffer_length may be smaller than the
-		 * size of the scatterlist (or vice versa)
-		 */
-		this_sg_len = min_t(int, sg_dma_len(sg), len);
-	} else {
-		sg = NULL;
-		buf = urb->transfer_dma;
-		this_sg_len = len;
-	}
-
-	if (is_input)
-		token |= (1 /* "in" */ << 8);
-	/* else it's already initted to "out" pid (0 << 8) */
-
-	maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
-
-	/*
-	 * buffer gets wrapped in one or more qtds;
-	 * last one may be "short" (including zero len)
-	 * and may serve as a control status ack
-	 */
-	for (;;) {
-		int this_qtd_len;
-
-		this_qtd_len = qtd_fill(fusbh200, qtd, buf, this_sg_len, token,
-				maxpacket);
-		this_sg_len -= this_qtd_len;
-		len -= this_qtd_len;
-		buf += this_qtd_len;
-
-		/*
-		 * short reads advance to a "magic" dummy instead of the next
-		 * qtd ... that forces the queue to stop, for manual cleanup.
-		 * (this will usually be overridden later.)
-		 */
-		if (is_input)
-			qtd->hw_alt_next = fusbh200->async->hw->hw_alt_next;
-
-		/* qh makes control packets use qtd toggle; maybe switch it */
-		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
-			token ^= QTD_TOGGLE;
-
-		if (likely(this_sg_len <= 0)) {
-			if (--i <= 0 || len <= 0)
-				break;
-			sg = sg_next(sg);
-			buf = sg_dma_address(sg);
-			this_sg_len = min_t(int, sg_dma_len(sg), len);
-		}
-
-		qtd_prev = qtd;
-		qtd = fusbh200_qtd_alloc (fusbh200, flags);
-		if (unlikely (!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-		list_add_tail (&qtd->qtd_list, head);
-	}
-
-	/*
-	 * unless the caller requires manual cleanup after short reads,
-	 * have the alt_next mechanism keep the queue running after the
-	 * last data qtd (the only one, for control and most other cases).
-	 */
-	if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol (urb->pipe)))
-		qtd->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-
-	/*
-	 * control requests may need a terminating data "status" ack;
-	 * other OUT ones may need a terminating short packet
-	 * (zero length).
-	 */
-	if (likely (urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
-
-		if (usb_pipecontrol (urb->pipe)) {
-			one_more = 1;
-			token ^= 0x0100;	/* "in" <--> "out"  */
-			token |= QTD_TOGGLE;	/* force DATA1 */
-		} else if (usb_pipeout(urb->pipe)
-				&& (urb->transfer_flags & URB_ZERO_PACKET)
-				&& !(urb->transfer_buffer_length % maxpacket)) {
-			one_more = 1;
-		}
-		if (one_more) {
-			qtd_prev = qtd;
-			qtd = fusbh200_qtd_alloc (fusbh200, flags);
-			if (unlikely (!qtd))
-				goto cleanup;
-			qtd->urb = urb;
-			qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-			list_add_tail (&qtd->qtd_list, head);
-
-			/* never any data in such packets */
-			qtd_fill(fusbh200, qtd, 0, 0, token, 0);
-		}
-	}
-
-	/* by default, enable interrupt on urb completion */
-	if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
-		qtd->hw_token |= cpu_to_hc32(fusbh200, QTD_IOC);
-	return head;
-
-cleanup:
-	qtd_list_free (fusbh200, urb, head);
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// Would be best to create all qh's from config descriptors,
-// when each interface/altsetting is established.  Unlink
-// any previous qh and cancel its urbs first; endpoints are
-// implicitly reset then (data toggle too).
-// That'd mean updating how usbcore talks to HCDs. (2.7?)
-
-
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
- *
- * For interrupt urbs, the scheduler must set the microframe scheduling
- * mask(s) each time the QH gets scheduled.  For highspeed, that's
- * just one microframe in the s-mask.  For split interrupt transactions
- * there are additional complications: c-mask, maybe FSTNs.
- */
-static struct fusbh200_qh *
-qh_make (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fusbh200_qh		*qh = fusbh200_qh_alloc (fusbh200, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fusbh200_qh_hw	*hw;
-
-	if (!qh)
-		return qh;
-
-	/*
-	 * init endpoint/device data for this QH
-	 */
-	info1 |= usb_pipeendpoint (urb->pipe) << 8;
-	info1 |= usb_pipedevice (urb->pipe) << 0;
-
-	is_input = usb_pipein (urb->pipe);
-	type = usb_pipetype (urb->pipe);
-	maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
-
-	/* 1024 byte maxpacket is a hardware ceiling.  High bandwidth
-	 * acts like up to 3KB, but is built from smaller packets.
-	 */
-	if (max_packet(maxp) > 1024) {
-		fusbh200_dbg(fusbh200, "bogus qh maxpacket %d\n", max_packet(maxp));
-		goto done;
-	}
-
-	/* Compute interrupt scheduling parameters just once, and save.
-	 * - allowing for high bandwidth, how many nsec/uframe are used?
-	 * - split transactions need a second CSPLIT uframe; same question
-	 * - splits also need a schedule gap (for full/low speed I/O)
-	 * - qh has a polling interval
-	 *
-	 * For control/bulk requests, the HC or TT handles these.
-	 */
-	if (type == PIPE_INTERRUPT) {
-		qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
-				is_input, 0,
-				hb_mult(maxp) * max_packet(maxp)));
-		qh->start = NO_FRAME;
-
-		if (urb->dev->speed == USB_SPEED_HIGH) {
-			qh->c_usecs = 0;
-			qh->gap_uf = 0;
-
-			qh->period = urb->interval >> 3;
-			if (qh->period == 0 && urb->interval != 1) {
-				/* NOTE interval 2 or 4 uframes could work.
-				 * But interval 1 scheduling is simpler, and
-				 * includes high bandwidth.
-				 */
-				urb->interval = 1;
-			} else if (qh->period > fusbh200->periodic_size) {
-				qh->period = fusbh200->periodic_size;
-				urb->interval = qh->period << 3;
-			}
-		} else {
-			int		think_time;
-
-			/* gap is f(FS/LS transfer times) */
-			qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
-					is_input, 0, maxp) / (125 * 1000);
-
-			/* FIXME this just approximates SPLIT/CSPLIT times */
-			if (is_input) {		// SPLIT, gap, CSPLIT+DATA
-				qh->c_usecs = qh->usecs + HS_USECS (0);
-				qh->usecs = HS_USECS (1);
-			} else {		// SPLIT+DATA, gap, CSPLIT
-				qh->usecs += HS_USECS (1);
-				qh->c_usecs = HS_USECS (0);
-			}
-
-			think_time = tt ? tt->think_time : 0;
-			qh->tt_usecs = NS_TO_US (think_time +
-					usb_calc_bus_time (urb->dev->speed,
-					is_input, 0, max_packet (maxp)));
-			qh->period = urb->interval;
-			if (qh->period > fusbh200->periodic_size) {
-				qh->period = fusbh200->periodic_size;
-				urb->interval = qh->period;
-			}
-		}
-	}
-
-	/* support for tt scheduling, and access to toggles */
-	qh->dev = urb->dev;
-
-	/* using TT? */
-	switch (urb->dev->speed) {
-	case USB_SPEED_LOW:
-		info1 |= QH_LOW_SPEED;
-		/* FALL THROUGH */
-
-	case USB_SPEED_FULL:
-		/* EPS 0 means "full" */
-		if (type != PIPE_INTERRUPT)
-			info1 |= (FUSBH200_TUNE_RL_TT << 28);
-		if (type == PIPE_CONTROL) {
-			info1 |= QH_CONTROL_EP;		/* for TT */
-			info1 |= QH_TOGGLE_CTL;		/* toggle from qtd */
-		}
-		info1 |= maxp << 16;
-
-		info2 |= (FUSBH200_TUNE_MULT_TT << 30);
-
-		/* Some Freescale processors have an erratum in which the
-		 * port number in the queue head was 0..N-1 instead of 1..N.
-		 */
-		if (fusbh200_has_fsl_portno_bug(fusbh200))
-			info2 |= (urb->dev->ttport-1) << 23;
-		else
-			info2 |= urb->dev->ttport << 23;
-
-		/* set the address of the TT; for TDI's integrated
-		 * root hub tt, leave it zeroed.
-		 */
-		if (tt && tt->hub != fusbh200_to_hcd(fusbh200)->self.root_hub)
-			info2 |= tt->hub->devnum << 16;
-
-		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
-
-		break;
-
-	case USB_SPEED_HIGH:		/* no TT involved */
-		info1 |= QH_HIGH_SPEED;
-		if (type == PIPE_CONTROL) {
-			info1 |= (FUSBH200_TUNE_RL_HS << 28);
-			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
-			info1 |= QH_TOGGLE_CTL;	/* toggle from qtd */
-			info2 |= (FUSBH200_TUNE_MULT_HS << 30);
-		} else if (type == PIPE_BULK) {
-			info1 |= (FUSBH200_TUNE_RL_HS << 28);
-			/* The USB spec says that high speed bulk endpoints
-			 * always use 512 byte maxpacket.  But some device
-			 * vendors decided to ignore that, and MSFT is happy
-			 * to help them do so.  So now people expect to use
-			 * such nonconformant devices with Linux too; sigh.
-			 */
-			info1 |= max_packet(maxp) << 16;
-			info2 |= (FUSBH200_TUNE_MULT_HS << 30);
-		} else {		/* PIPE_INTERRUPT */
-			info1 |= max_packet (maxp) << 16;
-			info2 |= hb_mult (maxp) << 30;
-		}
-		break;
-	default:
-		fusbh200_dbg(fusbh200, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
-done:
-		qh_destroy(fusbh200, qh);
-		return NULL;
-	}
-
-	/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets s-mask } */
-
-	/* init as live, toggle clear, advance to dummy */
-	qh->qh_state = QH_STATE_IDLE;
-	hw = qh->hw;
-	hw->hw_info1 = cpu_to_hc32(fusbh200, info1);
-	hw->hw_info2 = cpu_to_hc32(fusbh200, info2);
-	qh->is_out = !is_input;
-	usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
-	qh_refresh (fusbh200, qh);
-	return qh;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void enable_async(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->async_count++)
-		return;
-
-	/* Stop waiting to turn off the async schedule */
-	fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_DISABLE_ASYNC);
-
-	/* Don't start the schedule until ASS is 0 */
-	fusbh200_poll_ASS(fusbh200);
-	turn_on_io_watchdog(fusbh200);
-}
-
-static void disable_async(struct fusbh200_hcd *fusbh200)
-{
-	if (--fusbh200->async_count)
-		return;
-
-	/* The async schedule and async_unlink list are supposed to be empty */
-	WARN_ON(fusbh200->async->qh_next.qh || fusbh200->async_unlink);
-
-	/* Don't turn off the schedule until ASS is 1 */
-	fusbh200_poll_ASS(fusbh200);
-}
-
-/* move qh (and its qtds) onto async queue; maybe enable queue.  */
-
-static void qh_link_async (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	__hc32		dma = QH_NEXT(fusbh200, qh->qh_dma);
-	struct fusbh200_qh	*head;
-
-	/* Don't link a QH if there's a Clear-TT-Buffer pending */
-	if (unlikely(qh->clearing_tt))
-		return;
-
-	WARN_ON(qh->qh_state != QH_STATE_IDLE);
-
-	/* clear halt and/or toggle; and maybe recover from silicon quirk */
-	qh_refresh(fusbh200, qh);
-
-	/* splice right after start */
-	head = fusbh200->async;
-	qh->qh_next = head->qh_next;
-	qh->hw->hw_next = head->hw->hw_next;
-	wmb ();
-
-	head->qh_next.qh = qh;
-	head->hw->hw_next = dma;
-
-	qh->xacterrs = 0;
-	qh->qh_state = QH_STATE_LINKED;
-	/* qtd completions reported later by interrupt */
-
-	enable_async(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
- * Allocates and initializes the QH if necessary.
- * Returns null if it can't allocate a QH it needs to.
- * If the QH has TDs (urbs) already, that's great.
- */
-static struct fusbh200_qh *qh_append_tds (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
-{
-	struct fusbh200_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fusbh200, 0x7f);
-
-	qh = (struct fusbh200_qh *) *ptr;
-	if (unlikely (qh == NULL)) {
-		/* can't sleep here, we have fusbh200->lock... */
-		qh = qh_make (fusbh200, urb, GFP_ATOMIC);
-		*ptr = qh;
-	}
-	if (likely (qh != NULL)) {
-		struct fusbh200_qtd	*qtd;
-
-		if (unlikely (list_empty (qtd_list)))
-			qtd = NULL;
-		else
-			qtd = list_entry (qtd_list->next, struct fusbh200_qtd,
-					qtd_list);
-
-		/* control qh may need patching ... */
-		if (unlikely (epnum == 0)) {
-
-                        /* usb_reset_device() briefly reverts to address 0 */
-                        if (usb_pipedevice (urb->pipe) == 0)
-				qh->hw->hw_info1 &= ~qh_addr_mask;
-		}
-
-		/* just one way to queue requests: swap with the dummy qtd.
-		 * only hc or qh_refresh() ever modify the overlay.
-		 */
-		if (likely (qtd != NULL)) {
-			struct fusbh200_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
-
-			/* to avoid racing the HC, use the dummy td instead of
-			 * the first td of our list (becomes new dummy).  both
-			 * tds stay deactivated until we're done, when the
-			 * HC is allowed to fetch the old dummy (4.10.2).
-			 */
-			token = qtd->hw_token;
-			qtd->hw_token = HALT_BIT(fusbh200);
-
-			dummy = qh->dummy;
-
-			dma = dummy->qtd_dma;
-			*dummy = *qtd;
-			dummy->qtd_dma = dma;
-
-			list_del (&qtd->qtd_list);
-			list_add (&dummy->qtd_list, qtd_list);
-			list_splice_tail(qtd_list, &qh->qtd_list);
-
-			fusbh200_qtd_init(fusbh200, qtd, qtd->qtd_dma);
-			qh->dummy = qtd;
-
-			/* hc must see the new dummy at list end */
-			dma = qtd->qtd_dma;
-			qtd = list_entry (qh->qtd_list.prev,
-					struct fusbh200_qtd, qtd_list);
-			qtd->hw_next = QTD_NEXT(fusbh200, dma);
-
-			/* let the hc process these next qtds */
-			wmb ();
-			dummy->hw_token = token;
-
-			urb->hcpriv = qh;
-		}
-	}
-	return qh;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fusbh200_qh		*qh = NULL;
-	int			rc;
-
-	epnum = urb->ep->desc.bEndpointAddress;
-
-#ifdef FUSBH200_URB_TRACE
-	{
-		struct fusbh200_qtd *qtd;
-		qtd = list_entry(qtd_list->next, struct fusbh200_qtd, qtd_list);
-		fusbh200_dbg(fusbh200,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
-	}
-#endif
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		rc = -ESHUTDOWN;
-		goto done;
-	}
-	rc = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(rc))
-		goto done;
-
-	qh = qh_append_tds(fusbh200, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	if (unlikely(qh == NULL)) {
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-		rc = -ENOMEM;
-		goto done;
-	}
-
-	/* Control/bulk operations through TTs don't need scheduling,
-	 * the HC and TT handle it when the TT has a buffer ready.
-	 */
-	if (likely (qh->qh_state == QH_STATE_IDLE))
-		qh_link_async(fusbh200, qh);
- done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	if (unlikely (qh == NULL))
-		qtd_list_free (fusbh200, urb, qtd_list);
-	return rc;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void single_unlink_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh		*prev;
-
-	/* Add to the end of the list of QHs waiting for the next IAAD */
-	qh->qh_state = QH_STATE_UNLINK;
-	if (fusbh200->async_unlink)
-		fusbh200->async_unlink_last->unlink_next = qh;
-	else
-		fusbh200->async_unlink = qh;
-	fusbh200->async_unlink_last = qh;
-
-	/* Unlink it from the schedule */
-	prev = fusbh200->async;
-	while (prev->qh_next.qh != qh)
-		prev = prev->qh_next.qh;
-
-	prev->hw->hw_next = qh->hw->hw_next;
-	prev->qh_next = qh->qh_next;
-	if (fusbh200->qh_scan_next == qh)
-		fusbh200->qh_scan_next = qh->qh_next.qh;
-}
-
-static void start_iaa_cycle(struct fusbh200_hcd *fusbh200, bool nested)
-{
-	/*
-	 * Do nothing if an IAA cycle is already running or
-	 * if one will be started shortly.
-	 */
-	if (fusbh200->async_iaa || fusbh200->async_unlinking)
-		return;
-
-	/* Do all the waiting QHs at once */
-	fusbh200->async_iaa = fusbh200->async_unlink;
-	fusbh200->async_unlink = NULL;
-
-	/* If the controller isn't running, we don't have to wait for it */
-	if (unlikely(fusbh200->rh_state < FUSBH200_RH_RUNNING)) {
-		if (!nested)		/* Avoid recursion */
-			end_unlink_async(fusbh200);
-
-	/* Otherwise start a new IAA cycle */
-	} else if (likely(fusbh200->rh_state == FUSBH200_RH_RUNNING)) {
-		/* Make sure the unlinks are all visible to the hardware */
-		wmb();
-
-		fusbh200_writel(fusbh200, fusbh200->command | CMD_IAAD,
-				&fusbh200->regs->command);
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_IAA_WATCHDOG, true);
-	}
-}
-
-/* the async qh for the qtds being unlinked are now gone from the HC */
-
-static void end_unlink_async(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-
-	/* Process the idle QHs */
- restart:
-	fusbh200->async_unlinking = true;
-	while (fusbh200->async_iaa) {
-		qh = fusbh200->async_iaa;
-		fusbh200->async_iaa = qh->unlink_next;
-		qh->unlink_next = NULL;
-
-		qh->qh_state = QH_STATE_IDLE;
-		qh->qh_next.qh = NULL;
-
-		qh_completions(fusbh200, qh);
-		if (!list_empty(&qh->qtd_list) &&
-				fusbh200->rh_state == FUSBH200_RH_RUNNING)
-			qh_link_async(fusbh200, qh);
-		disable_async(fusbh200);
-	}
-	fusbh200->async_unlinking = false;
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fusbh200->async_unlink) {
-		start_iaa_cycle(fusbh200, true);
-		if (unlikely(fusbh200->rh_state < FUSBH200_RH_RUNNING))
-			goto restart;
-	}
-}
-
-static void unlink_empty_async(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh, *next;
-	bool			stopped = (fusbh200->rh_state < FUSBH200_RH_RUNNING);
-	bool			check_unlinks_later = false;
-
-	/* Unlink all the async QHs that have been empty for a timer cycle */
-	next = fusbh200->async->qh_next.qh;
-	while (next) {
-		qh = next;
-		next = qh->qh_next.qh;
-
-		if (list_empty(&qh->qtd_list) &&
-				qh->qh_state == QH_STATE_LINKED) {
-			if (!stopped && qh->unlink_cycle ==
-					fusbh200->async_unlink_cycle)
-				check_unlinks_later = true;
-			else
-				single_unlink_async(fusbh200, qh);
-		}
-	}
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fusbh200->async_unlink)
-		start_iaa_cycle(fusbh200, false);
-
-	/* QHs that haven't been empty for long enough will be handled later */
-	if (check_unlinks_later) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_ASYNC_UNLINKS, true);
-		++fusbh200->async_unlink_cycle;
-	}
-}
-
-/* makes sure the async qh will become idle */
-/* caller must own fusbh200->lock */
-
-static void start_unlink_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/*
-	 * If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	single_unlink_async(fusbh200, qh);
-	start_iaa_cycle(fusbh200, false);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void scan_async (struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-	bool			check_unlinks_later = false;
-
-	fusbh200->qh_scan_next = fusbh200->async->qh_next.qh;
-	while (fusbh200->qh_scan_next) {
-		qh = fusbh200->qh_scan_next;
-		fusbh200->qh_scan_next = qh->qh_next.qh;
- rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fusbh200->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fusbh200->qh_scan_next is adjusted
-			 * in single_unlink_async().
-			 */
-			temp = qh_completions(fusbh200, qh);
-			if (qh->needs_rescan) {
-				start_unlink_async(fusbh200, qh);
-			} else if (list_empty(&qh->qtd_list)
-					&& qh->qh_state == QH_STATE_LINKED) {
-				qh->unlink_cycle = fusbh200->async_unlink_cycle;
-				check_unlinks_later = true;
-			} else if (temp != 0)
-				goto rescan;
-		}
-	}
-
-	/*
-	 * Unlink empty entries, reducing DMA usage as well
-	 * as HCD schedule-scanning costs.  Delay for any qh
-	 * we just scanned, there's a not-unusual case that it
-	 * doesn't stay idle for long.
-	 */
-	if (check_unlinks_later && fusbh200->rh_state == FUSBH200_RH_RUNNING &&
-			!(fusbh200->enabled_hrtimer_events &
-				BIT(FUSBH200_HRTIMER_ASYNC_UNLINKS))) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_ASYNC_UNLINKS, true);
-		++fusbh200->async_unlink_cycle;
-	}
-}
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
- * These are called "periodic" transactions in the EHCI spec.
- *
- * Note that for interrupt transfers, the QH/QTD manipulation is shared
- * with the "asynchronous" transaction support (control/bulk transfers).
- * The only real difference is in how interrupt transfers are scheduled.
- *
- * For ISO, we make an "iso_stream" head to serve the same role as a QH.
- * It keeps track of every ITD (or SITD) that's linked, and holds enough
- * pre-calculated schedule data to make appending to the queue be quick.
- */
-
-static int fusbh200_get_frame (struct usb_hcd *hcd);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
- * @periodic: host pointer to qh/itd
- * @tag: hardware tag for type of this record
- */
-static union fusbh200_shadow *
-periodic_next_shadow(struct fusbh200_hcd *fusbh200, union fusbh200_shadow *periodic,
-		__hc32 tag)
-{
-	switch (hc32_to_cpu(fusbh200, tag)) {
-	case Q_TYPE_QH:
-		return &periodic->qh->qh_next;
-	case Q_TYPE_FSTN:
-		return &periodic->fstn->fstn_next;
-	default:
-		return &periodic->itd->itd_next;
-	}
-}
-
-static __hc32 *
-shadow_next_periodic(struct fusbh200_hcd *fusbh200, union fusbh200_shadow *periodic,
-		__hc32 tag)
-{
-	switch (hc32_to_cpu(fusbh200, tag)) {
-	/* our fusbh200_shadow.qh is actually software part */
-	case Q_TYPE_QH:
-		return &periodic->qh->hw->hw_next;
-	/* others are hw parts */
-	default:
-		return periodic->hw_next;
-	}
-}
-
-/* caller must hold fusbh200->lock */
-static void periodic_unlink (struct fusbh200_hcd *fusbh200, unsigned frame, void *ptr)
-{
-	union fusbh200_shadow	*prev_p = &fusbh200->pshadow[frame];
-	__hc32			*hw_p = &fusbh200->periodic[frame];
-	union fusbh200_shadow	here = *prev_p;
-
-	/* find predecessor of "ptr"; hw and shadow lists are in sync */
-	while (here.ptr && here.ptr != ptr) {
-		prev_p = periodic_next_shadow(fusbh200, prev_p,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-		hw_p = shadow_next_periodic(fusbh200, &here,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-		here = *prev_p;
-	}
-	/* an interrupt entry (at list end) could have been shared */
-	if (!here.ptr)
-		return;
-
-	/* update shadow and hardware lists ... the old "next" pointers
-	 * from ptr may still be in use, the caller updates them.
-	 */
-	*prev_p = *periodic_next_shadow(fusbh200, &here,
-			Q_NEXT_TYPE(fusbh200, *hw_p));
-
-	*hw_p = *shadow_next_periodic(fusbh200, &here,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-}
-
-/* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs (struct fusbh200_hcd *fusbh200, unsigned frame, unsigned uframe)
-{
-	__hc32			*hw_p = &fusbh200->periodic [frame];
-	union fusbh200_shadow	*q = &fusbh200->pshadow [frame];
-	unsigned		usecs = 0;
-	struct fusbh200_qh_hw	*hw;
-
-	while (q->ptr) {
-		switch (hc32_to_cpu(fusbh200, Q_NEXT_TYPE(fusbh200, *hw_p))) {
-		case Q_TYPE_QH:
-			hw = q->qh->hw;
-			/* is it in the S-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fusbh200, 1 << uframe))
-				usecs += q->qh->usecs;
-			/* ... or C-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fusbh200,
-					1 << (8 + uframe)))
-				usecs += q->qh->c_usecs;
-			hw_p = &hw->hw_next;
-			q = &q->qh->qh_next;
-			break;
-		// case Q_TYPE_FSTN:
-		default:
-			/* for "save place" FSTNs, count the relevant INTR
-			 * bandwidth from the previous frame
-			 */
-			if (q->fstn->hw_prev != FUSBH200_LIST_END(fusbh200)) {
-				fusbh200_dbg (fusbh200, "ignoring FSTN cost ...\n");
-			}
-			hw_p = &q->fstn->hw_next;
-			q = &q->fstn->fstn_next;
-			break;
-		case Q_TYPE_ITD:
-			if (q->itd->hw_transaction[uframe])
-				usecs += q->itd->stream->usecs;
-			hw_p = &q->itd->hw_next;
-			q = &q->itd->itd_next;
-			break;
-		}
-	}
-	if (usecs > fusbh200->uframe_periodic_max)
-		fusbh200_err (fusbh200, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
-	return usecs;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
-{
-	if (!dev1->tt || !dev2->tt)
-		return 0;
-	if (dev1->tt != dev2->tt)
-		return 0;
-	if (dev1->tt->multi)
-		return dev1->ttport == dev2->ttport;
-	else
-		return 1;
-}
-
-/* return true iff the device's transaction translator is available
- * for a periodic transfer starting at the specified frame, using
- * all the uframes in the mask.
- */
-static int tt_no_collision (
-	struct fusbh200_hcd		*fusbh200,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
-{
-	if (period == 0)	/* error */
-		return 0;
-
-	/* note bandwidth wastage:  split never follows csplit
-	 * (different dev or endpoint) until the next uframe.
-	 * calling convention doesn't make that distinction.
-	 */
-	for (; frame < fusbh200->periodic_size; frame += period) {
-		union fusbh200_shadow	here;
-		__hc32			type;
-		struct fusbh200_qh_hw	*hw;
-
-		here = fusbh200->pshadow [frame];
-		type = Q_NEXT_TYPE(fusbh200, fusbh200->periodic [frame]);
-		while (here.ptr) {
-			switch (hc32_to_cpu(fusbh200, type)) {
-			case Q_TYPE_ITD:
-				type = Q_NEXT_TYPE(fusbh200, here.itd->hw_next);
-				here = here.itd->itd_next;
-				continue;
-			case Q_TYPE_QH:
-				hw = here.qh->hw;
-				if (same_tt (dev, here.qh->dev)) {
-					u32		mask;
-
-					mask = hc32_to_cpu(fusbh200,
-							hw->hw_info2);
-					/* "knows" no gap is needed */
-					mask |= mask >> 8;
-					if (mask & uf_mask)
-						break;
-				}
-				type = Q_NEXT_TYPE(fusbh200, hw->hw_next);
-				here = here.qh->qh_next;
-				continue;
-			// case Q_TYPE_FSTN:
-			default:
-				fusbh200_dbg (fusbh200,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
-			}
-
-			/* collision or error */
-			return 0;
-		}
-	}
-
-	/* no collision */
-	return 1;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void enable_periodic(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->periodic_count++)
-		return;
-
-	/* Stop waiting to turn off the periodic schedule */
-	fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_DISABLE_PERIODIC);
-
-	/* Don't start the schedule until PSS is 0 */
-	fusbh200_poll_PSS(fusbh200);
-	turn_on_io_watchdog(fusbh200);
-}
-
-static void disable_periodic(struct fusbh200_hcd *fusbh200)
-{
-	if (--fusbh200->periodic_count)
-		return;
-
-	/* Don't turn off the schedule until PSS is 1 */
-	fusbh200_poll_PSS(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* periodic schedule slots have iso tds (normal or split) first, then a
- * sparse tree for active interrupt transfers.
- *
- * this just links in a qh; caller guarantees uframe masks are set right.
- * no FSTN support (yet; fusbh200 0.96+)
- */
-static void qh_link_periodic(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	unsigned	i;
-	unsigned	period = qh->period;
-
-	dev_dbg (&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fusbh200, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* high bandwidth, or otherwise every microframe */
-	if (period == 0)
-		period = 1;
-
-	for (i = qh->start; i < fusbh200->periodic_size; i += period) {
-		union fusbh200_shadow	*prev = &fusbh200->pshadow[i];
-		__hc32			*hw_p = &fusbh200->periodic[i];
-		union fusbh200_shadow	here = *prev;
-		__hc32			type = 0;
-
-		/* skip the iso nodes at list head */
-		while (here.ptr) {
-			type = Q_NEXT_TYPE(fusbh200, *hw_p);
-			if (type == cpu_to_hc32(fusbh200, Q_TYPE_QH))
-				break;
-			prev = periodic_next_shadow(fusbh200, prev, type);
-			hw_p = shadow_next_periodic(fusbh200, &here, type);
-			here = *prev;
-		}
-
-		/* sorting each branch by period (slow-->fast)
-		 * enables sharing interior tree nodes
-		 */
-		while (here.ptr && qh != here.qh) {
-			if (qh->period > here.qh->period)
-				break;
-			prev = &here.qh->qh_next;
-			hw_p = &here.qh->hw->hw_next;
-			here = *prev;
-		}
-		/* link in this qh, unless some earlier pass did that */
-		if (qh != here.qh) {
-			qh->qh_next = here;
-			if (here.qh)
-				qh->hw->hw_next = *hw_p;
-			wmb ();
-			prev->qh = qh;
-			*hw_p = QH_NEXT (fusbh200, qh->qh_dma);
-		}
-	}
-	qh->qh_state = QH_STATE_LINKED;
-	qh->xacterrs = 0;
-
-	/* update per-qh bandwidth for usbfs */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated += qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	list_add(&qh->intr_node, &fusbh200->intr_qh_list);
-
-	/* maybe enable periodic schedule processing */
-	++fusbh200->intr_count;
-	enable_periodic(fusbh200);
-}
-
-static void qh_unlink_periodic(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	unsigned	i;
-	unsigned	period;
-
-	/*
-	 * If qh is for a low/full-speed device, simply unlinking it
-	 * could interfere with an ongoing split transaction.  To unlink
-	 * it safely would require setting the QH_INACTIVATE bit and
-	 * waiting at least one frame, as described in EHCI 4.12.2.5.
-	 *
-	 * We won't bother with any of this.  Instead, we assume that the
-	 * only reason for unlinking an interrupt QH while the current URB
-	 * is still active is to dequeue all the URBs (flush the whole
-	 * endpoint queue).
-	 *
-	 * If rebalancing the periodic schedule is ever implemented, this
-	 * approach will no longer be valid.
-	 */
-
-	/* high bandwidth, or otherwise part of every microframe */
-	if ((period = qh->period) == 0)
-		period = 1;
-
-	for (i = qh->start; i < fusbh200->periodic_size; i += period)
-		periodic_unlink (fusbh200, i, qh);
-
-	/* update per-qh bandwidth for usbfs */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated -= qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	dev_dbg (&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fusbh200, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* qh->qh_next still "live" to HC */
-	qh->qh_state = QH_STATE_UNLINK;
-	qh->qh_next.ptr = NULL;
-
-	if (fusbh200->qh_scan_next == qh)
-		fusbh200->qh_scan_next = list_entry(qh->intr_node.next,
-				struct fusbh200_qh, intr_node);
-	list_del(&qh->intr_node);
-}
-
-static void start_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/* If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	qh_unlink_periodic (fusbh200, qh);
-
-	/* Make sure the unlinks are visible before starting the timer */
-	wmb();
-
-	/*
-	 * The EHCI spec doesn't say how long it takes the controller to
-	 * stop accessing an unlinked interrupt QH.  The timer delay is
-	 * 9 uframes; presumably that will be long enough.
-	 */
-	qh->unlink_cycle = fusbh200->intr_unlink_cycle;
-
-	/* New entries go at the end of the intr_unlink list */
-	if (fusbh200->intr_unlink)
-		fusbh200->intr_unlink_last->unlink_next = qh;
-	else
-		fusbh200->intr_unlink = qh;
-	fusbh200->intr_unlink_last = qh;
-
-	if (fusbh200->intr_unlinking)
-		;	/* Avoid recursive calls */
-	else if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-		fusbh200_handle_intr_unlinks(fusbh200);
-	else if (fusbh200->intr_unlink == qh) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_UNLINK_INTR, true);
-		++fusbh200->intr_unlink_cycle;
-	}
-}
-
-static void end_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh_hw	*hw = qh->hw;
-	int			rc;
-
-	qh->qh_state = QH_STATE_IDLE;
-	hw->hw_next = FUSBH200_LIST_END(fusbh200);
-
-	qh_completions(fusbh200, qh);
-
-	/* reschedule QH iff another request is queued */
-	if (!list_empty(&qh->qtd_list) && fusbh200->rh_state == FUSBH200_RH_RUNNING) {
-		rc = qh_schedule(fusbh200, qh);
-
-		/* An error here likely indicates handshake failure
-		 * or no space left in the schedule.  Neither fault
-		 * should happen often ...
-		 *
-		 * FIXME kill the now-dysfunctional queued urbs
-		 */
-		if (rc != 0)
-			fusbh200_err(fusbh200, "can't reschedule qh %p, err %d\n",
-					qh, rc);
-	}
-
-	/* maybe turn off periodic schedule */
-	--fusbh200->intr_count;
-	disable_periodic(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int check_period (
-	struct fusbh200_hcd *fusbh200,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
-
-	/* complete split running into next frame?
-	 * given FSTN support, we could sometimes check...
-	 */
-	if (uframe >= 8)
-		return 0;
-
-	/* convert "usecs we need" to "max already claimed" */
-	usecs = fusbh200->uframe_periodic_max - usecs;
-
-	/* we "know" 2 and 4 uframe intervals were rejected; so
-	 * for period 0, check _every_ microframe in the schedule.
-	 */
-	if (unlikely (period == 0)) {
-		do {
-			for (uframe = 0; uframe < 7; uframe++) {
-				claimed = periodic_usecs (fusbh200, frame, uframe);
-				if (claimed > usecs)
-					return 0;
-			}
-		} while ((frame += 1) < fusbh200->periodic_size);
-
-	/* just check the specified uframe, at that period */
-	} else {
-		do {
-			claimed = periodic_usecs (fusbh200, frame, uframe);
-			if (claimed > usecs)
-				return 0;
-		} while ((frame += period) < fusbh200->periodic_size);
-	}
-
-	// success!
-	return 1;
-}
-
-static int check_intr_schedule (
-	struct fusbh200_hcd		*fusbh200,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fusbh200_qh	*qh,
-	__hc32			*c_maskp
-)
-{
-	int		retval = -ENOSPC;
-	u8		mask = 0;
-
-	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
-		goto done;
-
-	if (!check_period (fusbh200, frame, uframe, qh->period, qh->usecs))
-		goto done;
-	if (!qh->c_usecs) {
-		retval = 0;
-		*c_maskp = 0;
-		goto done;
-	}
-
-	/* Make sure this tt's buffer is also available for CSPLITs.
-	 * We pessimize a bit; probably the typical full speed case
-	 * doesn't need the second CSPLIT.
-	 *
-	 * NOTE:  both SPLIT and CSPLIT could be checked in just
-	 * one smart pass...
-	 */
-	mask = 0x03 << (uframe + qh->gap_uf);
-	*c_maskp = cpu_to_hc32(fusbh200, mask << 8);
-
-	mask |= 1 << uframe;
-	if (tt_no_collision (fusbh200, qh->period, qh->dev, frame, mask)) {
-		if (!check_period (fusbh200, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
-			goto done;
-		if (!check_period (fusbh200, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
-			goto done;
-		retval = 0;
-	}
-done:
-	return retval;
-}
-
-/* "first fit" scheduling policy used the first time through,
- * or when the previous schedule slot can't be re-used.
- */
-static int qh_schedule(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	qh_refresh(fusbh200, qh);
-	hw->hw_next = FUSBH200_LIST_END(fusbh200);
-	frame = qh->start;
-
-	/* reuse the previous schedule slots, if we can */
-	if (frame < qh->period) {
-		uframe = ffs(hc32_to_cpup(fusbh200, &hw->hw_info2) & QH_SMASK);
-		status = check_intr_schedule (fusbh200, frame, --uframe,
-				qh, &c_mask);
-	} else {
-		uframe = 0;
-		c_mask = 0;
-		status = -ENOSPC;
-	}
-
-	/* else scan the schedule to find a group of slots such that all
-	 * uframes have enough periodic bandwidth available.
-	 */
-	if (status) {
-		/* "normal" case, uframing flexible except with splits */
-		if (qh->period) {
-			int		i;
-
-			for (i = qh->period; status && i > 0; --i) {
-				frame = ++fusbh200->random_frame % qh->period;
-				for (uframe = 0; uframe < 8; uframe++) {
-					status = check_intr_schedule (fusbh200,
-							frame, uframe, qh,
-							&c_mask);
-					if (status == 0)
-						break;
-				}
-			}
-
-		/* qh->period == 0 means every uframe */
-		} else {
-			frame = 0;
-			status = check_intr_schedule (fusbh200, 0, 0, qh, &c_mask);
-		}
-		if (status)
-			goto done;
-		qh->start = frame;
-
-		/* reset S-frame and (maybe) C-frame masks */
-		hw->hw_info2 &= cpu_to_hc32(fusbh200, ~(QH_CMASK | QH_SMASK));
-		hw->hw_info2 |= qh->period
-			? cpu_to_hc32(fusbh200, 1 << uframe)
-			: cpu_to_hc32(fusbh200, QH_SMASK);
-		hw->hw_info2 |= c_mask;
-	} else
-		fusbh200_dbg (fusbh200, "reused qh %p schedule\n", qh);
-
-	/* stuff into the periodic schedule */
-	qh_link_periodic(fusbh200, qh);
-done:
-	return status;
-}
-
-static int intr_submit (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fusbh200_qh		*qh;
-	int			status;
-	struct list_head	empty;
-
-	/* get endpoint and transfer/schedule data */
-	epnum = urb->ep->desc.bEndpointAddress;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-
-	/* get qh and force any scheduling errors */
-	INIT_LIST_HEAD (&empty);
-	qh = qh_append_tds(fusbh200, urb, &empty, epnum, &urb->ep->hcpriv);
-	if (qh == NULL) {
-		status = -ENOMEM;
-		goto done;
-	}
-	if (qh->qh_state == QH_STATE_IDLE) {
-		if ((status = qh_schedule (fusbh200, qh)) != 0)
-			goto done;
-	}
-
-	/* then queue the urb's tds to the qh */
-	qh = qh_append_tds(fusbh200, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	BUG_ON (qh == NULL);
-
-	/* ... update usbfs periodic stats */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_int_reqs++;
-
-done:
-	if (unlikely(status))
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-done_not_linked:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	if (status)
-		qtd_list_free (fusbh200, urb, qtd_list);
-
-	return status;
-}
-
-static void scan_intr(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-
-	list_for_each_entry_safe(qh, fusbh200->qh_scan_next, &fusbh200->intr_qh_list,
-			intr_node) {
- rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fusbh200->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fusbh200->qh_scan_next is adjusted
-			 * in qh_unlink_periodic().
-			 */
-			temp = qh_completions(fusbh200, qh);
-			if (unlikely(qh->needs_rescan ||
-					(list_empty(&qh->qtd_list) &&
-						qh->qh_state == QH_STATE_LINKED)))
-				start_unlink_intr(fusbh200, qh);
-			else if (temp != 0)
-				goto rescan;
-		}
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* fusbh200_iso_stream ops work with both ITD and SITD */
-
-static struct fusbh200_iso_stream *
-iso_stream_alloc (gfp_t mem_flags)
-{
-	struct fusbh200_iso_stream *stream;
-
-	stream = kzalloc(sizeof *stream, mem_flags);
-	if (likely (stream != NULL)) {
-		INIT_LIST_HEAD(&stream->td_list);
-		INIT_LIST_HEAD(&stream->free_list);
-		stream->next_uframe = -1;
-	}
-	return stream;
-}
-
-static void
-iso_stream_init (
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
-{
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned 		multi;
-
-	/*
-	 * this might be a "high bandwidth" highspeed endpoint,
-	 * as encoded in the ep descriptor's wMaxPacket field
-	 */
-	epnum = usb_pipeendpoint (pipe);
-	is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
-	maxp = usb_maxpacket(dev, pipe, !is_input);
-	if (is_input) {
-		buf1 = (1 << 11);
-	} else {
-		buf1 = 0;
-	}
-
-	maxp = max_packet(maxp);
-	multi = hb_mult(maxp);
-	buf1 |= maxp;
-	maxp *= multi;
-
-	stream->buf0 = cpu_to_hc32(fusbh200, (epnum << 8) | dev->devnum);
-	stream->buf1 = cpu_to_hc32(fusbh200, buf1);
-	stream->buf2 = cpu_to_hc32(fusbh200, multi);
-
-	/* usbfs wants to report the average usecs per frame tied up
-	 * when transfers on this endpoint are scheduled ...
-	 */
-	if (dev->speed == USB_SPEED_FULL) {
-		interval <<= 3;
-		stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
-				is_input, 1, maxp));
-		stream->usecs /= 8;
-	} else {
-		stream->highspeed = 1;
-		stream->usecs = HS_USECS_ISO (maxp);
-	}
-	bandwidth = stream->usecs * 8;
-	bandwidth /= interval;
-
-	stream->bandwidth = bandwidth;
-	stream->udev = dev;
-	stream->bEndpointAddress = is_input | epnum;
-	stream->interval = interval;
-	stream->maxp = maxp;
-}
-
-static struct fusbh200_iso_stream *
-iso_stream_find (struct fusbh200_hcd *fusbh200, struct urb *urb)
-{
-	unsigned		epnum;
-	struct fusbh200_iso_stream	*stream;
-	struct usb_host_endpoint *ep;
-	unsigned long		flags;
-
-	epnum = usb_pipeendpoint (urb->pipe);
-	if (usb_pipein(urb->pipe))
-		ep = urb->dev->ep_in[epnum];
-	else
-		ep = urb->dev->ep_out[epnum];
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	stream = ep->hcpriv;
-
-	if (unlikely (stream == NULL)) {
-		stream = iso_stream_alloc(GFP_ATOMIC);
-		if (likely (stream != NULL)) {
-			ep->hcpriv = stream;
-			stream->ep = ep;
-			iso_stream_init(fusbh200, stream, urb->dev, urb->pipe,
-					urb->interval);
-		}
-
-	/* if dev->ep [epnum] is a QH, hw is set */
-	} else if (unlikely (stream->hw != NULL)) {
-		fusbh200_dbg (fusbh200, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
-		stream = NULL;
-	}
-
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return stream;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* fusbh200_iso_sched ops can be ITD-only or SITD-only */
-
-static struct fusbh200_iso_sched *
-iso_sched_alloc (unsigned packets, gfp_t mem_flags)
-{
-	struct fusbh200_iso_sched	*iso_sched;
-	int			size = sizeof *iso_sched;
-
-	size += packets * sizeof (struct fusbh200_iso_packet);
-	iso_sched = kzalloc(size, mem_flags);
-	if (likely (iso_sched != NULL)) {
-		INIT_LIST_HEAD (&iso_sched->td_list);
-	}
-	return iso_sched;
-}
-
-static inline void
-itd_sched_init(
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_iso_sched	*iso_sched,
-	struct fusbh200_iso_stream	*stream,
-	struct urb		*urb
-)
-{
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
-
-	/* how many uframes are needed for these transfers */
-	iso_sched->span = urb->number_of_packets * stream->interval;
-
-	/* figure out per-uframe itd fields that we'll need later
-	 * when we fit new itds into the schedule.
-	 */
-	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fusbh200_iso_packet	*uframe = &iso_sched->packet [i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
-
-		length = urb->iso_frame_desc [i].length;
-		buf = dma + urb->iso_frame_desc [i].offset;
-
-		trans = FUSBH200_ISOC_ACTIVE;
-		trans |= buf & 0x0fff;
-		if (unlikely (((i + 1) == urb->number_of_packets))
-				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
-			trans |= FUSBH200_ITD_IOC;
-		trans |= length << 16;
-		uframe->transaction = cpu_to_hc32(fusbh200, trans);
-
-		/* might need to cross a buffer page within a uframe */
-		uframe->bufp = (buf & ~(u64)0x0fff);
-		buf += length;
-		if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
-			uframe->cross = 1;
-	}
-}
-
-static void
-iso_sched_free (
-	struct fusbh200_iso_stream	*stream,
-	struct fusbh200_iso_sched	*iso_sched
-)
-{
-	if (!iso_sched)
-		return;
-	// caller must hold fusbh200->lock!
-	list_splice (&iso_sched->td_list, &stream->free_list);
-	kfree (iso_sched);
-}
-
-static int
-itd_urb_transaction (
-	struct fusbh200_iso_stream	*stream,
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
-{
-	struct fusbh200_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fusbh200_iso_sched	*sched;
-	unsigned long		flags;
-
-	sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (unlikely (sched == NULL))
-		return -ENOMEM;
-
-	itd_sched_init(fusbh200, sched, stream, urb);
-
-	if (urb->interval < 8)
-		num_itds = 1 + (sched->span + 7) / 8;
-	else
-		num_itds = urb->number_of_packets;
-
-	/* allocate/init ITDs */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (i = 0; i < num_itds; i++) {
-
-		/*
-		 * Use iTDs from the free list, but not iTDs that may
-		 * still be in use by the hardware.
-		 */
-		if (likely(!list_empty(&stream->free_list))) {
-			itd = list_first_entry(&stream->free_list,
-					struct fusbh200_itd, itd_list);
-			if (itd->frame == fusbh200->now_frame)
-				goto alloc_itd;
-			list_del (&itd->itd_list);
-			itd_dma = itd->itd_dma;
-		} else {
- alloc_itd:
-			spin_unlock_irqrestore (&fusbh200->lock, flags);
-			itd = dma_pool_alloc (fusbh200->itd_pool, mem_flags,
-					&itd_dma);
-			spin_lock_irqsave (&fusbh200->lock, flags);
-			if (!itd) {
-				iso_sched_free(stream, sched);
-				spin_unlock_irqrestore(&fusbh200->lock, flags);
-				return -ENOMEM;
-			}
-		}
-
-		memset (itd, 0, sizeof *itd);
-		itd->itd_dma = itd_dma;
-		list_add (&itd->itd_list, &sched->td_list);
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	/* temporarily store schedule info in hcpriv */
-	urb->hcpriv = sched;
-	urb->error_count = 0;
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok (
-	struct fusbh200_hcd		*fusbh200,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
-{
-	uframe %= period;
-	do {
-		/* can't commit more than uframe_periodic_max usec */
-		if (periodic_usecs (fusbh200, uframe >> 3, uframe & 0x7)
-				> (fusbh200->uframe_periodic_max - usecs))
-			return 0;
-
-		/* we know urb->interval is 2^N uframes */
-		uframe += period;
-	} while (uframe < mod);
-	return 1;
-}
-
-/*
- * This scheduler plans almost as far into the future as it has actual
- * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
- * "as small as possible" to be cache-friendlier.)  That limits the size
- * transfers you can stream reliably; avoid more than 64 msec per urb.
- * Also avoid queue depths of less than fusbh200's worst irq latency (affected
- * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
- * and other factors); or more than about 230 msec total (for portability,
- * given FUSBH200_TUNE_FLS and the slop).  Or, write a smarter scheduler!
- */
-
-#define SCHEDULE_SLOP	80	/* microframes */
-
-static int
-iso_stream_schedule (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct fusbh200_iso_stream	*stream
-)
-{
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fusbh200->periodic_size << 3;
-	struct fusbh200_iso_sched	*sched = urb->hcpriv;
-
-	period = urb->interval;
-	span = sched->span;
-
-	if (span > mod - SCHEDULE_SLOP) {
-		fusbh200_dbg (fusbh200, "iso request %p too long\n", urb);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	now = fusbh200_read_frame_index(fusbh200) & (mod - 1);
-
-	/* Typical case: reuse current schedule, stream is still active.
-	 * Hopefully there are no gaps from the host falling behind
-	 * (irq delays etc), but if there are we'll take the next
-	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
-	 */
-	if (likely (!list_empty (&stream->td_list))) {
-		u32	excess;
-
-		/* For high speed devices, allow scheduling within the
-		 * isochronous scheduling threshold.  For full speed devices
-		 * and Intel PCI-based controllers, don't (work around for
-		 * Intel ICH9 bug).
-		 */
-		if (!stream->highspeed && fusbh200->fs_i_thresh)
-			next = now + fusbh200->i_thresh;
-		else
-			next = now;
-
-		/* Fell behind (by up to twice the slop amount)?
-		 * We decide based on the time of the last currently-scheduled
-		 * slot, not the time of the next available slot.
-		 */
-		excess = (stream->next_uframe - period - next) & (mod - 1);
-		if (excess >= mod - 2 * SCHEDULE_SLOP)
-			start = next + excess - mod + period *
-					DIV_ROUND_UP(mod - excess, period);
-		else
-			start = next + excess + period;
-		if (start - now >= mod) {
-			fusbh200_dbg(fusbh200, "request %p would overflow (%d+%d >= %d)\n",
-					urb, start - now - period, period,
-					mod);
-			status = -EFBIG;
-			goto fail;
-		}
-	}
-
-	/* need to schedule; when's the next (u)frame we could start?
-	 * this is bigger than fusbh200->i_thresh allows; scheduling itself
-	 * isn't free, the slop should handle reasonably slow cpus.  it
-	 * can also help high bandwidth if the dma and irq loads don't
-	 * jump until after the queue is primed.
-	 */
-	else {
-		int done = 0;
-		start = SCHEDULE_SLOP + (now & ~0x07);
-
-		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
-
-		/* find a uframe slot with enough bandwidth.
-		 * Early uframes are more precious because full-speed
-		 * iso IN transfers can't use late uframes,
-		 * and therefore they should be allocated last.
-		 */
-		next = start;
-		start += period;
-		do {
-			start--;
-			/* check schedule: enough space? */
-			if (itd_slot_ok(fusbh200, mod, start,
-					stream->usecs, period))
-				done = 1;
-		} while (start > next && !done);
-
-		/* no room in the schedule */
-		if (!done) {
-			fusbh200_dbg(fusbh200, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
-			status = -ENOSPC;
-			goto fail;
-		}
-	}
-
-	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
-		fusbh200_dbg(fusbh200, "request %p would overflow (%d+%d >= %d)\n",
-				urb, start - now, span - period,
-				mod - 2 * SCHEDULE_SLOP);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	stream->next_uframe = start & (mod - 1);
-
-	/* report high speed start in uframes; full speed, in frames */
-	urb->start_frame = stream->next_uframe;
-	if (!stream->highspeed)
-		urb->start_frame >>= 3;
-
-	/* Make sure scan_isoc() sees these */
-	if (fusbh200->isoc_count == 0)
-		fusbh200->next_frame = now >> 3;
-	return 0;
-
- fail:
-	iso_sched_free(stream, sched);
-	urb->hcpriv = NULL;
-	return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fusbh200_hcd *fusbh200, struct fusbh200_iso_stream *stream,
-		struct fusbh200_itd *itd)
-{
-	int i;
-
-	/* it's been recently zeroed */
-	itd->hw_next = FUSBH200_LIST_END(fusbh200);
-	itd->hw_bufp [0] = stream->buf0;
-	itd->hw_bufp [1] = stream->buf1;
-	itd->hw_bufp [2] = stream->buf2;
-
-	for (i = 0; i < 8; i++)
-		itd->index[i] = -1;
-
-	/* All other fields are filled when scheduling */
-}
-
-static inline void
-itd_patch(
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_itd		*itd,
-	struct fusbh200_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
-{
-	struct fusbh200_iso_packet	*uf = &iso_sched->packet [index];
-	unsigned		pg = itd->pg;
-
-	// BUG_ON (pg == 6 && uf->cross);
-
-	uframe &= 0x07;
-	itd->index [uframe] = index;
-
-	itd->hw_transaction[uframe] = uf->transaction;
-	itd->hw_transaction[uframe] |= cpu_to_hc32(fusbh200, pg << 12);
-	itd->hw_bufp[pg] |= cpu_to_hc32(fusbh200, uf->bufp & ~(u32)0);
-	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fusbh200, (u32)(uf->bufp >> 32));
-
-	/* iso_frame_desc[].offset must be strictly increasing */
-	if (unlikely (uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
-
-		itd->pg = ++pg;
-		itd->hw_bufp[pg] |= cpu_to_hc32(fusbh200, bufp & ~(u32)0);
-		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fusbh200, (u32)(bufp >> 32));
-	}
-}
-
-static inline void
-itd_link (struct fusbh200_hcd *fusbh200, unsigned frame, struct fusbh200_itd *itd)
-{
-	union fusbh200_shadow	*prev = &fusbh200->pshadow[frame];
-	__hc32			*hw_p = &fusbh200->periodic[frame];
-	union fusbh200_shadow	here = *prev;
-	__hc32			type = 0;
-
-	/* skip any iso nodes which might belong to previous microframes */
-	while (here.ptr) {
-		type = Q_NEXT_TYPE(fusbh200, *hw_p);
-		if (type == cpu_to_hc32(fusbh200, Q_TYPE_QH))
-			break;
-		prev = periodic_next_shadow(fusbh200, prev, type);
-		hw_p = shadow_next_periodic(fusbh200, &here, type);
-		here = *prev;
-	}
-
-	itd->itd_next = here;
-	itd->hw_next = *hw_p;
-	prev->itd = itd;
-	itd->frame = frame;
-	wmb ();
-	*hw_p = cpu_to_hc32(fusbh200, itd->itd_dma | Q_TYPE_ITD);
-}
-
-/* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fusbh200_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fusbh200_iso_sched	*iso_sched = urb->hcpriv;
-	struct fusbh200_itd		*itd;
-
-	next_uframe = stream->next_uframe & (mod - 1);
-
-	if (unlikely (list_empty(&stream->td_list))) {
-		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated
-				+= stream->bandwidth;
-		fusbh200_dbg(fusbh200,
-			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
-			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
-			urb->interval,
-			next_uframe >> 3, next_uframe & 0x7);
-	}
-
-	/* fill iTDs uframe by uframe */
-	for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
-		if (itd == NULL) {
-			/* ASSERT:  we have all necessary itds */
-			// BUG_ON (list_empty (&iso_sched->td_list));
-
-			/* ASSERT:  no itds for this endpoint in this uframe */
-
-			itd = list_entry (iso_sched->td_list.next,
-					struct fusbh200_itd, itd_list);
-			list_move_tail (&itd->itd_list, &stream->td_list);
-			itd->stream = stream;
-			itd->urb = urb;
-			itd_init (fusbh200, stream, itd);
-		}
-
-		uframe = next_uframe & 0x07;
-		frame = next_uframe >> 3;
-
-		itd_patch(fusbh200, itd, iso_sched, packet, uframe);
-
-		next_uframe += stream->interval;
-		next_uframe &= mod - 1;
-		packet++;
-
-		/* link completed itds into the schedule */
-		if (((next_uframe >> 3) != frame)
-				|| packet == urb->number_of_packets) {
-			itd_link(fusbh200, frame & (fusbh200->periodic_size - 1), itd);
-			itd = NULL;
-		}
-	}
-	stream->next_uframe = next_uframe;
-
-	/* don't need that schedule data any more */
-	iso_sched_free (stream, iso_sched);
-	urb->hcpriv = NULL;
-
-	++fusbh200->isoc_count;
-	enable_periodic(fusbh200);
-}
-
-#define	ISO_ERRS (FUSBH200_ISOC_BUF_ERR | FUSBH200_ISOC_BABBLE | FUSBH200_ISOC_XACTERR)
-
-/* Process and recycle a completed ITD.  Return true iff its urb completed,
- * and hence its completion callback probably added things to the hardware
- * schedule.
- *
- * Note that we carefully avoid recycling this descriptor until after any
- * completion callback runs, so that it won't be reused quickly.  That is,
- * assuming (a) no more than two urbs per frame on this endpoint, and also
- * (b) only this endpoint's completions submit URBs.  It seems some silicon
- * corrupts things if you reuse completed descriptors very quickly...
- */
-static bool itd_complete(struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd)
-{
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fusbh200_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
-
-	/* for each uframe with a packet */
-	for (uframe = 0; uframe < 8; uframe++) {
-		if (likely (itd->index[uframe] == -1))
-			continue;
-		urb_index = itd->index[uframe];
-		desc = &urb->iso_frame_desc [urb_index];
-
-		t = hc32_to_cpup(fusbh200, &itd->hw_transaction [uframe]);
-		itd->hw_transaction [uframe] = 0;
-
-		/* report transfer status */
-		if (unlikely (t & ISO_ERRS)) {
-			urb->error_count++;
-			if (t & FUSBH200_ISOC_BUF_ERR)
-				desc->status = usb_pipein (urb->pipe)
-					? -ENOSR  /* hc couldn't read */
-					: -ECOMM; /* hc couldn't write */
-			else if (t & FUSBH200_ISOC_BABBLE)
-				desc->status = -EOVERFLOW;
-			else /* (t & FUSBH200_ISOC_XACTERR) */
-				desc->status = -EPROTO;
-
-			/* HC need not update length with this error */
-			if (!(t & FUSBH200_ISOC_BABBLE)) {
-				desc->actual_length = fusbh200_itdlen(urb, desc, t);
-				urb->actual_length += desc->actual_length;
-			}
-		} else if (likely ((t & FUSBH200_ISOC_ACTIVE) == 0)) {
-			desc->status = 0;
-			desc->actual_length = fusbh200_itdlen(urb, desc, t);
-			urb->actual_length += desc->actual_length;
-		} else {
-			/* URB was too late */
-			desc->status = -EXDEV;
-		}
-	}
-
-	/* handle completion now? */
-	if (likely ((urb_index + 1) != urb->number_of_packets))
-		goto done;
-
-	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
-	 */
-
-	/* give urb back to the driver; completion often (re)submits */
-	dev = urb->dev;
-	fusbh200_urb_done(fusbh200, urb, 0);
-	retval = true;
-	urb = NULL;
-
-	--fusbh200->isoc_count;
-	disable_periodic(fusbh200);
-
-	if (unlikely(list_is_singular(&stream->td_list))) {
-		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated
-				-= stream->bandwidth;
-		fusbh200_dbg(fusbh200,
-			"deschedule devp %s ep%d%s-iso\n",
-			dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
-	}
-
-done:
-	itd->urb = NULL;
-
-	/* Add to the end of the free list for later reuse */
-	list_move_tail(&itd->itd_list, &stream->free_list);
-
-	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
-	if (list_empty(&stream->td_list)) {
-		list_splice_tail_init(&stream->free_list,
-				&fusbh200->cached_itd_list);
-		start_free_itds(fusbh200);
-	}
-
-	return retval;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int itd_submit (struct fusbh200_hcd *fusbh200, struct urb *urb,
-	gfp_t mem_flags)
-{
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fusbh200_iso_stream	*stream;
-
-	/* Get iso_stream head */
-	stream = iso_stream_find (fusbh200, urb);
-	if (unlikely (stream == NULL)) {
-		fusbh200_dbg (fusbh200, "can't get iso stream\n");
-		return -ENOMEM;
-	}
-	if (unlikely (urb->interval != stream->interval &&
-		      fusbh200_port_speed(fusbh200, 0) == USB_PORT_STAT_HIGH_SPEED)) {
-			fusbh200_dbg (fusbh200, "can't change iso interval %d --> %d\n",
-				stream->interval, urb->interval);
-			goto done;
-	}
-
-#ifdef FUSBH200_URB_TRACE
-	fusbh200_dbg (fusbh200,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
-#endif
-
-	/* allocate ITDs w/o locking anything */
-	status = itd_urb_transaction (stream, fusbh200, urb, mem_flags);
-	if (unlikely (status < 0)) {
-		fusbh200_dbg (fusbh200, "can't init itds\n");
-		goto done;
-	}
-
-	/* schedule ... need to lock */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-	status = iso_stream_schedule(fusbh200, urb, stream);
-	if (likely (status == 0))
-		itd_link_urb (fusbh200, urb, fusbh200->periodic_size << 3, stream);
-	else
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
- done_not_linked:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
- done:
-	return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void scan_isoc(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fusbh200->periodic_size - 1;
-	bool		modified, live;
-
-	/*
-	 * When running, scan from last scan point up to "now"
-	 * else clean up by scanning everything that's left.
-	 * Touches as few pages as possible:  cache-friendly.
-	 */
-	if (fusbh200->rh_state >= FUSBH200_RH_RUNNING) {
-		uf = fusbh200_read_frame_index(fusbh200);
-		now_frame = (uf >> 3) & fmask;
-		live = true;
-	} else  {
-		now_frame = (fusbh200->next_frame - 1) & fmask;
-		live = false;
-	}
-	fusbh200->now_frame = now_frame;
-
-	frame = fusbh200->next_frame;
-	for (;;) {
-		union fusbh200_shadow	q, *q_p;
-		__hc32			type, *hw_p;
-
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fusbh200->pshadow [frame];
-		hw_p = &fusbh200->periodic [frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fusbh200, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fusbh200, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fusbh200))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fusbh200,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fusbh200, q.itd->hw_next);
-				wmb();
-				modified = itd_complete (fusbh200, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fusbh200_dbg(fusbh200, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
-				// BUG ();
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fusbh200->isoc_count > 0))
-				goto restart;
-		}
-
-		/* Stop when we have reached the current frame */
-		if (frame == now_frame)
-			break;
-		frame = (frame + 1) & fmask;
-	}
-	fusbh200->next_frame = now_frame;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * Display / Set uframe_periodic_max
- */
-static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	struct fusbh200_hcd		*fusbh200;
-	int			n;
-
-	fusbh200 = hcd_to_fusbh200(bus_to_hcd(dev_get_drvdata(dev)));
-	n = scnprintf(buf, PAGE_SIZE, "%d\n", fusbh200->uframe_periodic_max);
-	return n;
-}
-
-
-static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
-{
-	struct fusbh200_hcd		*fusbh200;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
-
-	fusbh200 = hcd_to_fusbh200(bus_to_hcd(dev_get_drvdata(dev)));
-	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
-		return -EINVAL;
-
-	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-		fusbh200_info(fusbh200, "rejecting invalid request for "
-				"uframe_periodic_max=%u\n", uframe_periodic_max);
-		return -EINVAL;
-	}
-
-	ret = -EINVAL;
-
-	/*
-	 * lock, so that our checking does not race with possible periodic
-	 * bandwidth allocation through submitting new urbs.
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	/*
-	 * for request to decrease max periodic bandwidth, we have to check
-	 * every microframe in the schedule to see whether the decrease is
-	 * possible.
-	 */
-	if (uframe_periodic_max < fusbh200->uframe_periodic_max) {
-		allocated_max = 0;
-
-		for (frame = 0; frame < fusbh200->periodic_size; ++frame)
-			for (uframe = 0; uframe < 7; ++uframe)
-				allocated_max = max(allocated_max,
-						    periodic_usecs (fusbh200, frame, uframe));
-
-		if (allocated_max > uframe_periodic_max) {
-			fusbh200_info(fusbh200,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
-				allocated_max, uframe_periodic_max);
-			goto out_unlock;
-		}
-	}
-
-	/* increasing is always ok */
-
-	fusbh200_info(fusbh200, "setting max periodic bandwidth to %u%% "
-			"(== %u usec/uframe)\n",
-			100*uframe_periodic_max/125, uframe_periodic_max);
-
-	if (uframe_periodic_max != 100)
-		fusbh200_warn(fusbh200, "max periodic bandwidth set is non-standard\n");
-
-	fusbh200->uframe_periodic_max = uframe_periodic_max;
-	ret = count;
-
-out_unlock:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return ret;
-}
-static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max, store_uframe_periodic_max);
-
-
-static inline int create_sysfs_files(struct fusbh200_hcd *fusbh200)
-{
-	struct device	*controller = fusbh200_to_hcd(fusbh200)->self.controller;
-	int	i = 0;
-
-	if (i)
-		goto out;
-
-	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
-out:
-	return i;
-}
-
-static inline void remove_sysfs_files(struct fusbh200_hcd *fusbh200)
-{
-	struct device	*controller = fusbh200_to_hcd(fusbh200)->self.controller;
-
-	device_remove_file(controller, &dev_attr_uframe_periodic_max);
-}
-/*-------------------------------------------------------------------------*/
-
-/* On some systems, leaving remote wakeup enabled prevents system shutdown.
- * The firmware seems to think that powering off is a wakeup event!
- * This routine turns off remote wakeup and everything else, on all ports.
- */
-static void fusbh200_turn_off_all_ports(struct fusbh200_hcd *fusbh200)
-{
-	u32 __iomem *status_reg = &fusbh200->regs->port_status;
-
-	fusbh200_writel(fusbh200, PORT_RWC_BITS, status_reg);
-}
-
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fusbh200_silence_controller(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_halt(fusbh200);
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200_turn_off_all_ports(fusbh200);
-	spin_unlock_irq(&fusbh200->lock);
-}
-
-/* fusbh200_shutdown kick in for silicon on any bus (not just pci, etc).
- * This forcibly disables dma and IRQs, helping kexec and other cases
- * where the next system software may expect clean state.
- */
-static void fusbh200_shutdown(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200(hcd);
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->shutdown = true;
-	fusbh200->rh_state = FUSBH200_RH_STOPPING;
-	fusbh200->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fusbh200->lock);
-
-	fusbh200_silence_controller(fusbh200);
-
-	hrtimer_cancel(&fusbh200->hrtimer);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * fusbh200_work is called from some interrupts, timers, and so on.
- * it calls driver completion functions, after dropping fusbh200->lock.
- */
-static void fusbh200_work (struct fusbh200_hcd *fusbh200)
-{
-	/* another CPU may drop fusbh200->lock during a schedule scan while
-	 * it reports urb completions.  this flag guards against bogus
-	 * attempts at re-entrant schedule scanning.
-	 */
-	if (fusbh200->scanning) {
-		fusbh200->need_rescan = true;
-		return;
-	}
-	fusbh200->scanning = true;
-
- rescan:
-	fusbh200->need_rescan = false;
-	if (fusbh200->async_count)
-		scan_async(fusbh200);
-	if (fusbh200->intr_count > 0)
-		scan_intr(fusbh200);
-	if (fusbh200->isoc_count > 0)
-		scan_isoc(fusbh200);
-	if (fusbh200->need_rescan)
-		goto rescan;
-	fusbh200->scanning = false;
-
-	/* the IO watchdog guards against hardware or driver bugs that
-	 * misplace IRQs, and should let us run completely without IRQs.
-	 * such lossage has been observed on both VT6202 and VT8235.
-	 */
-	turn_on_io_watchdog(fusbh200);
-}
-
-/*
- * Called when the fusbh200_hcd module is removed.
- */
-static void fusbh200_stop (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-
-	fusbh200_dbg (fusbh200, "stop\n");
-
-	/* no more interrupts ... */
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fusbh200->lock);
-
-	fusbh200_quiesce(fusbh200);
-	fusbh200_silence_controller(fusbh200);
-	fusbh200_reset (fusbh200);
-
-	hrtimer_cancel(&fusbh200->hrtimer);
-	remove_sysfs_files(fusbh200);
-	remove_debug_files (fusbh200);
-
-	/* root hub is shut down separately (first, when possible) */
-	spin_lock_irq (&fusbh200->lock);
-	end_free_itds(fusbh200);
-	spin_unlock_irq (&fusbh200->lock);
-	fusbh200_mem_cleanup (fusbh200);
-
-	fusbh200_dbg(fusbh200, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,
-		fusbh200->stats.lost_iaa);
-	fusbh200_dbg (fusbh200, "complete %ld unlink %ld\n",
-		fusbh200->stats.complete, fusbh200->stats.unlink);
-
-	dbg_status (fusbh200, "fusbh200_stop completed",
-		    fusbh200_readl(fusbh200, &fusbh200->regs->status));
-}
-
-/* one-time init, only for memory state */
-static int hcd_fusbh200_init(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fusbh200_qh_hw	*hw;
-
-	spin_lock_init(&fusbh200->lock);
-
-	/*
-	 * keep io watchdog by default, those good HCDs could turn off it later
-	 */
-	fusbh200->need_io_watchdog = 1;
-
-	hrtimer_init(&fusbh200->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-	fusbh200->hrtimer.function = fusbh200_hrtimer_func;
-	fusbh200->next_hrtimer_event = FUSBH200_HRTIMER_NO_EVENT;
-
-	hcc_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	/*
-	 * by default set standard 80% (== 100 usec/uframe) max periodic
-	 * bandwidth as required by USB 2.0
-	 */
-	fusbh200->uframe_periodic_max = 100;
-
-	/*
-	 * hw default: 1K periodic list heads, one per frame.
-	 * periodic_size can shrink by USBCMD update if hcc_params allows.
-	 */
-	fusbh200->periodic_size = DEFAULT_I_TDPS;
-	INIT_LIST_HEAD(&fusbh200->intr_qh_list);
-	INIT_LIST_HEAD(&fusbh200->cached_itd_list);
-
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		switch (FUSBH200_TUNE_FLS) {
-		case 0: fusbh200->periodic_size = 1024; break;
-		case 1: fusbh200->periodic_size = 512; break;
-		case 2: fusbh200->periodic_size = 256; break;
-		default:	BUG();
-		}
-	}
-	if ((retval = fusbh200_mem_init(fusbh200, GFP_KERNEL)) < 0)
-		return retval;
-
-	/* controllers may cache some of the periodic schedule ... */
-	fusbh200->i_thresh = 2;
-
-	/*
-	 * dedicate a qh for the async ring head, since we couldn't unlink
-	 * a 'real' qh without stopping the async schedule [4.8].  use it
-	 * as the 'reclamation list head' too.
-	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
-	 * from automatically advancing to the next td after short reads.
-	 */
-	fusbh200->async->qh_next.qh = NULL;
-	hw = fusbh200->async->hw;
-	hw->hw_next = QH_NEXT(fusbh200, fusbh200->async->qh_dma);
-	hw->hw_info1 = cpu_to_hc32(fusbh200, QH_HEAD);
-	hw->hw_token = cpu_to_hc32(fusbh200, QTD_STS_HALT);
-	hw->hw_qtd_next = FUSBH200_LIST_END(fusbh200);
-	fusbh200->async->qh_state = QH_STATE_LINKED;
-	hw->hw_alt_next = QTD_NEXT(fusbh200, fusbh200->async->dummy->qtd_dma);
-
-	/* clear interrupt enables, set irq latency */
-	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
-		log2_irq_thresh = 0;
-	temp = 1 << (16 + log2_irq_thresh);
-	if (HCC_CANPARK(hcc_params)) {
-		/* HW default park == 3, on hardware that supports it (like
-		 * NVidia and ALI silicon), maximizes throughput on the async
-		 * schedule by avoiding QH fetches between transfers.
-		 *
-		 * With fast usb storage devices and NForce2, "park" seems to
-		 * make problems:  throughput reduction (!), data errors...
-		 */
-		if (park) {
-			park = min(park, (unsigned) 3);
-			temp |= CMD_PARK;
-			temp |= park << 8;
-		}
-		fusbh200_dbg(fusbh200, "park %d\n", park);
-	}
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		temp &= ~(3 << 2);
-		temp |= (FUSBH200_TUNE_FLS << 2);
-	}
-	fusbh200->command = temp;
-
-	/* Accept arbitrarily long scatter-gather lists */
-	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
-		hcd->self.sg_tablesize = ~0;
-	return 0;
-}
-
-/* start HC running; it's halted, hcd_fusbh200_init() has been run (once) */
-static int fusbh200_run (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32			temp;
-	u32			hcc_params;
-
-	hcd->uses_new_polling = 1;
-
-	/* EHCI spec section 4.1 */
-
-	fusbh200_writel(fusbh200, fusbh200->periodic_dma, &fusbh200->regs->frame_list);
-	fusbh200_writel(fusbh200, (u32)fusbh200->async->qh_dma, &fusbh200->regs->async_next);
-
-	/*
-	 * hcc_params controls whether fusbh200->regs->segment must (!!!)
-	 * be used; it constrains QH/ITD/SITD and QTD locations.
-	 * pci_pool consistent memory always uses segment zero.
-	 * streaming mappings for I/O buffers, like pci_map_single(),
-	 * can return segments above 4GB, if the device allows.
-	 *
-	 * NOTE:  the dma mask is visible through dma_supported(), so
-	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
-	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
-	 * host side drivers though.
-	 */
-	hcc_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	// Philips, Intel, and maybe others need CMD_RUN before the
-	// root hub will detect new devices (why?); NEC doesn't
-	fusbh200->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-	fusbh200->command |= CMD_RUN;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-	dbg_cmd (fusbh200, "init", fusbh200->command);
-
-	/*
-	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
-	 * are explicitly handed to companion controller(s), so no TT is
-	 * involved with the root hub.  (Except where one is integrated,
-	 * and there's no companion controller unless maybe for USB OTG.)
-	 *
-	 * Turning on the CF flag will transfer ownership of all ports
-	 * from the companions to the EHCI controller.  If any of the
-	 * companions are in the middle of a port reset at the time, it
-	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
-	 * guarantees that no resets are in progress.  After we set CF,
-	 * a short delay lets the hardware catch up; new resets shouldn't
-	 * be started before the port switching actions could complete.
-	 */
-	down_write(&ehci_cf_port_reset_rwsem);
-	fusbh200->rh_state = FUSBH200_RH_RUNNING;
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted writes */
-	msleep(5);
-	up_write(&ehci_cf_port_reset_rwsem);
-	fusbh200->last_periodic_enable = ktime_get_real();
-
-	temp = HC_VERSION(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	fusbh200_info (fusbh200,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fusbh200->sbrn & 0xf0)>>4), (fusbh200->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
-
-	fusbh200_writel(fusbh200, INTR_MASK,
-		    &fusbh200->regs->intr_enable); /* Turn On Interrupts */
-
-	/* GRR this is run-once init(), being done every time the HC starts.
-	 * So long as they're part of class devices, we can't do it init()
-	 * since the class device isn't created that early.
-	 */
-	create_debug_files(fusbh200);
-	create_sysfs_files(fusbh200);
-
-	return 0;
-}
-
-static int fusbh200_setup(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd *fusbh200 = hcd_to_fusbh200(hcd);
-	int retval;
-
-	fusbh200->regs = (void __iomem *)fusbh200->caps +
-	    HC_LENGTH(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	dbg_hcs_params(fusbh200, "reset");
-	dbg_hcc_params(fusbh200, "reset");
-
-	/* cache this readonly data; minimize chip reads */
-	fusbh200->hcs_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-
-	fusbh200->sbrn = HCD_USB2;
-
-	/* data structure init */
-	retval = hcd_fusbh200_init(hcd);
-	if (retval)
-		return retval;
-
-	retval = fusbh200_halt(fusbh200);
-	if (retval)
-		return retval;
-
-	fusbh200_reset(fusbh200);
-
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static irqreturn_t fusbh200_irq (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
-
-	spin_lock (&fusbh200->lock);
-
-	status = fusbh200_readl(fusbh200, &fusbh200->regs->status);
-
-	/* e.g. cardbus physical eject */
-	if (status == ~(u32) 0) {
-		fusbh200_dbg (fusbh200, "device removed\n");
-		goto dead;
-	}
-
-	/*
-	 * We don't use STS_FLR, but some controllers don't like it to
-	 * remain on, so mask it out along with the other status bits.
-	 */
-	masked_status = status & (INTR_MASK | STS_FLR);
-
-	/* Shared IRQ? */
-	if (!masked_status || unlikely(fusbh200->rh_state == FUSBH200_RH_HALTED)) {
-		spin_unlock(&fusbh200->lock);
-		return IRQ_NONE;
-	}
-
-	/* clear (just) interrupts */
-	fusbh200_writel(fusbh200, masked_status, &fusbh200->regs->status);
-	cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-	bh = 0;
-
-	/* normal [4.15.1.2] or error [4.15.1.1] completion */
-	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
-		if (likely ((status & STS_ERR) == 0))
-			COUNT (fusbh200->stats.normal);
-		else
-			COUNT (fusbh200->stats.error);
-		bh = 1;
-	}
-
-	/* complete the unlinking of some qh [4.15.2.3] */
-	if (status & STS_IAA) {
-
-		/* Turn off the IAA watchdog */
-		fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_IAA_WATCHDOG);
-
-		/*
-		 * Mild optimization: Allow another IAAD to reset the
-		 * hrtimer, if one occurs before the next expiration.
-		 * In theory we could always cancel the hrtimer, but
-		 * tests show that about half the time it will be reset
-		 * for some other event anyway.
-		 */
-		if (fusbh200->next_hrtimer_event == FUSBH200_HRTIMER_IAA_WATCHDOG)
-			++fusbh200->next_hrtimer_event;
-
-		/* guard against (alleged) silicon errata */
-		if (cmd & CMD_IAAD)
-			fusbh200_dbg(fusbh200, "IAA with IAAD still set?\n");
-		if (fusbh200->async_iaa) {
-			COUNT(fusbh200->stats.iaa);
-			end_unlink_async(fusbh200);
-		} else
-			fusbh200_dbg(fusbh200, "IAA with nothing unlinked?\n");
-	}
-
-	/* remote wakeup [4.3.1] */
-	if (status & STS_PCD) {
-		int pstatus;
-		u32 __iomem *status_reg = &fusbh200->regs->port_status;
-
-		/* kick root hub later */
-		pcd_status = status;
-
-		/* resume root hub? */
-		if (fusbh200->rh_state == FUSBH200_RH_SUSPENDED)
-			usb_hcd_resume_root_hub(hcd);
-
-		pstatus = fusbh200_readl(fusbh200, status_reg);
-
-		if (test_bit(0, &fusbh200->suspended_ports) &&
-				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
-				(pstatus & PORT_PE) &&
-				fusbh200->reset_done[0] == 0) {
-
-			/* start 20 msec resume signaling from this port,
-			 * and make hub_wq collect PORT_STAT_C_SUSPEND to
-			 * stop that signaling.  Use 5 ms extra for safety,
-			 * like usb_port_resume() does.
-			 */
-			fusbh200->reset_done[0] = jiffies + msecs_to_jiffies(25);
-			set_bit(0, &fusbh200->resuming_ports);
-			fusbh200_dbg (fusbh200, "port 1 remote wakeup\n");
-			mod_timer(&hcd->rh_timer, fusbh200->reset_done[0]);
-		}
-	}
-
-	/* PCI errors [4.15.2.4] */
-	if (unlikely ((status & STS_FATAL) != 0)) {
-		fusbh200_err(fusbh200, "fatal error\n");
-		dbg_cmd(fusbh200, "fatal", cmd);
-		dbg_status(fusbh200, "fatal", status);
-dead:
-		usb_hc_died(hcd);
-
-		/* Don't let the controller do anything more */
-		fusbh200->shutdown = true;
-		fusbh200->rh_state = FUSBH200_RH_STOPPING;
-		fusbh200->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-		fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-		fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-		fusbh200_handle_controller_death(fusbh200);
-
-		/* Handle completions when the controller stops */
-		bh = 0;
-	}
-
-	if (bh)
-		fusbh200_work (fusbh200);
-	spin_unlock (&fusbh200->lock);
-	if (pcd_status)
-		usb_hcd_poll_rh_status(hcd);
-	return IRQ_HANDLED;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * non-error returns are a promise to giveback() the urb later
- * we drop ownership so next owner (or urb unlink) can get it
- *
- * urb + dev is in hcd.self.controller.urb_list
- * we're queueing TDs onto software and hardware lists
- *
- * hcd-specific init for hcpriv hasn't been done yet
- *
- * NOTE:  control, bulk, and interrupt share the same code to append TDs
- * to a (possibly active) QH, and the same QH scanning code.
- */
-static int fusbh200_urb_enqueue (
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	struct list_head	qtd_list;
-
-	INIT_LIST_HEAD (&qtd_list);
-
-	switch (usb_pipetype (urb->pipe)) {
-	case PIPE_CONTROL:
-		/* qh_completions() code doesn't handle all the fault cases
-		 * in multi-TD control transfers.  Even 1KB is rare anyway.
-		 */
-		if (urb->transfer_buffer_length > (16 * 1024))
-			return -EMSGSIZE;
-		/* FALLTHROUGH */
-	/* case PIPE_BULK: */
-	default:
-		if (!qh_urb_transaction (fusbh200, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return submit_async(fusbh200, urb, &qtd_list, mem_flags);
-
-	case PIPE_INTERRUPT:
-		if (!qh_urb_transaction (fusbh200, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return intr_submit(fusbh200, urb, &qtd_list, mem_flags);
-
-	case PIPE_ISOCHRONOUS:
-		return itd_submit (fusbh200, urb, mem_flags);
-	}
-}
-
-/* remove from hardware lists
- * completions normally happen asynchronously
- */
-
-static int fusbh200_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	struct fusbh200_qh		*qh;
-	unsigned long		flags;
-	int			rc;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-	if (rc)
-		goto done;
-
-	switch (usb_pipetype (urb->pipe)) {
-	// case PIPE_CONTROL:
-	// case PIPE_BULK:
-	default:
-		qh = (struct fusbh200_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_async(fusbh200, qh);
-			break;
-		case QH_STATE_UNLINK:
-		case QH_STATE_UNLINK_WAIT:
-			/* already started */
-			break;
-		case QH_STATE_IDLE:
-			/* QH might be waiting for a Clear-TT-Buffer */
-			qh_completions(fusbh200, qh);
-			break;
-		}
-		break;
-
-	case PIPE_INTERRUPT:
-		qh = (struct fusbh200_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_intr(fusbh200, qh);
-			break;
-		case QH_STATE_IDLE:
-			qh_completions (fusbh200, qh);
-			break;
-		default:
-			fusbh200_dbg (fusbh200, "bogus qh %p state %d\n",
-					qh, qh->qh_state);
-			goto done;
-		}
-		break;
-
-	case PIPE_ISOCHRONOUS:
-		// itd...
-
-		// wait till next completion, do it then.
-		// completion irqs can wait up to 1024 msec,
-		break;
-	}
-done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return rc;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// bulk qh holds the data toggle
-
-static void
-fusbh200_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	unsigned long		flags;
-	struct fusbh200_qh		*qh, *tmp;
-
-	/* ASSERT:  any requests/urbs are being unlinked */
-	/* ASSERT:  nobody can be submitting urbs for this any more */
-
-rescan:
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	qh = ep->hcpriv;
-	if (!qh)
-		goto done;
-
-	/* endpoints can be iso streams.  for now, we don't
-	 * accelerate iso completions ... so spin a while.
-	 */
-	if (qh->hw == NULL) {
-		struct fusbh200_iso_stream	*stream = ep->hcpriv;
-
-		if (!list_empty(&stream->td_list))
-			goto idle_timeout;
-
-		/* BUG_ON(!list_empty(&stream->free_list)); */
-		kfree(stream);
-		goto done;
-	}
-
-	if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-		qh->qh_state = QH_STATE_IDLE;
-	switch (qh->qh_state) {
-	case QH_STATE_LINKED:
-	case QH_STATE_COMPLETING:
-		for (tmp = fusbh200->async->qh_next.qh;
-				tmp && tmp != qh;
-				tmp = tmp->qh_next.qh)
-			continue;
-		/* periodic qh self-unlinks on empty, and a COMPLETING qh
-		 * may already be unlinked.
-		 */
-		if (tmp)
-			start_unlink_async(fusbh200, qh);
-		/* FALL THROUGH */
-	case QH_STATE_UNLINK:		/* wait for hw to finish? */
-	case QH_STATE_UNLINK_WAIT:
-idle_timeout:
-		spin_unlock_irqrestore (&fusbh200->lock, flags);
-		schedule_timeout_uninterruptible(1);
-		goto rescan;
-	case QH_STATE_IDLE:		/* fully unlinked */
-		if (qh->clearing_tt)
-			goto idle_timeout;
-		if (list_empty (&qh->qtd_list)) {
-			qh_destroy(fusbh200, qh);
-			break;
-		}
-		/* else FALL THROUGH */
-	default:
-		/* caller was supposed to have unlinked any requests;
-		 * that's not our job.  just leak this memory.
-		 */
-		fusbh200_err (fusbh200, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty (&qh->qtd_list) ? "" : "(has tds)");
-		break;
-	}
- done:
-	ep->hcpriv = NULL;
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-}
-
-static void
-fusbh200_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	struct fusbh200_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
-
-	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
-		return;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-	qh = ep->hcpriv;
-
-	/* For Bulk and Interrupt endpoints we maintain the toggle state
-	 * in the hardware; the toggle bits in udev aren't used at all.
-	 * When an endpoint is reset by usb_clear_halt() we must reset
-	 * the toggle bit in the QH.
-	 */
-	if (qh) {
-		usb_settoggle(qh->dev, epnum, is_out, 0);
-		if (!list_empty(&qh->qtd_list)) {
-			WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-		} else if (qh->qh_state == QH_STATE_LINKED ||
-				qh->qh_state == QH_STATE_COMPLETING) {
-
-			/* The toggle value in the QH can't be updated
-			 * while the QH is active.  Unlink it now;
-			 * re-linking will call qh_refresh().
-			 */
-			if (eptype == USB_ENDPOINT_XFER_BULK)
-				start_unlink_async(fusbh200, qh);
-			else
-				start_unlink_intr(fusbh200, qh);
-		}
-	}
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-}
-
-static int fusbh200_get_frame (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	return (fusbh200_read_frame_index(fusbh200) >> 3) % fusbh200->periodic_size;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * 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 fusbh200 driver exclusive access to those.
- */
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_LICENSE ("GPL");
-
-static const struct hc_driver fusbh200_fusbh200_hc_driver = {
-	.description 		= hcd_name,
-	.product_desc 		= "Faraday USB2.0 Host Controller",
-	.hcd_priv_size 		= sizeof(struct fusbh200_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq 			= fusbh200_irq,
-	.flags 			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset 			= hcd_fusbh200_init,
-	.start 			= fusbh200_run,
-	.stop 			= fusbh200_stop,
-	.shutdown 		= fusbh200_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue 		= fusbh200_urb_enqueue,
-	.urb_dequeue 		= fusbh200_urb_dequeue,
-	.endpoint_disable 	= fusbh200_endpoint_disable,
-	.endpoint_reset 	= fusbh200_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number 	= fusbh200_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data 	= fusbh200_hub_status_data,
-	.hub_control 		= fusbh200_hub_control,
-	.bus_suspend 		= fusbh200_bus_suspend,
-	.bus_resume 		= fusbh200_bus_resume,
-
-	.relinquish_port 	= fusbh200_relinquish_port,
-	.port_handed_over 	= fusbh200_port_handed_over,
-
-	.clear_tt_buffer_complete = fusbh200_clear_tt_buffer_complete,
-};
-
-static void fusbh200_init(struct fusbh200_hcd *fusbh200)
-{
-	u32 reg;
-
-	reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmcsr);
-	reg |= BMCSR_INT_POLARITY;
-	reg &= ~BMCSR_VBUS_OFF;
-	fusbh200_writel(fusbh200, reg, &fusbh200->regs->bmcsr);
-
-	reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmier);
-	fusbh200_writel(fusbh200, reg | BMIER_OVC_EN | BMIER_VBUS_ERR_EN,
-		&fusbh200->regs->bmier);
-}
-
-/**
- * fusbh200_hcd_probe - initialize faraday FUSBH200 HCDs
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- */
-static int fusbh200_hcd_probe(struct platform_device *pdev)
-{
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd 			*hcd;
-	struct resource			*res;
-	int 				irq;
-	int 				retval = -ENODEV;
-	struct fusbh200_hcd 		*fusbh200;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
-		return -ENODEV;
-	}
-
-	irq = res->start;
-
-	hcd = usb_create_hcd(&fusbh200_fusbh200_hc_driver, dev,
-			dev_name(dev));
-	if (!hcd) {
-		dev_err(dev, "failed to create hcd with err %d\n", retval);
-		retval = -ENOMEM;
-		goto fail_create_hcd;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no register addr. Check %s setup!\n",
-			dev_name(dev));
-		retval = -ENODEV;
-		goto fail_request_resource;
-	}
-
-	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = resource_size(res);
-	hcd->has_tt = 1;
-
-	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
-				fusbh200_fusbh200_hc_driver.description)) {
-		dev_dbg(dev, "controller already in use\n");
-		retval = -EBUSY;
-		goto fail_request_resource;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no register addr. Check %s setup!\n",
-			dev_name(dev));
-		retval = -ENODEV;
-		goto fail_request_resource;
-	}
-
-	hcd->regs = ioremap_nocache(res->start, resource_size(res));
-	if (hcd->regs == NULL) {
-		dev_dbg(dev, "error mapping memory\n");
-		retval = -EFAULT;
-		goto fail_ioremap;
-	}
-
-	fusbh200 = hcd_to_fusbh200(hcd);
-
-	fusbh200->caps = hcd->regs;
-
-	retval = fusbh200_setup(hcd);
-	if (retval)
-		goto fail_add_hcd;
-
-	fusbh200_init(fusbh200);
-
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-	if (retval) {
-		dev_err(dev, "failed to add hcd with err %d\n", retval);
-		goto fail_add_hcd;
-	}
-	device_wakeup_enable(hcd->self.controller);
-
-	return retval;
-
-fail_add_hcd:
-	iounmap(hcd->regs);
-fail_ioremap:
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
-	usb_put_hcd(hcd);
-fail_create_hcd:
-	dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
-	return retval;
-}
-
-/**
- * fusbh200_hcd_remove - shutdown processing for EHCI HCDs
- * @dev: USB Host Controller being removed
- *
- * Reverses the effect of fotg2xx_usb_hcd_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- */
-static int fusbh200_hcd_remove(struct platform_device *pdev)
-{
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
-
-	if (!hcd)
-		return 0;
-
-	usb_remove_hcd(hcd);
-	iounmap(hcd->regs);
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-	usb_put_hcd(hcd);
-
-	return 0;
-}
-
-static struct platform_driver fusbh200_hcd_fusbh200_driver = {
-	.driver = {
-		.name   = "fusbh200",
-	},
-	.probe  = fusbh200_hcd_probe,
-	.remove = fusbh200_hcd_remove,
-};
-
-static int __init fusbh200_hcd_init(void)
-{
-	int retval = 0;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
-	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
-			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		printk(KERN_WARNING "Warning! fusbh200_hcd should always be loaded"
-				" before uhci_hcd and ohci_hcd, not after\n");
-
-	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fusbh200_qh), sizeof(struct fusbh200_qtd),
-		 sizeof(struct fusbh200_itd));
-
-	fusbh200_debug_root = debugfs_create_dir("fusbh200", usb_debug_root);
-	if (!fusbh200_debug_root) {
-		retval = -ENOENT;
-		goto err_debug;
-	}
-
-	retval = platform_driver_register(&fusbh200_hcd_fusbh200_driver);
-	if (retval < 0)
-		goto clean;
-	return retval;
-
-	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);
-clean:
-	debugfs_remove(fusbh200_debug_root);
-	fusbh200_debug_root = NULL;
-err_debug:
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	return retval;
-}
-module_init(fusbh200_hcd_init);
-
-static void __exit fusbh200_hcd_cleanup(void)
-{
-	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);
-	debugfs_remove(fusbh200_debug_root);
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-}
-module_exit(fusbh200_hcd_cleanup);
diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h
deleted file mode 100644
index d6e5b3d4aa68b7bd9378594fd5fcbcacbe90de4a..0000000000000000000000000000000000000000
--- a/drivers/usb/host/fusbh200.h
+++ /dev/null
@@ -1,675 +0,0 @@
-#ifndef __LINUX_FUSBH200_H
-#define __LINUX_FUSBH200_H
-
-#include <linux/usb/ehci-dbgp.h>
-
-/* definitions used for the EHCI driver */
-
-/*
- * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
- * __leXX (normally) or __beXX (given FUSBH200_BIG_ENDIAN_DESC), depending on
- * the host controller implementation.
- *
- * To facilitate the strongest possible byte-order checking from "sparse"
- * and so on, we use __leXX unless that's not practical.
- */
-#define __hc32	__le32
-#define __hc16	__le16
-
-/* statistics can be kept for tuning/monitoring */
-struct fusbh200_stats {
-	/* irq usage */
-	unsigned long		normal;
-	unsigned long		error;
-	unsigned long		iaa;
-	unsigned long		lost_iaa;
-
-	/* termination of urbs from core */
-	unsigned long		complete;
-	unsigned long		unlink;
-};
-
-/* fusbh200_hcd->lock guards shared data against other CPUs:
- *   fusbh200_hcd:	async, unlink, periodic (and shadow), ...
- *   usb_host_endpoint: hcpriv
- *   fusbh200_qh:	qh_next, qtd_list
- *   fusbh200_qtd:	qtd_list
- *
- * Also, hold this lock when talking to HC registers or
- * when updating hw_* fields in shared qh/qtd/... structures.
- */
-
-#define	FUSBH200_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
-
-/*
- * fusbh200_rh_state values of FUSBH200_RH_RUNNING or above mean that the
- * controller may be doing DMA.  Lower values mean there's no DMA.
- */
-enum fusbh200_rh_state {
-	FUSBH200_RH_HALTED,
-	FUSBH200_RH_SUSPENDED,
-	FUSBH200_RH_RUNNING,
-	FUSBH200_RH_STOPPING
-};
-
-/*
- * Timer events, ordered by increasing delay length.
- * Always update event_delays_ns[] and event_handlers[] (defined in
- * ehci-timer.c) in parallel with this list.
- */
-enum fusbh200_hrtimer_event {
-	FUSBH200_HRTIMER_POLL_ASS,		/* Poll for async schedule off */
-	FUSBH200_HRTIMER_POLL_PSS,		/* Poll for periodic schedule off */
-	FUSBH200_HRTIMER_POLL_DEAD,		/* Wait for dead controller to stop */
-	FUSBH200_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
-	FUSBH200_HRTIMER_FREE_ITDS,		/* Wait for unused iTDs and siTDs */
-	FUSBH200_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
-	FUSBH200_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
-	FUSBH200_HRTIMER_DISABLE_PERIODIC,	/* Wait to disable periodic sched */
-	FUSBH200_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
-	FUSBH200_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
-	FUSBH200_HRTIMER_NUM_EVENTS		/* Must come last */
-};
-#define FUSBH200_HRTIMER_NO_EVENT	99
-
-struct fusbh200_hcd {			/* one per controller */
-	/* timing support */
-	enum fusbh200_hrtimer_event	next_hrtimer_event;
-	unsigned		enabled_hrtimer_events;
-	ktime_t			hr_timeouts[FUSBH200_HRTIMER_NUM_EVENTS];
-	struct hrtimer		hrtimer;
-
-	int			PSS_poll_count;
-	int			ASS_poll_count;
-	int			died_poll_count;
-
-	/* glue to PCI and HCD framework */
-	struct fusbh200_caps __iomem *caps;
-	struct fusbh200_regs __iomem *regs;
-	struct ehci_dbg_port __iomem *debug;
-
-	__u32			hcs_params;	/* cached register copy */
-	spinlock_t		lock;
-	enum fusbh200_rh_state	rh_state;
-
-	/* general schedule support */
-	bool			scanning:1;
-	bool			need_rescan:1;
-	bool			intr_unlinking:1;
-	bool			async_unlinking:1;
-	bool			shutdown:1;
-	struct fusbh200_qh		*qh_scan_next;
-
-	/* async schedule support */
-	struct fusbh200_qh		*async;
-	struct fusbh200_qh		*dummy;		/* For AMD quirk use */
-	struct fusbh200_qh		*async_unlink;
-	struct fusbh200_qh		*async_unlink_last;
-	struct fusbh200_qh		*async_iaa;
-	unsigned		async_unlink_cycle;
-	unsigned		async_count;	/* async activity count */
-
-	/* periodic schedule support */
-#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */
-	unsigned		periodic_size;
-	__hc32			*periodic;	/* hw periodic table */
-	dma_addr_t		periodic_dma;
-	struct list_head	intr_qh_list;
-	unsigned		i_thresh;	/* uframes HC might cache */
-
-	union fusbh200_shadow	*pshadow;	/* mirror hw periodic table */
-	struct fusbh200_qh		*intr_unlink;
-	struct fusbh200_qh		*intr_unlink_last;
-	unsigned		intr_unlink_cycle;
-	unsigned		now_frame;	/* frame from HC hardware */
-	unsigned		next_frame;	/* scan periodic, start here */
-	unsigned		intr_count;	/* intr activity count */
-	unsigned		isoc_count;	/* isoc activity count */
-	unsigned		periodic_count;	/* periodic activity count */
-	unsigned		uframe_periodic_max; /* max periodic time per uframe */
-
-
-	/* list of itds completed while now_frame was still active */
-	struct list_head	cached_itd_list;
-	struct fusbh200_itd	*last_itd_to_free;
-
-	/* per root hub port */
-	unsigned long		reset_done [FUSBH200_MAX_ROOT_PORTS];
-
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
-
-	/* per-HC memory pools (could be per-bus, but ...) */
-	struct dma_pool		*qh_pool;	/* qh per active urb */
-	struct dma_pool		*qtd_pool;	/* one or more per qh */
-	struct dma_pool		*itd_pool;	/* itd per iso urb */
-
-	unsigned		random_frame;
-	unsigned long		next_statechange;
-	ktime_t			last_periodic_enable;
-	u32			command;
-
-	/* SILICON QUIRKS */
-	unsigned		need_io_watchdog:1;
-	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
-
-	u8			sbrn;		/* packed release number */
-
-	/* irq statistics */
-	struct fusbh200_stats	stats;
-#	define COUNT(x) do { (x)++; } while (0)
-
-	/* debug files */
-	struct dentry		*debug_dir;
-};
-
-/* convert between an HCD pointer and the corresponding FUSBH200_HCD */
-static inline struct fusbh200_hcd *hcd_to_fusbh200 (struct usb_hcd *hcd)
-{
-	return (struct fusbh200_hcd *) (hcd->hcd_priv);
-}
-static inline struct usb_hcd *fusbh200_to_hcd (struct fusbh200_hcd *fusbh200)
-{
-	return container_of ((void *) fusbh200, struct usb_hcd, hcd_priv);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-
-/* Section 2.2 Host Controller Capability Registers */
-struct fusbh200_caps {
-	/* these fields are specified as 8 and 16 bit registers,
-	 * but some hosts can't perform 8 or 16 bit PCI accesses.
-	 * some hosts treat caplength and hciversion as parts of a 32-bit
-	 * register, others treat them as two separate registers, this
-	 * affects the memory map for big endian controllers.
-	 */
-	u32		hc_capbase;
-#define HC_LENGTH(fusbh200, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-				(fusbh200_big_endian_capbase(fusbh200) ? 24 : 0)))
-#define HC_VERSION(fusbh200, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-				(fusbh200_big_endian_capbase(fusbh200) ? 0 : 16)))
-	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
-#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
-
-	u32		hcc_params;      /* HCCPARAMS - offset 0x8 */
-#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */
-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
-	u8		portroute[8];	 /* nibbles for routing - offset 0xC */
-};
-
-
-/* Section 2.3 Host Controller Operational Registers */
-struct fusbh200_regs {
-
-	/* USBCMD: offset 0x00 */
-	u32		command;
-
-/* EHCI 1.1 addendum */
-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
-#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
-#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
-#define CMD_ASE		(1<<5)		/* async schedule enable */
-#define CMD_PSE		(1<<4)		/* periodic schedule enable */
-/* 3:2 is periodic frame list size */
-#define CMD_RESET	(1<<1)		/* reset HC not bus */
-#define CMD_RUN		(1<<0)		/* start/stop HC */
-
-	/* USBSTS: offset 0x04 */
-	u32		status;
-#define STS_ASS		(1<<15)		/* Async Schedule Status */
-#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
-#define STS_RECL	(1<<13)		/* Reclamation */
-#define STS_HALT	(1<<12)		/* Not running (any reason) */
-/* some bits reserved */
-	/* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA		(1<<5)		/* Interrupted on async advance */
-#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
-#define STS_FLR		(1<<3)		/* frame list rolled over */
-#define STS_PCD		(1<<2)		/* port change detect */
-#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
-#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
-
-	/* USBINTR: offset 0x08 */
-	u32		intr_enable;
-
-	/* FRINDEX: offset 0x0C */
-	u32		frame_index;	/* current microframe number */
-	/* CTRLDSSEGMENT: offset 0x10 */
-	u32		segment;	/* address bits 63:32 if needed */
-	/* PERIODICLISTBASE: offset 0x14 */
-	u32		frame_list;	/* points to periodic list */
-	/* ASYNCLISTADDR: offset 0x18 */
-	u32		async_next;	/* address of next async queue head */
-
-	u32	reserved1;
-	/* PORTSC: offset 0x20 */
-	u32	port_status;
-/* 31:23 reserved */
-#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10))	/* USB 1.1 device */
-#define PORT_RESET	(1<<8)		/* reset port */
-#define PORT_SUSPEND	(1<<7)		/* suspend port */
-#define PORT_RESUME	(1<<6)		/* resume it */
-#define PORT_PEC	(1<<3)		/* port enable change */
-#define PORT_PE		(1<<2)		/* port enable */
-#define PORT_CSC	(1<<1)		/* connect status change */
-#define PORT_CONNECT	(1<<0)		/* device connected */
-#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
-
-	u32	reserved2[3];
-
-	/* BMCSR: offset 0x30 */
-	u32	bmcsr; /* Bus Moniter Control/Status Register */
-#define BMCSR_HOST_SPD_TYP	(3<<9)
-#define BMCSR_VBUS_OFF		(1<<4)
-#define BMCSR_INT_POLARITY	(1<<3)
-
-	/* BMISR: offset 0x34 */
-	u32	bmisr; /* Bus Moniter Interrupt Status Register*/
-#define BMISR_OVC		(1<<1)
-
-	/* BMIER: offset 0x38 */
-	u32	bmier; /* Bus Moniter Interrupt Enable Register */
-#define BMIER_OVC_EN		(1<<1)
-#define BMIER_VBUS_ERR_EN	(1<<0)
-};
-
-/*-------------------------------------------------------------------------*/
-
-#define	QTD_NEXT(fusbh200, dma)	cpu_to_hc32(fusbh200, (u32)dma)
-
-/*
- * EHCI Specification 0.95 Section 3.5
- * QTD: describe data transfer components (buffer, direction, ...)
- * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
- *
- * These are associated only with "QH" (Queue Head) structures,
- * used with control, bulk, and interrupt transfers.
- */
-struct fusbh200_qtd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;	/* see EHCI 3.5.1 */
-	__hc32			hw_alt_next;    /* see EHCI 3.5.2 */
-	__hc32			hw_token;       /* see EHCI 3.5.3 */
-#define	QTD_TOGGLE	(1 << 31)	/* data toggle */
-#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
-#define	QTD_IOC		(1 << 15)	/* interrupt on complete */
-#define	QTD_CERR(tok)	(((tok)>>10) & 0x3)
-#define	QTD_PID(tok)	(((tok)>>8) & 0x3)
-#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
-#define	QTD_STS_HALT	(1 << 6)	/* halted on error */
-#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
-#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */
-#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */
-#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */
-#define	QTD_STS_STS	(1 << 1)	/* split transaction state */
-#define	QTD_STS_PING	(1 << 0)	/* issue PING? */
-
-#define ACTIVE_BIT(fusbh200)	cpu_to_hc32(fusbh200, QTD_STS_ACTIVE)
-#define HALT_BIT(fusbh200)		cpu_to_hc32(fusbh200, QTD_STS_HALT)
-#define STATUS_BIT(fusbh200)	cpu_to_hc32(fusbh200, QTD_STS_STS)
-
-	__hc32			hw_buf [5];        /* see EHCI 3.5.4 */
-	__hc32			hw_buf_hi [5];        /* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		qtd_dma;		/* qtd address */
-	struct list_head	qtd_list;		/* sw qtd list */
-	struct urb		*urb;			/* qtd's urb */
-	size_t			length;			/* length of buffer */
-} __attribute__ ((aligned (32)));
-
-/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK(fusbh200)	cpu_to_hc32 (fusbh200, ~0x1f)
-
-#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
-
-/*-------------------------------------------------------------------------*/
-
-/* type tag from {qh,itd,fstn}->hw_next */
-#define Q_NEXT_TYPE(fusbh200,dma)	((dma) & cpu_to_hc32(fusbh200, 3 << 1))
-
-/*
- * Now the following defines are not converted using the
- * cpu_to_le32() macro anymore, since we have to support
- * "dynamic" switching between be and le support, so that the driver
- * can be used on one system with SoC EHCI controller using big-endian
- * descriptors as well as a normal little-endian PCI EHCI controller.
- */
-/* values for that type tag */
-#define Q_TYPE_ITD	(0 << 1)
-#define Q_TYPE_QH	(1 << 1)
-#define Q_TYPE_SITD	(2 << 1)
-#define Q_TYPE_FSTN	(3 << 1)
-
-/* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(fusbh200,dma)	(cpu_to_hc32(fusbh200, (((u32)dma)&~0x01f)|Q_TYPE_QH))
-
-/* for periodic/async schedules and qtd lists, mark end of list */
-#define FUSBH200_LIST_END(fusbh200)	cpu_to_hc32(fusbh200, 1) /* "null pointer" to hw */
-
-/*
- * Entries in periodic shadow table are pointers to one of four kinds
- * of data structure.  That's dictated by the hardware; a type tag is
- * encoded in the low bits of the hardware's periodic schedule.  Use
- * Q_NEXT_TYPE to get the tag.
- *
- * For entries in the async schedule, the type tag always says "qh".
- */
-union fusbh200_shadow {
-	struct fusbh200_qh	*qh;		/* Q_TYPE_QH */
-	struct fusbh200_itd	*itd;		/* Q_TYPE_ITD */
-	struct fusbh200_fstn	*fstn;		/* Q_TYPE_FSTN */
-	__hc32			*hw_next;	/* (all types) */
-	void			*ptr;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.6
- * QH: describes control/bulk/interrupt endpoints
- * See Fig 3-7 "Queue Head Structure Layout".
- *
- * These appear in both the async and (for interrupt) periodic schedules.
- */
-
-/* first part defined by EHCI spec */
-struct fusbh200_qh_hw {
-	__hc32			hw_next;	/* see EHCI 3.6.1 */
-	__hc32			hw_info1;       /* see EHCI 3.6.2 */
-#define	QH_CONTROL_EP	(1 << 27)	/* FS/LS control endpoint */
-#define	QH_HEAD		(1 << 15)	/* Head of async reclamation list */
-#define	QH_TOGGLE_CTL	(1 << 14)	/* Data toggle control */
-#define	QH_HIGH_SPEED	(2 << 12)	/* Endpoint speed */
-#define	QH_LOW_SPEED	(1 << 12)
-#define	QH_FULL_SPEED	(0 << 12)
-#define	QH_INACTIVATE	(1 << 7)	/* Inactivate on next transaction */
-	__hc32			hw_info2;        /* see EHCI 3.6.2 */
-#define	QH_SMASK	0x000000ff
-#define	QH_CMASK	0x0000ff00
-#define	QH_HUBADDR	0x007f0000
-#define	QH_HUBPORT	0x3f800000
-#define	QH_MULT		0xc0000000
-	__hc32			hw_current;	/* qtd list - see EHCI 3.6.4 */
-
-	/* qtd overlay (hardware parts of a struct fusbh200_qtd) */
-	__hc32			hw_qtd_next;
-	__hc32			hw_alt_next;
-	__hc32			hw_token;
-	__hc32			hw_buf [5];
-	__hc32			hw_buf_hi [5];
-} __attribute__ ((aligned(32)));
-
-struct fusbh200_qh {
-	struct fusbh200_qh_hw	*hw;		/* Must come first */
-	/* the rest is HCD-private */
-	dma_addr_t		qh_dma;		/* address of qh */
-	union fusbh200_shadow	qh_next;	/* ptr to qh; or periodic */
-	struct list_head	qtd_list;	/* sw qtd list */
-	struct list_head	intr_node;	/* list of intr QHs */
-	struct fusbh200_qtd		*dummy;
-	struct fusbh200_qh		*unlink_next;	/* next on unlink list */
-
-	unsigned		unlink_cycle;
-
-	u8			needs_rescan;	/* Dequeue during giveback */
-	u8			qh_state;
-#define	QH_STATE_LINKED		1		/* HC sees this */
-#define	QH_STATE_UNLINK		2		/* HC may still see this */
-#define	QH_STATE_IDLE		3		/* HC doesn't see this */
-#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on unlink q */
-#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */
-
-	u8			xacterrs;	/* XactErr retry counter */
-#define	QH_XACTERR_MAX		32		/* XactErr retry limit */
-
-	/* periodic schedule info */
-	u8			usecs;		/* intr bandwidth */
-	u8			gap_uf;		/* uframes split/csplit gap */
-	u8			c_usecs;	/* ... split completion bw */
-	u16			tt_usecs;	/* tt downstream bandwidth */
-	unsigned short		period;		/* polling interval */
-	unsigned short		start;		/* where polling starts */
-#define NO_FRAME ((unsigned short)~0)			/* pick new start */
-
-	struct usb_device	*dev;		/* access to TT */
-	unsigned		is_out:1;	/* bulk or intr OUT */
-	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* description of one iso transaction (up to 3 KB data if highspeed) */
-struct fusbh200_iso_packet {
-	/* These will be copied to iTD when scheduling */
-	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */
-	__hc32			transaction;	/* itd->hw_transaction[i] |= */
-	u8			cross;		/* buf crosses pages */
-	/* for full speed OUT splits */
-	u32			buf1;
-};
-
-/* temporary schedule data for packets from iso urbs (both speeds)
- * each packet is one logical usb transaction to the device (not TT),
- * beginning at stream->next_uframe
- */
-struct fusbh200_iso_sched {
-	struct list_head	td_list;
-	unsigned		span;
-	struct fusbh200_iso_packet	packet [0];
-};
-
-/*
- * fusbh200_iso_stream - groups all (s)itds for this endpoint.
- * acts like a qh would, if EHCI had them for ISO.
- */
-struct fusbh200_iso_stream {
-	/* first field matches fusbh200_hq, but is NULL */
-	struct fusbh200_qh_hw	*hw;
-
-	u8			bEndpointAddress;
-	u8			highspeed;
-	struct list_head	td_list;	/* queued itds */
-	struct list_head	free_list;	/* list of unused itds */
-	struct usb_device	*udev;
-	struct usb_host_endpoint *ep;
-
-	/* output of (re)scheduling */
-	int			next_uframe;
-	__hc32			splits;
-
-	/* the rest is derived from the endpoint descriptor,
-	 * trusting urb->interval == f(epdesc->bInterval) and
-	 * including the extra info for hw_bufp[0..2]
-	 */
-	u8			usecs, c_usecs;
-	u16			interval;
-	u16			tt_usecs;
-	u16			maxp;
-	u16			raw_mask;
-	unsigned		bandwidth;
-
-	/* This is used to initialize iTD's hw_bufp fields */
-	__hc32			buf0;
-	__hc32			buf1;
-	__hc32			buf2;
-
-	/* this is used to initialize sITD's tt info */
-	__hc32			address;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.3
- * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
- *
- * Schedule records for high speed iso xfers
- */
-struct fusbh200_itd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;           /* see EHCI 3.3.1 */
-	__hc32			hw_transaction [8]; /* see EHCI 3.3.2 */
-#define FUSBH200_ISOC_ACTIVE        (1<<31)        /* activate transfer this slot */
-#define FUSBH200_ISOC_BUF_ERR       (1<<30)        /* Data buffer error */
-#define FUSBH200_ISOC_BABBLE        (1<<29)        /* babble detected */
-#define FUSBH200_ISOC_XACTERR       (1<<28)        /* XactErr - transaction error */
-#define	FUSBH200_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
-#define	FUSBH200_ITD_IOC		(1 << 15)	/* interrupt on complete */
-
-#define ITD_ACTIVE(fusbh200)	cpu_to_hc32(fusbh200, FUSBH200_ISOC_ACTIVE)
-
-	__hc32			hw_bufp [7];	/* see EHCI 3.3.3 */
-	__hc32			hw_bufp_hi [7];	/* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		itd_dma;	/* for this itd */
-	union fusbh200_shadow	itd_next;	/* ptr to periodic q entry */
-
-	struct urb		*urb;
-	struct fusbh200_iso_stream	*stream;	/* endpoint's queue */
-	struct list_head	itd_list;	/* list of stream's itds */
-
-	/* any/all hw_transactions here may be used by that urb */
-	unsigned		frame;		/* where scheduled */
-	unsigned		pg;
-	unsigned		index[8];	/* in urb->iso_frame_desc */
-} __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.96 Section 3.7
- * Periodic Frame Span Traversal Node (FSTN)
- *
- * Manages split interrupt transactions (using TT) that span frame boundaries
- * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN
- * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
- * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
- */
-struct fusbh200_fstn {
-	__hc32			hw_next;	/* any periodic q entry */
-	__hc32			hw_prev;	/* qh or FUSBH200_LIST_END */
-
-	/* the rest is HCD-private */
-	dma_addr_t		fstn_dma;
-	union fusbh200_shadow	fstn_next;	/* ptr to periodic q entry */
-} __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/* Prepare the PORTSC wakeup flags during controller suspend/resume */
-
-#define fusbh200_prepare_ports_for_controller_suspend(fusbh200, do_wakeup)	\
-		fusbh200_adjust_port_wakeup_flags(fusbh200, true, do_wakeup);
-
-#define fusbh200_prepare_ports_for_controller_resume(fusbh200)			\
-		fusbh200_adjust_port_wakeup_flags(fusbh200, false, false);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Some EHCI controllers have a Transaction Translator built into the
- * root hub. This is a non-standard feature.  Each controller will need
- * to add code to the following inline functions, and call them as
- * needed (mostly in root hub code).
- */
-
-static inline unsigned int
-fusbh200_get_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
-{
-	return (readl(&fusbh200->regs->bmcsr)
-		& BMCSR_HOST_SPD_TYP) >> 9;
-}
-
-/* Returns the speed of a device attached to a port on the root hub. */
-static inline unsigned int
-fusbh200_port_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
-{
-	switch (fusbh200_get_speed(fusbh200, portsc)) {
-	case 0:
-		return 0;
-	case 1:
-		return USB_PORT_STAT_LOW_SPEED;
-	case 2:
-	default:
-		return USB_PORT_STAT_HIGH_SPEED;
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define	fusbh200_has_fsl_portno_bug(e)		(0)
-
-/*
- * While most USB host controllers implement their registers in
- * little-endian format, a minority (celleb companion chip) implement
- * them in big endian format.
- *
- * This attempts to support either format at compile time without a
- * runtime penalty, or both formats with the additional overhead
- * of checking a flag bit.
- *
- */
-
-#define fusbh200_big_endian_mmio(e)	0
-#define fusbh200_big_endian_capbase(e)	0
-
-static inline unsigned int fusbh200_readl(const struct fusbh200_hcd *fusbh200,
-		__u32 __iomem * regs)
-{
-	return readl(regs);
-}
-
-static inline void fusbh200_writel(const struct fusbh200_hcd *fusbh200,
-		const unsigned int val, __u32 __iomem *regs)
-{
-	writel(val, regs);
-}
-
-/* cpu to fusbh200 */
-static inline __hc32 cpu_to_hc32 (const struct fusbh200_hcd *fusbh200, const u32 x)
-{
-	return cpu_to_le32(x);
-}
-
-/* fusbh200 to cpu */
-static inline u32 hc32_to_cpu (const struct fusbh200_hcd *fusbh200, const __hc32 x)
-{
-	return le32_to_cpu(x);
-}
-
-static inline u32 hc32_to_cpup (const struct fusbh200_hcd *fusbh200, const __hc32 *x)
-{
-	return le32_to_cpup(x);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline unsigned fusbh200_read_frame_index(struct fusbh200_hcd *fusbh200)
-{
-	return fusbh200_readl(fusbh200, &fusbh200->regs->frame_index);
-}
-
-#define fusbh200_itdlen(urb, desc, t) ({			\
-	usb_pipein((urb)->pipe) ?				\
-	(desc)->length - FUSBH200_ITD_LENGTH(t) :			\
-	FUSBH200_ITD_LENGTH(t);					\
-})
-/*-------------------------------------------------------------------------*/
-
-#endif /* __LINUX_FUSBH200_H */
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c
index d9f0481d7258aaa16b78f381518fe697af1e22a8..cfa94275c52c24d668cde3833e3694162ce52f9f 100644
--- a/drivers/usb/host/ohci-nxp.c
+++ b/drivers/usb/host/ohci-nxp.c
@@ -203,7 +203,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 		goto fail_disable;
 	}
 
-	ret = clk_enable(usb_pll_clk);
+	ret = clk_prepare_enable(usb_pll_clk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to start USB PLL\n");
 		goto fail_disable;
@@ -223,7 +223,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 		goto fail_rate;
 	}
 
-	ret = clk_enable(usb_dev_clk);
+	ret = clk_prepare_enable(usb_dev_clk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
 		goto fail_rate;
@@ -239,7 +239,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 
 	__raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
 
-	ret = clk_enable(usb_otg_clk);
+	ret = clk_prepare_enable(usb_otg_clk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to start USB DEV Clock\n");
 		goto fail_otg;
@@ -283,11 +283,11 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
 fail_resource:
 	usb_put_hcd(hcd);
 fail_hcd:
-	clk_disable(usb_otg_clk);
+	clk_disable_unprepare(usb_otg_clk);
 fail_otg:
-	clk_disable(usb_dev_clk);
+	clk_disable_unprepare(usb_dev_clk);
 fail_rate:
-	clk_disable(usb_pll_clk);
+	clk_disable_unprepare(usb_pll_clk);
 fail_disable:
 	isp1301_i2c_client = NULL;
 	return ret;
@@ -300,9 +300,9 @@ static int ohci_hcd_nxp_remove(struct platform_device *pdev)
 	usb_remove_hcd(hcd);
 	ohci_nxp_stop_hc();
 	usb_put_hcd(hcd);
-	clk_disable(usb_pll_clk);
-	clk_disable(usb_dev_clk);
-	i2c_unregister_device(isp1301_i2c_client);
+	clk_disable_unprepare(usb_otg_clk);
+	clk_disable_unprepare(usb_dev_clk);
+	clk_disable_unprepare(usb_pll_clk);
 	isp1301_i2c_client = NULL;
 
 	return 0;
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index 707437c88d03e578379ab2bab66cec2012a86202..56478ed2f932fc4dc74d32d156a643f90672c31a 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -161,6 +161,7 @@ static const struct of_device_id spear_ohci_id_table[] = {
 	{ .compatible = "st,spear600-ohci", },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, spear_ohci_id_table);
 
 /* Driver definition to register with the platform bus */
 static struct platform_driver spear_ohci_hcd_driver = {
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index a67bd509033097cfc156f84605f43f3617b951d8..0a94895a358d47e8e51cf32722afbdce0d6104d9 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -2245,8 +2245,7 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 	struct u132 *u132 = hcd_to_u132(hcd);
 	if (irqs_disabled()) {
 		if (__GFP_WAIT & mem_flags) {
-			printk(KERN_ERR "invalid context for function that migh"
-				"t sleep\n");
+			printk(KERN_ERR "invalid context for function that might sleep\n");
 			return -EINVAL;
 		}
 	}
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 3a3e3eeba291882b03484d6048a508194d57d82e..32a6f3d8deecf54abd4deaaa330bcd44f752cc11 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -140,6 +140,7 @@ static const struct of_device_id platform_uhci_ids[] = {
 	{ .compatible = "platform-uhci", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, platform_uhci_ids);
 
 static struct platform_driver uhci_platform_driver = {
 	.probe		= uhci_hcd_platform_probe,
diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c
index d3e13b640d4ba28493f27ca99fc26cfd3677981f..e36372393bb1f8719293a3cc979c95c075277e85 100644
--- a/drivers/usb/host/whci/init.c
+++ b/drivers/usb/host/whci/init.c
@@ -175,8 +175,7 @@ void whc_clean_up(struct whc *whc)
 	pzl_clean_up(whc);
 	asl_clean_up(whc);
 
-	if (whc->qset_pool)
-		dma_pool_destroy(whc->qset_pool);
+	dma_pool_destroy(whc->qset_pool);
 
 	len   = resource_size(&whc->umc->resource);
 	if (whc->base)
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 2d16faefb429b03a529304136c1eaf19deb15572..74c42f7226780b4c6a4924489f711d27a1b90f37 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -58,16 +58,17 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)
 static void xhci_print_cap_regs(struct xhci_hcd *xhci)
 {
 	u32 temp;
+	u32 hci_version;
 
 	xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs);
 
 	temp = readl(&xhci->cap_regs->hc_capbase);
+	hci_version = HC_VERSION(temp);
 	xhci_dbg(xhci, "CAPLENGTH AND HCIVERSION 0x%x:\n",
 			(unsigned int) temp);
 	xhci_dbg(xhci, "CAPLENGTH: 0x%x\n",
 			(unsigned int) HC_LENGTH(temp));
-	xhci_dbg(xhci, "HCIVERSION: 0x%x\n",
-			(unsigned int) HC_VERSION(temp));
+	xhci_dbg(xhci, "HCIVERSION: 0x%x\n", hci_version);
 
 	temp = readl(&xhci->cap_regs->hcs_params1);
 	xhci_dbg(xhci, "HCSPARAMS 1: 0x%x\n",
@@ -108,6 +109,18 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)
 
 	temp = readl(&xhci->cap_regs->run_regs_off);
 	xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK);
+
+	/* xhci 1.1 controllers have the HCCPARAMS2 register */
+	if (hci_version > 100) {
+		temp = readl(&xhci->cap_regs->hcc_params2);
+		xhci_dbg(xhci, "HCC PARAMS2 0x%x:\n", (unsigned int) temp);
+		xhci_dbg(xhci, "  HC %s Force save context capability",
+			 HCC2_FSC(temp) ? "supports" : "doesn't support");
+		xhci_dbg(xhci, "  HC %s Large ESIT Payload Capability",
+			 HCC2_LEC(temp) ? "supports" : "doesn't support");
+		xhci_dbg(xhci, "  HC %s Extended TBC capability",
+			 HCC2_ETC(temp) ? "supports" : "doesn't support");
+	}
 }
 
 static void xhci_print_command_reg(struct xhci_hcd *xhci)
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 78241b5550df877fb09189936867f7821e09d11a..5d2d7e954bd4cb8dbaa51ec1121e236e8f472dce 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -31,13 +31,15 @@
 #define	PORT_RWC_BITS	(PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
 			 PORT_RC | PORT_PLC | PORT_PE)
 
-/* USB 3.0 BOS descriptor and a capability descriptor, combined */
+/* USB 3 BOS descriptor and a capability descriptors, combined.
+ * Fields will be adjusted and added later in xhci_create_usb3_bos_desc()
+ */
 static u8 usb_bos_descriptor [] = {
 	USB_DT_BOS_SIZE,		/*  __u8 bLength, 5 bytes */
 	USB_DT_BOS,			/*  __u8 bDescriptorType */
 	0x0F, 0x00,			/*  __le16 wTotalLength, 15 bytes */
 	0x1,				/*  __u8 bNumDeviceCaps */
-	/* First device capability */
+	/* First device capability, SuperSpeed */
 	USB_DT_USB_SS_CAP_SIZE,		/*  __u8 bLength, 10 bytes */
 	USB_DT_DEVICE_CAPABILITY,	/* Device Capability */
 	USB_SS_CAP_TYPE,		/* bDevCapabilityType, SUPERSPEED_USB */
@@ -46,9 +48,108 @@ static u8 usb_bos_descriptor [] = {
 	0x03,				/* bFunctionalitySupport,
 					   USB 3.0 speed only */
 	0x00,				/* bU1DevExitLat, set later. */
-	0x00, 0x00			/* __le16 bU2DevExitLat, set later. */
+	0x00, 0x00,			/* __le16 bU2DevExitLat, set later. */
+	/* Second device capability, SuperSpeedPlus */
+	0x0c,				/* bLength 12, will be adjusted later */
+	USB_DT_DEVICE_CAPABILITY,	/* Device Capability */
+	USB_SSP_CAP_TYPE,		/* bDevCapabilityType SUPERSPEED_PLUS */
+	0x00,				/* bReserved 0 */
+	0x00, 0x00, 0x00, 0x00,		/* bmAttributes, get from xhci psic */
+	0x00, 0x00,			/* wFunctionalitySupport */
+	0x00, 0x00,			/* wReserved 0 */
+	/* Sublink Speed Attributes are added in xhci_create_usb3_bos_desc() */
 };
 
+static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf,
+				     u16 wLength)
+{
+	int i, ssa_count;
+	u32 temp;
+	u16 desc_size, ssp_cap_size, ssa_size = 0;
+	bool usb3_1 = false;
+
+	desc_size = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE;
+	ssp_cap_size = sizeof(usb_bos_descriptor) - desc_size;
+
+	/* does xhci support USB 3.1 Enhanced SuperSpeed */
+	if (xhci->usb3_rhub.min_rev >= 0x01 && xhci->usb3_rhub.psi_uid_count) {
+		/* two SSA entries for each unique PSI ID, one RX and one TX */
+		ssa_count = xhci->usb3_rhub.psi_uid_count * 2;
+		ssa_size = ssa_count * sizeof(u32);
+		desc_size += ssp_cap_size;
+		usb3_1 = true;
+	}
+	memcpy(buf, &usb_bos_descriptor, min(desc_size, wLength));
+
+	if (usb3_1) {
+		/* modify bos descriptor bNumDeviceCaps and wTotalLength */
+		buf[4] += 1;
+		put_unaligned_le16(desc_size + ssa_size, &buf[2]);
+	}
+
+	if (wLength < USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE)
+		return wLength;
+
+	/* Indicate whether the host has LTM support. */
+	temp = readl(&xhci->cap_regs->hcc_params);
+	if (HCC_LTC(temp))
+		buf[8] |= USB_LTM_SUPPORT;
+
+	/* Set the U1 and U2 exit latencies. */
+	if ((xhci->quirks & XHCI_LPM_SUPPORT)) {
+		temp = readl(&xhci->cap_regs->hcs_params3);
+		buf[12] = HCS_U1_LATENCY(temp);
+		put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]);
+	}
+
+	if (usb3_1) {
+		u32 ssp_cap_base, bm_attrib, psi;
+		int offset;
+
+		ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE;
+
+		if (wLength < desc_size)
+			return wLength;
+		buf[ssp_cap_base] = ssp_cap_size + ssa_size;
+
+		/* attribute count SSAC bits 4:0 and ID count SSIC bits 8:5 */
+		bm_attrib = (ssa_count - 1) & 0x1f;
+		bm_attrib |= (xhci->usb3_rhub.psi_uid_count - 1) << 5;
+		put_unaligned_le32(bm_attrib, &buf[ssp_cap_base + 4]);
+
+		if (wLength < desc_size + ssa_size)
+			return wLength;
+		/*
+		 * Create the Sublink Speed Attributes (SSA) array.
+		 * The xhci PSI field and USB 3.1 SSA fields are very similar,
+		 * but link type bits 7:6 differ for values 01b and 10b.
+		 * xhci has also only one PSI entry for a symmetric link when
+		 * USB 3.1 requires two SSA entries (RX and TX) for every link
+		 */
+		offset = desc_size;
+		for (i = 0; i < xhci->usb3_rhub.psi_count; i++) {
+			psi = xhci->usb3_rhub.psi[i];
+			psi &= ~USB_SSP_SUBLINK_SPEED_RSVD;
+			if ((psi & PLT_MASK) == PLT_SYM) {
+			/* Symmetric, create SSA RX and TX from one PSI entry */
+				put_unaligned_le32(psi, &buf[offset]);
+				psi |= 1 << 7;  /* turn entry to TX */
+				offset += 4;
+				if (offset >= desc_size + ssa_size)
+					return desc_size + ssa_size;
+			} else if ((psi & PLT_MASK) == PLT_ASYM_RX) {
+				/* Asymetric RX, flip bits 7:6 for SSA */
+				psi ^= PLT_MASK;
+			}
+			put_unaligned_le32(psi, &buf[offset]);
+			offset += 4;
+			if (offset >= desc_size + ssa_size)
+				return desc_size + ssa_size;
+		}
+	}
+	/* ssa_size is 0 for other than usb 3.1 hosts */
+	return desc_size + ssa_size;
+}
 
 static void xhci_common_hub_descriptor(struct xhci_hcd *xhci,
 		struct usb_hub_descriptor *desc, int ports)
@@ -161,7 +262,7 @@ static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 		struct usb_hub_descriptor *desc)
 {
 
-	if (hcd->speed == HCD_USB3)
+	if (hcd->speed >= HCD_USB3)
 		xhci_usb3_hub_descriptor(hcd, xhci, desc);
 	else
 		xhci_usb2_hub_descriptor(hcd, xhci, desc);
@@ -250,7 +351,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 		if (!xhci->devs[i])
 			continue;
 		speed = xhci->devs[i]->udev->speed;
-		if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3))
+		if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3))
 				&& xhci->devs[i]->fake_port == port) {
 			slot_id = i;
 			break;
@@ -339,7 +440,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 		u16 wIndex, __le32 __iomem *addr, u32 port_status)
 {
 	/* Don't allow the USB core to disable SuperSpeed ports. */
-	if (hcd->speed == HCD_USB3) {
+	if (hcd->speed >= HCD_USB3) {
 		xhci_dbg(xhci, "Ignoring request to disable "
 				"SuperSpeed port.\n");
 		return;
@@ -407,7 +508,7 @@ static int xhci_get_ports(struct usb_hcd *hcd, __le32 __iomem ***port_array)
 	int max_ports;
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 
-	if (hcd->speed == HCD_USB3) {
+	if (hcd->speed >= HCD_USB3) {
 		max_ports = xhci->num_usb3_ports;
 		*port_array = xhci->usb3_ports;
 	} else {
@@ -558,6 +659,22 @@ static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status,
 	}
 }
 
+static u32 xhci_get_ext_port_status(u32 raw_port_status, u32 port_li)
+{
+	u32 ext_stat = 0;
+	int speed_id;
+
+	/* only support rx and tx lane counts of 1 in usb3.1 spec */
+	speed_id = DEV_PORT_SPEED(raw_port_status);
+	ext_stat |= speed_id;		/* bits 3:0, RX speed id */
+	ext_stat |= speed_id << 4;	/* bits 7:4, TX speed id */
+
+	ext_stat |= PORT_RX_LANES(port_li) << 8;  /* bits 11:8 Rx lane count */
+	ext_stat |= PORT_TX_LANES(port_li) << 12; /* bits 15:12 Tx lane count */
+
+	return ext_stat;
+}
+
 /*
  * Converts a raw xHCI port status into the format that external USB 2.0 or USB
  * 3.0 hubs use.
@@ -590,7 +707,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 	if ((raw_port_status & PORT_RC))
 		status |= USB_PORT_STAT_C_RESET << 16;
 	/* USB3.0 only */
-	if (hcd->speed == HCD_USB3) {
+	if (hcd->speed >= HCD_USB3) {
 		/* Port link change with port in resume state should not be
 		 * reported to usbcore, as this is an internal state to be
 		 * handled by xhci driver. Reporting PLC to usbcore may
@@ -606,13 +723,13 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 			status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
 	}
 
-	if (hcd->speed != HCD_USB3) {
+	if (hcd->speed < HCD_USB3) {
 		if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3
 				&& (raw_port_status & PORT_POWER))
 			status |= USB_PORT_STAT_SUSPEND;
 	}
 	if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME &&
-			!DEV_SUPERSPEED(raw_port_status)) {
+		!DEV_SUPERSPEED_ANY(raw_port_status)) {
 		if ((raw_port_status & PORT_RESET) ||
 				!(raw_port_status & PORT_PE))
 			return 0xffffffff;
@@ -669,7 +786,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 			&& (raw_port_status & PORT_POWER)
 			&& (bus_state->suspended_ports & (1 << wIndex))) {
 		bus_state->suspended_ports &= ~(1 << wIndex);
-		if (hcd->speed != HCD_USB3)
+		if (hcd->speed < HCD_USB3)
 			bus_state->port_c_suspend |= 1 << wIndex;
 	}
 	if (raw_port_status & PORT_CONNECT) {
@@ -683,13 +800,13 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
 	if (raw_port_status & PORT_RESET)
 		status |= USB_PORT_STAT_RESET;
 	if (raw_port_status & PORT_POWER) {
-		if (hcd->speed == HCD_USB3)
+		if (hcd->speed >= HCD_USB3)
 			status |= USB_SS_PORT_STAT_POWER;
 		else
 			status |= USB_PORT_STAT_POWER;
 	}
 	/* Update Port Link State */
-	if (hcd->speed == HCD_USB3) {
+	if (hcd->speed >= HCD_USB3) {
 		xhci_hub_report_usb3_link_state(xhci, &status, raw_port_status);
 		/*
 		 * Verify if all USB3 Ports Have entered U0 already.
@@ -734,7 +851,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		 * descriptor for the USB 3.0 roothub.  If not, we stall the
 		 * endpoint, like external hubs do.
 		 */
-		if (hcd->speed == HCD_USB3 &&
+		if (hcd->speed >= HCD_USB3 &&
 				(wLength < USB_DT_SS_HUB_SIZE ||
 				 wValue != (USB_DT_SS_HUB << 8))) {
 			xhci_dbg(xhci, "Wrong hub descriptor type for "
@@ -748,25 +865,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		if ((wValue & 0xff00) != (USB_DT_BOS << 8))
 			goto error;
 
-		if (hcd->speed != HCD_USB3)
+		if (hcd->speed < HCD_USB3)
 			goto error;
 
-		/* Set the U1 and U2 exit latencies. */
-		memcpy(buf, &usb_bos_descriptor,
-				USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE);
-		if ((xhci->quirks & XHCI_LPM_SUPPORT)) {
-			temp = readl(&xhci->cap_regs->hcs_params3);
-			buf[12] = HCS_U1_LATENCY(temp);
-			put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]);
-		}
-
-		/* Indicate whether the host has LTM support. */
-		temp = readl(&xhci->cap_regs->hcc_params);
-		if (HCC_LTC(temp))
-			buf[8] |= USB_LTM_SUPPORT;
-
+		retval = xhci_create_usb3_bos_desc(xhci, buf, wLength);
 		spin_unlock_irqrestore(&xhci->lock, flags);
-		return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE;
+		return retval;
 	case GetPortStatus:
 		if (!wIndex || wIndex > max_ports)
 			goto error;
@@ -786,6 +890,19 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		xhci_dbg(xhci, "Get port status returned 0x%x\n", status);
 
 		put_unaligned(cpu_to_le32(status), (__le32 *) buf);
+		/* if USB 3.1 extended port status return additional 4 bytes */
+		if (wValue == 0x02) {
+			u32 port_li;
+
+			if (hcd->speed < HCD_USB31 || wLength != 8) {
+				xhci_err(xhci, "get ext port status invalid parameter\n");
+				retval = -EINVAL;
+				break;
+			}
+			port_li = readl(port_array[wIndex] + PORTLI);
+			status = xhci_get_ext_port_status(temp, port_li);
+			put_unaligned_le32(cpu_to_le32(status), &buf[4]);
+		}
 		break;
 	case SetPortFeature:
 		if (wValue == USB_PORT_FEAT_LINK_STATE)
@@ -952,7 +1069,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			temp = readl(port_array[wIndex]);
 			break;
 		case USB_PORT_FEAT_U1_TIMEOUT:
-			if (hcd->speed != HCD_USB3)
+			if (hcd->speed < HCD_USB3)
 				goto error;
 			temp = readl(port_array[wIndex] + PORTPMSC);
 			temp &= ~PORT_U1_TIMEOUT_MASK;
@@ -960,7 +1077,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			writel(temp, port_array[wIndex] + PORTPMSC);
 			break;
 		case USB_PORT_FEAT_U2_TIMEOUT:
-			if (hcd->speed != HCD_USB3)
+			if (hcd->speed < HCD_USB3)
 				goto error;
 			temp = readl(port_array[wIndex] + PORTPMSC);
 			temp &= ~PORT_U2_TIMEOUT_MASK;
@@ -1223,14 +1340,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 		u32 temp;
 
 		temp = readl(port_array[port_index]);
-		if (DEV_SUPERSPEED(temp))
+		if (DEV_SUPERSPEED_ANY(temp))
 			temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
 		else
 			temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
 		if (test_bit(port_index, &bus_state->bus_suspended) &&
 		    (temp & PORT_PLS_MASK)) {
 			set_bit(port_index, &port_was_suspended);
-			if (!DEV_SUPERSPEED(temp)) {
+			if (!DEV_SUPERSPEED_ANY(temp)) {
 				xhci_set_link_state(xhci, port_array,
 						port_index, XDEV_RESUME);
 				need_usb2_u3_exit = true;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 41f841fa6c4de6a57edb702c2875e4351a4cbff8..c48cbe731356539abf7df8ac1c94a09701b546f7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1828,24 +1828,20 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 	for (i = 1; i < MAX_HC_SLOTS; ++i)
 		xhci_free_virt_device(xhci, i);
 
-	if (xhci->segment_pool)
-		dma_pool_destroy(xhci->segment_pool);
+	dma_pool_destroy(xhci->segment_pool);
 	xhci->segment_pool = NULL;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed segment pool");
 
-	if (xhci->device_pool)
-		dma_pool_destroy(xhci->device_pool);
+	dma_pool_destroy(xhci->device_pool);
 	xhci->device_pool = NULL;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed device context pool");
 
-	if (xhci->small_streams_pool)
-		dma_pool_destroy(xhci->small_streams_pool);
+	dma_pool_destroy(xhci->small_streams_pool);
 	xhci->small_streams_pool = NULL;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			"Freed small stream array pool");
 
-	if (xhci->medium_streams_pool)
-		dma_pool_destroy(xhci->medium_streams_pool);
+	dma_pool_destroy(xhci->medium_streams_pool);
 	xhci->medium_streams_pool = NULL;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 			"Freed medium stream array pool");
@@ -2072,14 +2068,23 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
 {
 	u32 temp, port_offset, port_count;
 	int i;
+	struct xhci_hub *rhub;
 
-	if (major_revision > 0x03) {
+	temp = readl(addr);
+
+	if (XHCI_EXT_PORT_MAJOR(temp) == 0x03) {
+		rhub = &xhci->usb3_rhub;
+	} else if (XHCI_EXT_PORT_MAJOR(temp) <= 0x02) {
+		rhub = &xhci->usb2_rhub;
+	} else {
 		xhci_warn(xhci, "Ignoring unknown port speed, "
 				"Ext Cap %p, revision = 0x%x\n",
 				addr, major_revision);
 		/* Ignoring port protocol we can't understand. FIXME */
 		return;
 	}
+	rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp);
+	rhub->min_rev = XHCI_EXT_PORT_MINOR(temp);
 
 	/* Port offset and count in the third dword, see section 7.2 */
 	temp = readl(addr + 2);
@@ -2094,6 +2099,33 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
 		/* WTF? "Valid values are ‘1’ to MaxPorts" */
 		return;
 
+	rhub->psi_count = XHCI_EXT_PORT_PSIC(temp);
+	if (rhub->psi_count) {
+		rhub->psi = kcalloc(rhub->psi_count, sizeof(*rhub->psi),
+				    GFP_KERNEL);
+		if (!rhub->psi)
+			rhub->psi_count = 0;
+
+		rhub->psi_uid_count++;
+		for (i = 0; i < rhub->psi_count; i++) {
+			rhub->psi[i] = readl(addr + 4 + i);
+
+			/* count unique ID values, two consecutive entries can
+			 * have the same ID if link is assymetric
+			 */
+			if (i && (XHCI_EXT_PORT_PSIV(rhub->psi[i]) !=
+				  XHCI_EXT_PORT_PSIV(rhub->psi[i - 1])))
+				rhub->psi_uid_count++;
+
+			xhci_dbg(xhci, "PSIV:%d PSIE:%d PLT:%d PFD:%d LP:%d PSIM:%d\n",
+				  XHCI_EXT_PORT_PSIV(rhub->psi[i]),
+				  XHCI_EXT_PORT_PSIE(rhub->psi[i]),
+				  XHCI_EXT_PORT_PLT(rhub->psi[i]),
+				  XHCI_EXT_PORT_PFD(rhub->psi[i]),
+				  XHCI_EXT_PORT_LP(rhub->psi[i]),
+				  XHCI_EXT_PORT_PSIM(rhub->psi[i]));
+		}
+	}
 	/* cache usb2 port capabilities */
 	if (major_revision < 0x03 && xhci->num_ext_caps < max_caps)
 		xhci->ext_caps[xhci->num_ext_caps++] = temp;
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index c47d3e48058659230e8d48ed342f9c163b08732d..17f6897acde2a5a7674ccff44ddc55f0db192166 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -201,15 +201,17 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
 	int			retval;
 
+	xhci = hcd_to_xhci(hcd);
+	if (!xhci->sbrn)
+		pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
+
 	retval = xhci_gen_setup(hcd, xhci_pci_quirks);
 	if (retval)
 		return retval;
 
-	xhci = hcd_to_xhci(hcd);
 	if (!usb_hcd_is_primary_hcd(hcd))
 		return 0;
 
-	pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
 	xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn);
 
 	/* Find any debug ports */
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 890ad9d9d32991c7e74b02d9580b5cfbcd4d595e..05647e6753cd833f9b9e87924832be5d3e2c2216 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -19,6 +19,7 @@
 #include <linux/usb/phy.h>
 #include <linux/slab.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/acpi.h>
 
 #include "xhci.h"
 #include "xhci-mvebu.h"
@@ -93,14 +94,20 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
-	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-	if (!pdev->dev.dma_mask)
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+	/* Try to set 64-bit DMA first */
+	if (WARN_ON(!pdev->dev.dma_mask))
+		/* Platform did not initialize dma_mask */
+		ret = dma_coerce_mask_and_coherent(&pdev->dev,
+						   DMA_BIT_MASK(64));
 	else
-		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+
+	/* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
+	if (ret) {
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		if (ret)
+			return ret;
+	}
 
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)
@@ -262,6 +269,13 @@ static const struct of_device_id usb_xhci_of_match[] = {
 MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
 #endif
 
+static const struct acpi_device_id usb_xhci_acpi_match[] = {
+	/* XHCI-compliant USB Controller */
+	{ "PNP0D10", },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
+
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
@@ -269,6 +283,7 @@ static struct platform_driver usb_xhci_driver = {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
 		.of_match_table = of_match_ptr(usb_xhci_of_match),
+		.acpi_match_table = ACPI_PTR(usb_xhci_acpi_match),
 	},
 };
 MODULE_ALIAS("platform:xhci-hcd");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 97ffe39972735109f1ca1f86e003fe2550e4f936..fa836251ca21e4f19c59b3fd37b3b788b7b81008 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1453,7 +1453,7 @@ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
 		 * 1.1 ports are under the USB 2.0 hub.  If the port speed
 		 * matches the device speed, it's a similar speed port.
 		 */
-		if ((port_speed == 0x03) == (hcd->speed == HCD_USB3))
+		if ((port_speed == 0x03) == (hcd->speed >= HCD_USB3))
 			num_similar_speed_ports++;
 	}
 	return num_similar_speed_ports;
@@ -1515,7 +1515,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 
 	/* Find the right roothub. */
 	hcd = xhci_to_hcd(xhci);
-	if ((major_revision == 0x03) != (hcd->speed == HCD_USB3))
+	if ((major_revision == 0x03) != (hcd->speed >= HCD_USB3))
 		hcd = xhci->shared_hcd;
 
 	if (major_revision == 0) {
@@ -1541,7 +1541,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 	 * correct bus_state structure.
 	 */
 	bus_state = &xhci->bus_state[hcd_index(hcd)];
-	if (hcd->speed == HCD_USB3)
+	if (hcd->speed >= HCD_USB3)
 		port_array = xhci->usb3_ports;
 	else
 		port_array = xhci->usb2_ports;
@@ -1555,7 +1555,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 		usb_hcd_resume_root_hub(hcd);
 	}
 
-	if (hcd->speed == HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE)
+	if (hcd->speed >= HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE)
 		bus_state->port_remote_wakeup &= ~(1 << faked_port_index);
 
 	if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) {
@@ -1567,7 +1567,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 			goto cleanup;
 		}
 
-		if (DEV_SUPERSPEED(temp)) {
+		if (DEV_SUPERSPEED_ANY(temp)) {
 			xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
 			/* Set a flag to say the port signaled remote wakeup,
 			 * so we can tell the difference between the end of
@@ -1595,7 +1595,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 	}
 
 	if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
-			DEV_SUPERSPEED(temp)) {
+			DEV_SUPERSPEED_ANY(temp)) {
 		xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
 		/* We've just brought the device into U0 through either the
 		 * Resume state after a device remote wakeup, or through the
@@ -1625,7 +1625,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 	 * RExit to a disconnect state).  If so, let the the driver know it's
 	 * out of the RExit state.
 	 */
-	if (!DEV_SUPERSPEED(temp) &&
+	if (!DEV_SUPERSPEED_ANY(temp) &&
 			test_and_clear_bit(faked_port_index,
 				&bus_state->rexit_ports)) {
 		complete(&bus_state->rexit_done[faked_port_index]);
@@ -1633,7 +1633,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 		goto cleanup;
 	}
 
-	if (hcd->speed != HCD_USB3)
+	if (hcd->speed < HCD_USB3)
 		xhci_test_and_clear_bit(xhci, port_array, faked_port_index,
 					PORT_PLC);
 
@@ -3048,21 +3048,6 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
 
-/*
- * The TD size is the number of bytes remaining in the TD (including this TRB),
- * right shifted by 10.
- * It must fit in bits 21:17, so it can't be bigger than 31.
- */
-static u32 xhci_td_remainder(unsigned int remainder)
-{
-	u32 max = (1 << (21 - 17 + 1)) - 1;
-
-	if ((remainder >> 10) >= max)
-		return max << 17;
-	else
-		return (remainder >> 10) << 17;
-}
-
 /*
  * For xHCI 1.0 host controllers, TD size is the number of max packet sized
  * packets remaining in the TD (*not* including this TRB).
@@ -3075,30 +3060,36 @@ static u32 xhci_td_remainder(unsigned int remainder)
  *
  * TD size = total_packet_count - packets_transferred
  *
- * It must fit in bits 21:17, so it can't be bigger than 31.
+ * For xHCI 0.96 and older, TD size field should be the remaining bytes
+ * including this TRB, right shifted by 10
+ *
+ * For all hosts it must fit in bits 21:17, so it can't be bigger than 31.
+ * This is taken care of in the TRB_TD_SIZE() macro
+ *
  * The last TRB in a TD must have the TD size set to zero.
  */
-static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
-		unsigned int total_packet_count, struct urb *urb,
-		unsigned int num_trbs_left)
+static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
+			      int trb_buff_len, unsigned int td_total_len,
+			      struct urb *urb, unsigned int num_trbs_left)
 {
-	int packets_transferred;
+	u32 maxp, total_packet_count;
+
+	if (xhci->hci_version < 0x100)
+		return ((td_total_len - transferred) >> 10);
+
+	maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
+	total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
 
 	/* One TRB with a zero-length data packet. */
-	if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
+	if (num_trbs_left == 0 || (transferred == 0 && trb_buff_len == 0) ||
+	    trb_buff_len == td_total_len)
 		return 0;
 
-	/* All the TRB queueing functions don't count the current TRB in
-	 * running_total.
-	 */
-	packets_transferred = (running_total + trb_buff_len) /
-		GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
-
-	if ((total_packet_count - packets_transferred) > 31)
-		return 31 << 17;
-	return (total_packet_count - packets_transferred) << 17;
+	/* Queueing functions don't count the current TRB into transferred */
+	return (total_packet_count - ((transferred + trb_buff_len) / maxp));
 }
 
+
 static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		struct urb *urb, int slot_id, unsigned int ep_index)
 {
@@ -3220,17 +3211,12 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		}
 
 		/* Set the TRB length, TD size, and interrupter fields. */
-		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
-					urb->transfer_buffer_length -
-					running_total);
-		} else {
-			remainder = xhci_v1_0_td_remainder(running_total,
-					trb_buff_len, total_packet_count, urb,
-					num_trbs - 1);
-		}
+		remainder = xhci_td_remainder(xhci, running_total, trb_buff_len,
+					   urb->transfer_buffer_length,
+					   urb, num_trbs - 1);
+
 		length_field = TRB_LEN(trb_buff_len) |
-			remainder |
+			TRB_TD_SIZE(remainder) |
 			TRB_INTR_TARGET(0);
 
 		if (num_trbs > 1)
@@ -3393,17 +3379,12 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 			field |= TRB_ISP;
 
 		/* Set the TRB length, TD size, and interrupter fields. */
-		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
-					urb->transfer_buffer_length -
-					running_total);
-		} else {
-			remainder = xhci_v1_0_td_remainder(running_total,
-					trb_buff_len, total_packet_count, urb,
-					num_trbs - 1);
-		}
+		remainder = xhci_td_remainder(xhci, running_total, trb_buff_len,
+					   urb->transfer_buffer_length,
+					   urb, num_trbs - 1);
+
 		length_field = TRB_LEN(trb_buff_len) |
-			remainder |
+			TRB_TD_SIZE(remainder) |
 			TRB_INTR_TARGET(0);
 
 		if (num_trbs > 1)
@@ -3441,7 +3422,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	struct usb_ctrlrequest *setup;
 	struct xhci_generic_trb *start_trb;
 	int start_cycle;
-	u32 field, length_field;
+	u32 field, length_field, remainder;
 	struct urb_priv *urb_priv;
 	struct xhci_td *td;
 
@@ -3514,9 +3495,15 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	else
 		field = TRB_TYPE(TRB_DATA);
 
+	remainder = xhci_td_remainder(xhci, 0,
+				   urb->transfer_buffer_length,
+				   urb->transfer_buffer_length,
+				   urb, 1);
+
 	length_field = TRB_LEN(urb->transfer_buffer_length) |
-		xhci_td_remainder(urb->transfer_buffer_length) |
+		TRB_TD_SIZE(remainder) |
 		TRB_INTR_TARGET(0);
+
 	if (urb->transfer_buffer_length > 0) {
 		if (setup->bRequestType & USB_DIR_IN)
 			field |= TRB_DIR_IN;
@@ -3845,17 +3832,12 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 				trb_buff_len = td_remain_len;
 
 			/* Set the TRB length, TD size, & interrupter fields. */
-			if (xhci->hci_version < 0x100) {
-				remainder = xhci_td_remainder(
-						td_len - running_total);
-			} else {
-				remainder = xhci_v1_0_td_remainder(
-						running_total, trb_buff_len,
-						total_packet_count, urb,
-						(trbs_per_td - j - 1));
-			}
+			remainder = xhci_td_remainder(xhci, running_total,
+						   trb_buff_len, td_len,
+						   urb, trbs_per_td - j - 1);
+
 			length_field = TRB_LEN(trb_buff_len) |
-				remainder |
+				TRB_TD_SIZE(remainder) |
 				TRB_INTR_TARGET(0);
 
 			queue_trb(xhci, ep_ring, more_trbs_coming,
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9957bd96d4bc383dd9f27a557af157c8d7343fc8..6e7dc6f93978c54e300caaa1b53155a672c91019 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3973,7 +3973,7 @@ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
 	__le32 __iomem *addr;
 	int raw_port;
 
-	if (hcd->speed != HCD_USB3)
+	if (hcd->speed < HCD_USB3)
 		addr = xhci->usb2_ports[port1 - 1];
 	else
 		addr = xhci->usb3_ports[port1 - 1];
@@ -4124,7 +4124,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
 	int		hird, exit_latency;
 	int		ret;
 
-	if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support ||
+	if (hcd->speed >= HCD_USB3 || !xhci->hw_lpm_support ||
 			!udev->lpm_capable)
 		return -EPERM;
 
@@ -4241,7 +4241,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int		portnum = udev->portnum - 1;
 
-	if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support ||
+	if (hcd->speed >= HCD_USB3 || !xhci->sw_lpm_support ||
 			!udev->lpm_capable)
 		return 0;
 
@@ -4841,8 +4841,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 	/* XHCI controllers don't stop the ep queue on short packets :| */
 	hcd->self.no_stop_on_short = 1;
 
+	xhci = hcd_to_xhci(hcd);
+
 	if (usb_hcd_is_primary_hcd(hcd)) {
-		xhci = hcd_to_xhci(hcd);
 		xhci->main_hcd = hcd;
 		/* Mark the first roothub as being USB 2.0.
 		 * The xHCI driver will register the USB 3.0 roothub.
@@ -4856,6 +4857,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 		 */
 		hcd->has_tt = 1;
 	} else {
+		if (xhci->sbrn == 0x31) {
+			xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n");
+			hcd->speed = HCD_USB31;
+		}
 		/* xHCI private pointer was set in xhci_pci_probe for the second
 		 * registered roothub.
 		 */
@@ -4875,6 +4880,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 	xhci->hcc_params = readl(&xhci->cap_regs->hc_capbase);
 	xhci->hci_version = HC_VERSION(xhci->hcc_params);
 	xhci->hcc_params = readl(&xhci->cap_regs->hcc_params);
+	if (xhci->hci_version > 0x100)
+		xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2);
 	xhci_print_registers(xhci);
 
 	xhci->quirks = quirks;
@@ -4906,6 +4913,16 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 			!dma_set_mask(dev, DMA_BIT_MASK(64))) {
 		xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
 		dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
+	} else {
+		/*
+		 * This is to avoid error in cases where a 32-bit USB
+		 * controller is used on a 64-bit capable system.
+		 */
+		retval = dma_set_mask(dev, DMA_BIT_MASK(32));
+		if (retval)
+			return retval;
+		xhci_dbg(xhci, "Enabling 32-bit DMA addresses.\n");
+		dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
 	}
 
 	xhci_dbg(xhci, "Calling HCD init\n");
@@ -5020,7 +5037,7 @@ static int __init xhci_hcd_init(void)
 	BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
 	BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
 	BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
-	BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8);
+	BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 8*32/8);
 	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);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index dbda41e91c843f2e289c4a4aa0d4129f2641f2a9..be9048e2d4d4f1cc4f40003e89c2553358420122 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -29,6 +29,8 @@
 #include <linux/kernel.h>
 #include <linux/usb/hcd.h>
 
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
 /* Code sharing between pci-quirks and xhci hcd */
 #include	"xhci-ext-caps.h"
 #include "pci-quirks.h"
@@ -56,6 +58,7 @@
  * @hcc_params:		HCCPARAMS - Capability Parameters
  * @db_off:		DBOFF - Doorbell array offset
  * @run_regs_off:	RTSOFF - Runtime register space offset
+ * @hcc_params2:	HCCPARAMS2 Capability Parameters 2, xhci 1.1 only
  */
 struct xhci_cap_regs {
 	__le32	hc_capbase;
@@ -65,6 +68,7 @@ struct xhci_cap_regs {
 	__le32	hcc_params;
 	__le32	db_off;
 	__le32	run_regs_off;
+	__le32	hcc_params2; /* xhci 1.1 */
 	/* Reserved up to (CAPLENGTH - 0x1C) */
 };
 
@@ -134,6 +138,21 @@ struct xhci_cap_regs {
 /* run_regs_off bitmask - bits 0:4 reserved */
 #define	RTSOFF_MASK	(~0x1f)
 
+/* HCCPARAMS2 - hcc_params2 - bitmasks */
+/* true: HC supports U3 entry Capability */
+#define	HCC2_U3C(p)		((p) & (1 << 0))
+/* true: HC supports Configure endpoint command Max exit latency too large */
+#define	HCC2_CMC(p)		((p) & (1 << 1))
+/* true: HC supports Force Save context Capability */
+#define	HCC2_FSC(p)		((p) & (1 << 2))
+/* true: HC supports Compliance Transition Capability */
+#define	HCC2_CTC(p)		((p) & (1 << 3))
+/* true: HC support Large ESIT payload Capability > 48k */
+#define	HCC2_LEC(p)		((p) & (1 << 4))
+/* true: HC support Configuration Information Capability */
+#define	HCC2_CIC(p)		((p) & (1 << 5))
+/* true: HC support Extended TBC Capability, Isoc burst count > 65535 */
+#define	HCC2_ETC(p)		((p) & (1 << 6))
 
 /* Number of registers per port */
 #define	NUM_PORT_REGS	4
@@ -269,7 +288,11 @@ struct xhci_op_regs {
 /* CONFIG - Configure Register - config_reg bitmasks */
 /* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */
 #define MAX_DEVS(p)	((p) & 0xff)
-/* bits 8:31 - reserved and should be preserved */
+/* bit 8: U3 Entry Enabled, assert PLC when root port enters U3, xhci 1.1 */
+#define CONFIG_U3E		(1 << 8)
+/* bit 9: Configuration Information Enable, xhci 1.1 */
+#define CONFIG_CIE		(1 << 9)
+/* bits 10:31 - reserved and should be preserved */
 
 /* PORTSC - Port Status and Control Register - port_status_base bitmasks */
 /* true: device connected */
@@ -306,11 +329,16 @@ struct xhci_op_regs {
 #define	XDEV_LS			(0x2 << 10)
 #define	XDEV_HS			(0x3 << 10)
 #define	XDEV_SS			(0x4 << 10)
+#define	XDEV_SSP		(0x5 << 10)
 #define DEV_UNDEFSPEED(p)	(((p) & DEV_SPEED_MASK) == (0x0<<10))
 #define DEV_FULLSPEED(p)	(((p) & DEV_SPEED_MASK) == XDEV_FS)
 #define DEV_LOWSPEED(p)		(((p) & DEV_SPEED_MASK) == XDEV_LS)
 #define DEV_HIGHSPEED(p)	(((p) & DEV_SPEED_MASK) == XDEV_HS)
 #define DEV_SUPERSPEED(p)	(((p) & DEV_SPEED_MASK) == XDEV_SS)
+#define DEV_SUPERSPEEDPLUS(p)	(((p) & DEV_SPEED_MASK) == XDEV_SSP)
+#define DEV_SUPERSPEED_ANY(p)	(((p) & DEV_SPEED_MASK) >= XDEV_SS)
+#define DEV_PORT_SPEED(p)	(((p) >> 10) & 0x0f)
+
 /* Bits 20:23 in the Slot Context are the speed for the device */
 #define	SLOT_SPEED_FS		(XDEV_FS << 10)
 #define	SLOT_SPEED_LS		(XDEV_LS << 10)
@@ -394,6 +422,9 @@ struct xhci_op_regs {
 #define	PORT_L1DS(p)		(((p) & 0xff) << 8)
 #define	PORT_HLE		(1 << 16)
 
+/* USB3 Protocol PORTLI  Port Link Information */
+#define PORT_RX_LANES(p)	(((p) >> 16) & 0xf)
+#define PORT_TX_LANES(p)	(((p) >> 20) & 0xf)
 
 /* USB2 Protocol PORTHLPMC */
 #define PORT_HIRDM(p)((p) & 3)
@@ -519,9 +550,23 @@ struct xhci_protocol_caps {
 };
 
 #define	XHCI_EXT_PORT_MAJOR(x)	(((x) >> 24) & 0xff)
+#define	XHCI_EXT_PORT_MINOR(x)	(((x) >> 16) & 0xff)
+#define	XHCI_EXT_PORT_PSIC(x)	(((x) >> 28) & 0x0f)
 #define	XHCI_EXT_PORT_OFF(x)	((x) & 0xff)
 #define	XHCI_EXT_PORT_COUNT(x)	(((x) >> 8) & 0xff)
 
+#define	XHCI_EXT_PORT_PSIV(x)	(((x) >> 0) & 0x0f)
+#define	XHCI_EXT_PORT_PSIE(x)	(((x) >> 4) & 0x03)
+#define	XHCI_EXT_PORT_PLT(x)	(((x) >> 6) & 0x03)
+#define	XHCI_EXT_PORT_PFD(x)	(((x) >> 8) & 0x01)
+#define	XHCI_EXT_PORT_LP(x)	(((x) >> 14) & 0x03)
+#define	XHCI_EXT_PORT_PSIM(x)	(((x) >> 16) & 0xffff)
+
+#define PLT_MASK        (0x03 << 6)
+#define PLT_SYM         (0x00 << 6)
+#define PLT_ASYM_RX     (0x02 << 6)
+#define PLT_ASYM_TX     (0x03 << 6)
+
 /**
  * struct xhci_container_ctx
  * @type: Type of context.  Used to calculated offsets to contained contexts.
@@ -1136,6 +1181,8 @@ enum xhci_setup_dev {
 /* Normal TRB fields */
 /* transfer_len bitmasks - bits 0:16 */
 #define	TRB_LEN(p)		((p) & 0x1ffff)
+/* TD Size, packets remaining in this TD, bits 21:17 (5 bits, so max 31) */
+#define TRB_TD_SIZE(p)          (min((p), (u32)31) << 17)
 /* Interrupter Target - which MSI-X vector to target the completion event at */
 #define TRB_INTR_TARGET(p)	(((p) & 0x3ff) << 22)
 #define GET_INTR_TARGET(p)	(((p) >> 22) & 0x3ff)
@@ -1448,6 +1495,14 @@ static inline unsigned int hcd_index(struct usb_hcd *hcd)
 		return 1;
 }
 
+struct xhci_hub {
+	u8	maj_rev;
+	u8	min_rev;
+	u32	*psi;		/* array of protocol speed ID entries */
+	u8	psi_count;
+	u8	psi_uid_count;
+};
+
 /* There is one xhci_hcd structure per controller */
 struct xhci_hcd {
 	struct usb_hcd *main_hcd;
@@ -1465,6 +1520,7 @@ struct xhci_hcd {
 	__u32		hcs_params2;
 	__u32		hcs_params3;
 	__u32		hcc_params;
+	__u32		hcc_params2;
 
 	spinlock_t	lock;
 
@@ -1586,6 +1642,8 @@ struct xhci_hcd {
 	unsigned int		num_usb3_ports;
 	/* Array of pointers to USB 2.0 PORTSC registers */
 	__le32 __iomem		**usb2_ports;
+	struct xhci_hub		usb2_rhub;
+	struct xhci_hub		usb3_rhub;
 	unsigned int		num_usb2_ports;
 	/* support xHCI 0.96 spec USB2 software LPM */
 	unsigned		sw_lpm_support:1;
@@ -1651,20 +1709,12 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
 static inline u64 xhci_read_64(const struct xhci_hcd *xhci,
 		__le64 __iomem *regs)
 {
-	__u32 __iomem *ptr = (__u32 __iomem *) regs;
-	u64 val_lo = readl(ptr);
-	u64 val_hi = readl(ptr + 1);
-	return val_lo + (val_hi << 32);
+	return lo_hi_readq(regs);
 }
 static inline void xhci_write_64(struct xhci_hcd *xhci,
 				 const u64 val, __le64 __iomem *regs)
 {
-	__u32 __iomem *ptr = (__u32 __iomem *) regs;
-	u32 val_lo = lower_32_bits(val);
-	u32 val_hi = upper_32_bits(val);
-
-	writel(val_lo, ptr);
-	writel(val_hi, ptr + 1);
+	lo_hi_writeq(val, regs);
 }
 
 static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci)
diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
index 64ff5b91752d2187c0c949927dfa311b49531460..b45cb77c0744599a2ae7f77a12f3e014a59cba7a 100644
--- a/drivers/usb/misc/usb3503.c
+++ b/drivers/usb/misc/usb3503.c
@@ -410,7 +410,7 @@ static int __init usb3503_init(void)
 {
 	int err;
 
-	err = i2c_register_driver(THIS_MODULE, &usb3503_i2c_driver);
+	err = i2c_add_driver(&usb3503_i2c_driver);
 	if (err != 0)
 		pr_err("usb3503: Failed to register I2C driver: %d\n", err);
 
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 9517812a50e2982aa45db4102092c90e9732598f..637f3f7cfce8b884167ccd6e25c9d6de9cd0eaf6 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -17,6 +17,7 @@
 static int override_alt = -1;
 module_param_named(alt, override_alt, int, 0644);
 MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection");
+static void complicated_callback(struct urb *urb);
 
 /*-------------------------------------------------------------------------*/
 
@@ -95,6 +96,7 @@ static struct usb_device *testdev_to_usbdev(struct usbtest_dev *test)
 	dev_warn(&(tdev)->intf->dev , fmt , ## args)
 
 #define GUARD_BYTE	0xA5
+#define MAX_SGLEN	128
 
 /*-------------------------------------------------------------------------*/
 
@@ -238,7 +240,8 @@ static struct urb *usbtest_alloc_urb(
 	unsigned long		bytes,
 	unsigned		transfer_flags,
 	unsigned		offset,
-	u8			bInterval)
+	u8			bInterval,
+	usb_complete_t		complete_fn)
 {
 	struct urb		*urb;
 
@@ -247,10 +250,10 @@ static struct urb *usbtest_alloc_urb(
 		return urb;
 
 	if (bInterval)
-		usb_fill_int_urb(urb, udev, pipe, NULL, bytes, simple_callback,
+		usb_fill_int_urb(urb, udev, pipe, NULL, bytes, complete_fn,
 				NULL, bInterval);
 	else
-		usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback,
+		usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, complete_fn,
 				NULL);
 
 	urb->interval = (udev->speed == USB_SPEED_HIGH)
@@ -295,7 +298,17 @@ static struct urb *simple_alloc_urb(
 	u8			bInterval)
 {
 	return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0,
-			bInterval);
+			bInterval, simple_callback);
+}
+
+static struct urb *complicated_alloc_urb(
+	struct usb_device	*udev,
+	int			pipe,
+	unsigned long		bytes,
+	u8			bInterval)
+{
+	return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0,
+			bInterval, complicated_callback);
 }
 
 static unsigned pattern;
@@ -303,11 +316,20 @@ static unsigned mod_pattern;
 module_param_named(pattern, mod_pattern, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(mod_pattern, "i/o pattern (0 == zeroes)");
 
-static inline void simple_fill_buf(struct urb *urb)
+static unsigned get_maxpacket(struct usb_device *udev, int pipe)
+{
+	struct usb_host_endpoint	*ep;
+
+	ep = usb_pipe_endpoint(udev, pipe);
+	return le16_to_cpup(&ep->desc.wMaxPacketSize);
+}
+
+static void simple_fill_buf(struct urb *urb)
 {
 	unsigned	i;
 	u8		*buf = urb->transfer_buffer;
 	unsigned	len = urb->transfer_buffer_length;
+	unsigned	maxpacket;
 
 	switch (pattern) {
 	default:
@@ -316,8 +338,9 @@ static inline void simple_fill_buf(struct urb *urb)
 		memset(buf, 0, len);
 		break;
 	case 1:			/* mod63 */
+		maxpacket = get_maxpacket(urb->dev, urb->pipe);
 		for (i = 0; i < len; i++)
-			*buf++ = (u8) (i % 63);
+			*buf++ = (u8) ((i % maxpacket) % 63);
 		break;
 	}
 }
@@ -349,6 +372,7 @@ static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
 	u8		expected;
 	u8		*buf = urb->transfer_buffer;
 	unsigned	len = urb->actual_length;
+	unsigned	maxpacket = get_maxpacket(urb->dev, urb->pipe);
 
 	int ret = check_guard_bytes(tdev, urb);
 	if (ret)
@@ -366,7 +390,7 @@ static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
 		 * with set_interface or set_config.
 		 */
 		case 1:			/* mod63 */
-			expected = i % 63;
+			expected = (i % maxpacket) % 63;
 			break;
 		/* always fail unsupported patterns */
 		default:
@@ -478,11 +502,13 @@ static void free_sglist(struct scatterlist *sg, int nents)
 }
 
 static struct scatterlist *
-alloc_sglist(int nents, int max, int vary)
+alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
 {
 	struct scatterlist	*sg;
 	unsigned		i;
 	unsigned		size = max;
+	unsigned		maxpacket =
+		get_maxpacket(interface_to_usbdev(dev->intf), pipe);
 
 	if (max == 0)
 		return NULL;
@@ -511,7 +537,7 @@ alloc_sglist(int nents, int max, int vary)
 			break;
 		case 1:
 			for (j = 0; j < size; j++)
-				*buf++ = (u8) (j % 63);
+				*buf++ = (u8) ((j % maxpacket) % 63);
 			break;
 		}
 
@@ -1719,7 +1745,7 @@ static int ctrl_out(struct usbtest_dev *dev,
 	for (i = 0; i < count; i++) {
 		/* write patterned data */
 		for (j = 0; j < len; j++)
-			buf[j] = i + j;
+			buf[j] = (u8)(i + j);
 		retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				0x5b, USB_DIR_OUT|USB_TYPE_VENDOR,
 				0, 0, buf, len, USB_CTRL_SET_TIMEOUT);
@@ -1749,9 +1775,9 @@ static int ctrl_out(struct usbtest_dev *dev,
 
 		/* fail if we can't verify */
 		for (j = 0; j < len; j++) {
-			if (buf[j] != (u8) (i + j)) {
+			if (buf[j] != (u8)(i + j)) {
 				ERROR(dev, "ctrl_out, byte %d is %d not %d\n",
-					j, buf[j], (u8) i + j);
+					j, buf[j], (u8)(i + j));
 				retval = -EBADMSG;
 				break;
 			}
@@ -1781,12 +1807,12 @@ static int ctrl_out(struct usbtest_dev *dev,
 
 /*-------------------------------------------------------------------------*/
 
-/* ISO tests ... mimics common usage
+/* ISO/BULK tests ... mimics common usage
  *  - buffer length is split into N packets (mostly maxpacket sized)
  *  - multi-buffers according to sglen
  */
 
-struct iso_context {
+struct transfer_context {
 	unsigned		count;
 	unsigned		pending;
 	spinlock_t		lock;
@@ -1795,11 +1821,12 @@ struct iso_context {
 	unsigned long		errors;
 	unsigned long		packet_count;
 	struct usbtest_dev	*dev;
+	bool			is_iso;
 };
 
-static void iso_callback(struct urb *urb)
+static void complicated_callback(struct urb *urb)
 {
-	struct iso_context	*ctx = urb->context;
+	struct transfer_context	*ctx = urb->context;
 
 	spin_lock(&ctx->lock);
 	ctx->count--;
@@ -1808,7 +1835,7 @@ static void iso_callback(struct urb *urb)
 	if (urb->error_count > 0)
 		ctx->errors += urb->error_count;
 	else if (urb->status != 0)
-		ctx->errors += urb->number_of_packets;
+		ctx->errors += (ctx->is_iso ? urb->number_of_packets : 1);
 	else if (urb->actual_length != urb->transfer_buffer_length)
 		ctx->errors++;
 	else if (check_guard_bytes(ctx->dev, urb) != 0)
@@ -1895,7 +1922,7 @@ static struct urb *iso_alloc_urb(
 		urb->iso_frame_desc[i].offset = maxp * i;
 	}
 
-	urb->complete = iso_callback;
+	urb->complete = complicated_callback;
 	/* urb->context = SET BY CALLER */
 	urb->interval = 1 << (desc->bInterval - 1);
 	urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
@@ -1903,37 +1930,33 @@ static struct urb *iso_alloc_urb(
 }
 
 static int
-test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
+test_queue(struct usbtest_dev *dev, struct usbtest_param *param,
 		int pipe, struct usb_endpoint_descriptor *desc, unsigned offset)
 {
-	struct iso_context	context;
+	struct transfer_context	context;
 	struct usb_device	*udev;
 	unsigned		i;
 	unsigned long		packets = 0;
 	int			status = 0;
-	struct urb		*urbs[10];	/* FIXME no limit */
-
-	if (param->sglen > 10)
-		return -EDOM;
+	struct urb		*urbs[param->sglen];
 
 	memset(&context, 0, sizeof(context));
 	context.count = param->iterations * param->sglen;
 	context.dev = dev;
+	context.is_iso = !!desc;
 	init_completion(&context.done);
 	spin_lock_init(&context.lock);
 
-	memset(urbs, 0, sizeof(urbs));
 	udev = testdev_to_usbdev(dev);
-	dev_info(&dev->intf->dev,
-		"iso period %d %sframes, wMaxPacket %d, transactions: %d\n",
-		1 << (desc->bInterval - 1),
-		(udev->speed == USB_SPEED_HIGH) ? "micro" : "",
-		usb_endpoint_maxp(desc) & 0x7ff,
-		1 + (0x3 & (usb_endpoint_maxp(desc) >> 11)));
 
 	for (i = 0; i < param->sglen; i++) {
-		urbs[i] = iso_alloc_urb(udev, pipe, desc,
+		if (context.is_iso)
+			urbs[i] = iso_alloc_urb(udev, pipe, desc,
 					param->length, offset);
+		else
+			urbs[i] = complicated_alloc_urb(udev, pipe,
+					param->length, 0);
+
 		if (!urbs[i]) {
 			status = -ENOMEM;
 			goto fail;
@@ -1942,11 +1965,21 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
 		urbs[i]->context = &context;
 	}
 	packets *= param->iterations;
-	dev_info(&dev->intf->dev,
-		"total %lu msec (%lu packets)\n",
-		(packets * (1 << (desc->bInterval - 1)))
-			/ ((udev->speed == USB_SPEED_HIGH) ? 8 : 1),
-		packets);
+
+	if (context.is_iso) {
+		dev_info(&dev->intf->dev,
+			"iso period %d %sframes, wMaxPacket %d, transactions: %d\n",
+			1 << (desc->bInterval - 1),
+			(udev->speed == USB_SPEED_HIGH) ? "micro" : "",
+			usb_endpoint_maxp(desc) & 0x7ff,
+			1 + (0x3 & (usb_endpoint_maxp(desc) >> 11)));
+
+		dev_info(&dev->intf->dev,
+			"total %lu msec (%lu packets)\n",
+			(packets * (1 << (desc->bInterval - 1)))
+				/ ((udev->speed == USB_SPEED_HIGH) ? 8 : 1),
+			packets);
+	}
 
 	spin_lock_irq(&context.lock);
 	for (i = 0; i < param->sglen; i++) {
@@ -1983,7 +2016,8 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param,
 		;
 	else if (context.submit_error)
 		status = -EACCES;
-	else if (context.errors > context.packet_count / 10)
+	else if (context.errors >
+			(context.is_iso ? context.packet_count / 10 : 0))
 		status = -EIO;
 	return status;
 
@@ -2004,8 +2038,8 @@ static int test_unaligned_bulk(
 	const char *label)
 {
 	int retval;
-	struct urb *urb = usbtest_alloc_urb(
-		testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0);
+	struct urb *urb = usbtest_alloc_urb(testdev_to_usbdev(tdev),
+			pipe, length, transfer_flags, 1, 0, simple_callback);
 
 	if (!urb)
 		return -ENOMEM;
@@ -2061,6 +2095,9 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 	if (param->iterations <= 0)
 		return -EINVAL;
 
+	if (param->sglen > MAX_SGLEN)
+		return -EINVAL;
+
 	if (mutex_lock_interruptible(&dev->lock))
 		return -ERESTARTSYS;
 
@@ -2176,7 +2213,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 5:  write %d sglists %d entries of %d bytes\n",
 				param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist(param->sglen, param->length, 0);
+		sg = alloc_sglist(param->sglen, param->length,
+				0, dev, dev->out_pipe);
 		if (!sg) {
 			retval = -ENOMEM;
 			break;
@@ -2194,7 +2232,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 6:  read %d sglists %d entries of %d bytes\n",
 				param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist(param->sglen, param->length, 0);
+		sg = alloc_sglist(param->sglen, param->length,
+				0, dev, dev->in_pipe);
 		if (!sg) {
 			retval = -ENOMEM;
 			break;
@@ -2211,7 +2250,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 7:  write/%d %d sglists %d entries 0..%d bytes\n",
 				param->vary, param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist(param->sglen, param->length, param->vary);
+		sg = alloc_sglist(param->sglen, param->length,
+				param->vary, dev, dev->out_pipe);
 		if (!sg) {
 			retval = -ENOMEM;
 			break;
@@ -2228,7 +2268,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 8:  read/%d %d sglists %d entries 0..%d bytes\n",
 				param->vary, param->iterations,
 				param->sglen, param->length);
-		sg = alloc_sglist(param->sglen, param->length, param->vary);
+		sg = alloc_sglist(param->sglen, param->length,
+				param->vary, dev, dev->in_pipe);
 		if (!sg) {
 			retval = -ENOMEM;
 			break;
@@ -2325,7 +2366,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 				param->iterations,
 				param->sglen, param->length);
 		/* FIRMWARE:  iso sink */
-		retval = test_iso_queue(dev, param,
+		retval = test_queue(dev, param,
 				dev->out_iso_pipe, dev->iso_out, 0);
 		break;
 
@@ -2338,7 +2379,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 				param->iterations,
 				param->sglen, param->length);
 		/* FIRMWARE:  iso source */
-		retval = test_iso_queue(dev, param,
+		retval = test_queue(dev, param,
 				dev->in_iso_pipe, dev->iso_in, 0);
 		break;
 
@@ -2419,7 +2460,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 22:  write %d iso odd, %d entries of %d bytes\n",
 				param->iterations,
 				param->sglen, param->length);
-		retval = test_iso_queue(dev, param,
+		retval = test_queue(dev, param,
 				dev->out_iso_pipe, dev->iso_out, 1);
 		break;
 
@@ -2430,7 +2471,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 			"TEST 23:  read %d iso odd, %d entries of %d bytes\n",
 				param->iterations,
 				param->sglen, param->length);
-		retval = test_iso_queue(dev, param,
+		retval = test_queue(dev, param,
 				dev->in_iso_pipe, dev->iso_in, 1);
 		break;
 
@@ -2487,6 +2528,25 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 		retval = simple_io(dev, urb, param->iterations, 0, 0, "test26");
 		simple_free_urb(urb);
 		break;
+	case 27:
+		/* We do performance test, so ignore data compare */
+		if (dev->out_pipe == 0 || param->sglen == 0 || pattern != 0)
+			break;
+		dev_info(&intf->dev,
+			"TEST 27: bulk write %dMbytes\n", (param->iterations *
+			param->sglen * param->length) / (1024 * 1024));
+		retval = test_queue(dev, param,
+				dev->out_pipe, NULL, 0);
+		break;
+	case 28:
+		if (dev->in_pipe == 0 || param->sglen == 0 || pattern != 0)
+			break;
+		dev_info(&intf->dev,
+			"TEST 28: bulk read %dMbytes\n", (param->iterations *
+			param->sglen * param->length) / (1024 * 1024));
+		retval = test_queue(dev, param,
+				dev->in_pipe, NULL, 0);
+		break;
 	}
 	do_gettimeofday(&param->duration);
 	param->duration.tv_sec -= start.tv_sec;
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 4a518ff123106b0931082bd51f0705c8e8ca0bb7..ba13529cbd52ff82658e88bdba30db82a8e99790 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1028,18 +1028,22 @@ void musb_start(struct musb *musb)
 {
 	void __iomem    *regs = musb->mregs;
 	u8              devctl = musb_readb(regs, MUSB_DEVCTL);
+	u8		power;
 
 	dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
 
 	musb_enable_interrupts(musb);
 	musb_writeb(regs, MUSB_TESTMODE, 0);
 
-	/* put into basic highspeed mode and start session */
-	musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
-			| MUSB_POWER_HSENAB
-			/* ENSUSPEND wedges tusb */
-			/* | MUSB_POWER_ENSUSPEND */
-		   );
+	power = MUSB_POWER_ISOUPDATE;
+	/*
+	 * treating UNKNOWN as unspecified maximum speed, in which case
+	 * we will default to high-speed.
+	 */
+	if (musb->config->maximum_speed == USB_SPEED_HIGH ||
+			musb->config->maximum_speed == USB_SPEED_UNKNOWN)
+		power |= MUSB_POWER_HSENAB;
+	musb_writeb(regs, MUSB_POWER, power);
 
 	musb->is_active = 0;
 	devctl = musb_readb(regs, MUSB_DEVCTL);
@@ -1771,13 +1775,20 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
 	unsigned long	flags;
 	unsigned long	val;
 	int		vbus;
+	u8		devctl;
 
 	spin_lock_irqsave(&musb->lock, flags);
 	val = musb->a_wait_bcon;
-	/* FIXME get_vbus_status() is normally #defined as false...
-	 * and is effectively TUSB-specific.
-	 */
 	vbus = musb_platform_get_vbus_status(musb);
+	if (vbus < 0) {
+		/* Use default MUSB method by means of DEVCTL register */
+		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+		if ((devctl & MUSB_DEVCTL_VBUS)
+				== (3 << MUSB_DEVCTL_VBUS_SHIFT))
+			vbus = 1;
+		else
+			vbus = 0;
+	}
 	spin_unlock_irqrestore(&musb->lock, flags);
 
 	return sprintf(buf, "Vbus %s, timeout %lu msec\n",
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 4b886d0f6bdf1bcf10ca5477b9ea0820efc8d5b1..2337d7a7d62d66c75cfd2761b8e796352244d64a 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -579,7 +579,7 @@ static inline int  musb_platform_recover(struct musb *musb)
 static inline int musb_platform_get_vbus_status(struct musb *musb)
 {
 	if (!musb->ops->vbus_status)
-		return 0;
+		return -EINVAL;
 
 	return musb->ops->vbus_status(musb);
 }
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 84512d1d5eee1583fb057d6f45613f25293dc25b..eeb7d9ecf7df34ea1aa906330f55ba40952f4be1 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -666,7 +666,7 @@ static int get_musb_port_mode(struct device *dev)
 {
 	enum usb_dr_mode mode;
 
-	mode = of_usb_get_dr_mode(dev->of_node);
+	mode = usb_get_dr_mode(dev);
 	switch (mode) {
 	case USB_DR_MODE_HOST:
 		return MUSB_PORT_MODE_HOST;
@@ -747,6 +747,19 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
 	if (!ret && val)
 		config->multipoint = true;
 
+	config->maximum_speed = usb_get_maximum_speed(&parent->dev);
+	switch (config->maximum_speed) {
+	case USB_SPEED_LOW:
+	case USB_SPEED_FULL:
+		break;
+	case USB_SPEED_SUPER:
+		dev_warn(dev, "ignore incorrect maximum_speed "
+				"(super-speed) setting in dts");
+		/* fall through */
+	default:
+		config->maximum_speed = USB_SPEED_HIGH;
+	}
+
 	ret = platform_device_add_data(musb, &pdata, sizeof(pdata));
 	if (ret) {
 		dev_err(dev, "failed to add platform_data\n");
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index f9f6304ad854777fe7680a4d03e2432c98ba6a58..d9b0dc461439aa414b9942826453fb44fd6941de 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -341,6 +341,16 @@ static void sunxi_musb_disable(struct musb *musb)
 	clear_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags);
 }
 
+struct dma_controller *sunxi_musb_dma_controller_create(struct musb *musb,
+						    void __iomem *base)
+{
+	return NULL;
+}
+
+void sunxi_musb_dma_controller_destroy(struct dma_controller *c)
+{
+}
+
 /*
  * sunxi musb register layout
  * 0x00 - 0x17	fifo regs, 1 long per fifo
@@ -566,6 +576,8 @@ static const struct musb_platform_ops sunxi_musb_ops = {
 	.writeb		= sunxi_musb_writeb,
 	.readw		= sunxi_musb_readw,
 	.writew		= sunxi_musb_writew,
+	.dma_init	= sunxi_musb_dma_controller_create,
+	.dma_exit	= sunxi_musb_dma_controller_destroy,
 	.set_vbus	= sunxi_musb_set_vbus,
 	.pre_root_reset_end = sunxi_musb_pre_root_reset_end,
 	.post_root_reset_end = sunxi_musb_post_root_reset_end,
@@ -617,7 +629,7 @@ static int sunxi_musb_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	memset(&pdata, 0, sizeof(pdata));
-	switch (of_usb_get_dr_mode(np)) {
+	switch (usb_get_dr_mode(&pdev->dev)) {
 #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST
 	case USB_DR_MODE_HOST:
 		pdata.mode = MUSB_PORT_MODE_HOST;
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index c58c3c0dbe35edebec10a89ad7477484f4cab902..80eb991c2506c758315cc2e6e1f39b6ebbf319f4 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -1529,7 +1529,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
 	if (IS_ERR(motg->phy_rst))
 		motg->phy_rst = NULL;
 
-	pdata->mode = of_usb_get_dr_mode(node);
+	pdata->mode = usb_get_dr_mode(&pdev->dev);
 	if (pdata->mode == USB_DR_MODE_UNKNOWN)
 		pdata->mode = USB_DR_MODE_OTG;
 
diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c
index 5d357a94599ecb91f2070e6e8b5d79302fd6b917..579587d972177338e97ca7ece02fabbc60fdcf55 100644
--- a/drivers/usb/phy/phy-qcom-8x16-usb.c
+++ b/drivers/usb/phy/phy-qcom-8x16-usb.c
@@ -71,7 +71,7 @@ struct phy_8x16 {
 
 	struct reset_control		*phy_reset;
 
-	struct extcon_specific_cable_nb vbus_cable;
+	struct extcon_dev		*vbus_edev;
 	struct notifier_block		vbus_notify;
 
 	struct gpio_desc		*switch_gpio;
@@ -234,7 +234,7 @@ static int phy_8x16_init(struct usb_phy *phy)
 	val = ULPI_PWR_OTG_COMP_DISABLE;
 	usb_phy_io_write(phy, val, ULPI_SET(ULPI_PWR_CLK_MNG_REG));
 
-	state = extcon_get_cable_state(qphy->vbus_cable.edev, "USB");
+	state = extcon_get_cable_state_(qphy->vbus_edev, EXTCON_USB);
 	if (state)
 		phy_8x16_vbus_on(qphy);
 	else
@@ -314,7 +314,6 @@ static int phy_8x16_reboot_notify(struct notifier_block *this,
 
 static int phy_8x16_probe(struct platform_device *pdev)
 {
-	struct extcon_dev *edev;
 	struct phy_8x16 *qphy;
 	struct resource *res;
 	struct usb_phy *phy;
@@ -349,9 +348,9 @@ static int phy_8x16_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	edev = extcon_get_edev_by_phandle(phy->dev, 0);
-	if (IS_ERR(edev))
-		return PTR_ERR(edev);
+	qphy->vbus_edev = extcon_get_edev_by_phandle(phy->dev, 0);
+	if (IS_ERR(qphy->vbus_edev))
+		return PTR_ERR(qphy->vbus_edev);
 
 	ret = clk_set_rate(qphy->core_clk, INT_MAX);
 	if (ret < 0)
@@ -370,8 +369,8 @@ static int phy_8x16_probe(struct platform_device *pdev)
 		goto off_clks;
 
 	qphy->vbus_notify.notifier_call = phy_8x16_vbus_notify;
-	ret = extcon_register_interest(&qphy->vbus_cable, edev->name,
-				       "USB", &qphy->vbus_notify);
+	ret = extcon_register_notifier(qphy->vbus_edev, EXTCON_USB,
+				       &qphy->vbus_notify);
 	if (ret < 0)
 		goto off_power;
 
@@ -385,7 +384,8 @@ static int phy_8x16_probe(struct platform_device *pdev)
 	return 0;
 
 off_extcon:
-	extcon_unregister_interest(&qphy->vbus_cable);
+	extcon_unregister_notifier(qphy->vbus_edev, EXTCON_USB,
+				   &qphy->vbus_notify);
 off_power:
 	phy_8x16_regulators_disable(qphy);
 off_clks:
@@ -400,7 +400,8 @@ static int phy_8x16_remove(struct platform_device *pdev)
 	struct phy_8x16 *qphy = platform_get_drvdata(pdev);
 
 	unregister_reboot_notifier(&qphy->reboot_notify);
-	extcon_unregister_interest(&qphy->vbus_cable);
+	extcon_unregister_notifier(qphy->vbus_edev, EXTCON_USB,
+				   &qphy->vbus_notify);
 
 	/*
 	 * Ensure that D+/D- lines are routed to uB connector, so
diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
index ab025b00964c393b7622b0187486b53dc44f829f..5fe4a5704bde329caf492451be7fdb0593bb3548 100644
--- a/drivers/usb/phy/phy-tegra-usb.c
+++ b/drivers/usb/phy/phy-tegra-usb.c
@@ -1029,7 +1029,7 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
 	}
 
 	if (of_find_property(np, "dr_mode", NULL))
-		tegra_phy->mode = of_usb_get_dr_mode(np);
+		tegra_phy->mode = usb_get_dr_mode(&pdev->dev);
 	else
 		tegra_phy->mode = USB_DR_MODE_HOST;
 
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 0ac1b10be1f73a6d28a825a85dd9e468c9f2a48c..fce82fd79f77bf59db864c2d1f09e166aa5d018a 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -54,8 +54,10 @@
 #define	TI_MODE_CONFIGURING	0   /* Device has not entered start device */
 #define	TI_MODE_BOOT		1   /* Staying in boot mode		   */
 #define TI_MODE_DOWNLOAD	2   /* Made it to download mode		   */
-#define TI_MODE_TRANSITIONING	3   /* Currently in boot mode but
-				       transitioning to download mode	   */
+#define TI_MODE_TRANSITIONING	3   /*
+				     * Currently in boot mode but
+				     * transitioning to download mode
+				     */
 
 /* read urb state */
 #define EDGE_READ_URB_RUNNING	0
@@ -97,9 +99,11 @@ struct edgeport_port {
 	__u8 shadow_mcr;
 	__u8 shadow_lsr;
 	__u8 lsr_mask;
-	__u32 ump_read_timeout;		/* Number of milliseconds the UMP will
-					   wait without data before completing
-					   a read short */
+	__u32 ump_read_timeout;		/*
+					 * Number of milliseconds the UMP will
+					 * wait without data before completing
+					 * a read short
+					 */
 	int baud_rate;
 	int close_pending;
 	int lsr_event;
@@ -115,8 +119,10 @@ struct edgeport_port {
 struct edgeport_serial {
 	struct product_info product_info;
 	u8 TI_I2C_Type;			/* Type of I2C in UMP */
-	u8 TiReadI2C;			/* Set to TRUE if we have read the
-					   I2c in Boot Mode */
+	u8 TiReadI2C;			/*
+					 * Set to TRUE if we have read the
+					 * I2c in Boot Mode
+					 */
 	struct mutex es_lock;
 	int num_ports_open;
 	struct usb_serial *serial;
@@ -223,6 +229,11 @@ static void edge_set_termios(struct tty_struct *tty,
 		struct usb_serial_port *port, struct ktermios *old_termios);
 static void edge_send(struct usb_serial_port *port, struct tty_struct *tty);
 
+static int do_download_mode(struct edgeport_serial *serial,
+		const struct firmware *fw);
+static int do_boot_mode(struct edgeport_serial *serial,
+		const struct firmware *fw);
+
 /* sysfs attributes */
 static int edge_create_sysfs_attrs(struct usb_serial_port *port);
 static int edge_remove_sysfs_attrs(struct usb_serial_port *port);
@@ -324,7 +335,8 @@ static int read_download_mem(struct usb_device *dev, int start_address,
 
 	dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length);
 
-	/* Read in blocks of 64 bytes
+	/*
+	 * Read in blocks of 64 bytes
 	 * (TI firmware can't handle more than 64 byte reads)
 	 */
 	while (length) {
@@ -430,7 +442,6 @@ static int write_boot_mem(struct edgeport_serial *serial,
 	return status;
 }
 
-
 /* Write edgeport I2C memory to TI chip	*/
 static int write_i2c_mem(struct edgeport_serial *serial,
 		int start_address, int length, __u8 address_type, __u8 *buffer)
@@ -472,8 +483,10 @@ static int write_i2c_mem(struct edgeport_serial *serial,
 	start_address	+= write_length;
 	buffer		+= write_length;
 
-	/* We should be aligned now -- can write
-	   max page size bytes at a time */
+	/*
+	 * We should be aligned now -- can write max page size bytes at a
+	 * time.
+	 */
 	while (length) {
 		if (length > EPROM_PAGE_SIZE)
 			write_length = EPROM_PAGE_SIZE;
@@ -506,7 +519,8 @@ static int write_i2c_mem(struct edgeport_serial *serial,
 	return status;
 }
 
-/* Examine the UMP DMA registers and LSR
+/*
+ * Examine the UMP DMA registers and LSR
  *
  * Check the MSBit of the X and Y DMA byte count registers.
  * A zero in this bit indicates that the TX DMA buffers are empty
@@ -523,9 +537,11 @@ static int tx_active(struct edgeport_port *port)
 	if (!oedb)
 		return -ENOMEM;
 
-	lsr = kmalloc(1, GFP_KERNEL);	/* Sigh, that's right, just one byte,
-					   as not all platforms can do DMA
-					   from stack */
+	/*
+	 * Sigh, that's right, just one byte, as not all platforms can
+	 * do DMA from stack
+	 */
+	lsr = kmalloc(1, GFP_KERNEL);
 	if (!lsr) {
 		kfree(oedb);
 		return -ENOMEM;
@@ -615,8 +631,6 @@ static int write_rom(struct edgeport_serial *serial, int start_address,
 	return -EINVAL;
 }
 
-
-
 /* Read a descriptor header from I2C based on type */
 static int get_descriptor_addr(struct edgeport_serial *serial,
 				int desc_type, struct ti_i2c_desc *rom_desc)
@@ -785,8 +799,7 @@ static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer)
 }
 
 /* Build firmware header used for firmware update */
-static int build_i2c_fw_hdr(u8 *header, struct device *dev,
-		const struct firmware *fw)
+static int build_i2c_fw_hdr(u8 *header, const struct firmware *fw)
 {
 	__u8 *buffer;
 	int buffer_size;
@@ -797,7 +810,8 @@ static int build_i2c_fw_hdr(u8 *header, struct device *dev,
 	struct ti_i2c_firmware_rec *firmware_rec;
 	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
 
-	/* In order to update the I2C firmware we must change the type 2 record
+	/*
+	 * In order to update the I2C firmware we must change the type 2 record
 	 * to type 0xF2.  This will force the UMP to come up in Boot Mode.
 	 * Then while in boot mode, the driver will download the latest
 	 * firmware (padded to 15.5k) into the UMP ram.  And finally when the
@@ -806,8 +820,10 @@ static int build_i2c_fw_hdr(u8 *header, struct device *dev,
 	 * update the record type from 0xf2 to 0x02.
 	 */
 
-	/* Allocate a 15.5k buffer + 2 bytes for version number
-	 * (Firmware Record) */
+	/*
+	 * Allocate a 15.5k buffer + 2 bytes for version number (Firmware
+	 * Record)
+	 */
 	buffer_size = (((1024 * 16) - 512 ) +
 			sizeof(struct ti_i2c_firmware_rec));
 
@@ -815,7 +831,7 @@ static int build_i2c_fw_hdr(u8 *header, struct device *dev,
 	if (!buffer)
 		return -ENOMEM;
 
-	// Set entire image of 0xffs
+	/* Set entire image of 0xffs */
 	memset(buffer, 0xff, buffer_size);
 
 	/* Copy version number into firmware record */
@@ -981,32 +997,41 @@ static int check_fw_sanity(struct edgeport_serial *serial,
 	return 0;
 }
 
-/**
+/*
  * DownloadTIFirmware - Download run-time operating firmware to the TI5052
  *
  * This routine downloads the main operating code into the TI5052, using the
  * boot code already burned into E2PROM or ROM.
  */
-static int download_fw(struct edgeport_serial *serial,
-		const struct firmware *fw)
+static int download_fw(struct edgeport_serial *serial)
 {
-	struct device *dev = &serial->serial->dev->dev;
+	struct device *dev = &serial->serial->interface->dev;
 	int status = 0;
-	int start_address;
-	struct edge_ti_manuf_descriptor *ti_manuf_desc;
 	struct usb_interface_descriptor *interface;
-	int download_cur_ver;
-	int download_new_ver;
-	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
+	const struct firmware *fw;
+	const char *fw_name = "edgeport/down3.bin";
+	struct edgeport_fw_hdr *fw_hdr;
 
-	if (check_fw_sanity(serial, fw))
-		return -EINVAL;
+	status = request_firmware(&fw, fw_name, dev);
+	if (status) {
+		dev_err(dev, "Failed to load image \"%s\" err %d\n",
+				fw_name, status);
+		return status;
+	}
+
+	if (check_fw_sanity(serial, fw)) {
+		status = -EINVAL;
+		goto out;
+	}
 
-	/* If on-board version is newer, "fw_version" will be updated below. */
+	fw_hdr = (struct edgeport_fw_hdr *)fw->data;
+
+	/* If on-board version is newer, "fw_version" will be updated later. */
 	serial->fw_version = (fw_hdr->major_version << 8) +
 			fw_hdr->minor_version;
 
-	/* This routine is entered by both the BOOT mode and the Download mode
+	/*
+	 * This routine is entered by both the BOOT mode and the Download mode
 	 * We can determine which code is running by the reading the config
 	 * descriptor and if we have only one bulk pipe it is in boot mode
 	 */
@@ -1017,12 +1042,13 @@ static int download_fw(struct edgeport_serial *serial,
 
 	status = choose_config(serial->serial->dev);
 	if (status)
-		return status;
+		goto out;
 
 	interface = &serial->serial->interface->cur_altsetting->desc;
 	if (!interface) {
 		dev_err(dev, "%s - no interface set, error!\n", __func__);
-		return -ENODEV;
+		status = -ENODEV;
+		goto out;
 	}
 
 	/*
@@ -1030,190 +1056,219 @@ static int download_fw(struct edgeport_serial *serial,
 	 * if we have more than one endpoint we are definitely in download
 	 * mode
 	 */
-	if (interface->bNumEndpoints > 1)
+	if (interface->bNumEndpoints > 1) {
 		serial->product_info.TiMode = TI_MODE_DOWNLOAD;
-	else
+		status = do_download_mode(serial, fw);
+	} else {
 		/* Otherwise we will remain in configuring mode */
 		serial->product_info.TiMode = TI_MODE_CONFIGURING;
+		status = do_boot_mode(serial, fw);
+	}
 
-	/********************************************************************/
-	/* Download Mode */
-	/********************************************************************/
-	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {
-		struct ti_i2c_desc *rom_desc;
+out:
+	release_firmware(fw);
+	return status;
+}
 
-		dev_dbg(dev, "%s - RUNNING IN DOWNLOAD MODE\n", __func__);
+static int do_download_mode(struct edgeport_serial *serial,
+		const struct firmware *fw)
+{
+	struct device *dev = &serial->serial->interface->dev;
+	int status = 0;
+	int start_address;
+	struct edge_ti_manuf_descriptor *ti_manuf_desc;
+	int download_cur_ver;
+	int download_new_ver;
+	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
+	struct ti_i2c_desc *rom_desc;
 
-		status = check_i2c_image(serial);
-		if (status) {
-			dev_dbg(dev, "%s - DOWNLOAD MODE -- BAD I2C\n", __func__);
-			return status;
-		}
+	dev_dbg(dev, "%s - RUNNING IN DOWNLOAD MODE\n", __func__);
 
-		/* Validate Hardware version number
-		 * Read Manufacturing Descriptor from TI Based Edgeport
-		 */
-		ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
-		if (!ti_manuf_desc)
+	status = check_i2c_image(serial);
+	if (status) {
+		dev_dbg(dev, "%s - DOWNLOAD MODE -- BAD I2C\n", __func__);
+		return status;
+	}
+
+	/*
+	 * Validate Hardware version number
+	 * Read Manufacturing Descriptor from TI Based Edgeport
+	 */
+	ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
+	if (!ti_manuf_desc)
+		return -ENOMEM;
+
+	status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
+	if (status) {
+		kfree(ti_manuf_desc);
+		return status;
+	}
+
+	/* Check version number of ION descriptor */
+	if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
+		dev_dbg(dev, "%s - Wrong CPU Rev %d (Must be 2)\n",
+			__func__, ti_cpu_rev(ti_manuf_desc));
+		kfree(ti_manuf_desc);
+		return -EINVAL;
+	}
+
+	rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
+	if (!rom_desc) {
+		kfree(ti_manuf_desc);
+		return -ENOMEM;
+	}
+
+	/* Search for type 2 record (firmware record) */
+	start_address = get_descriptor_addr(serial,
+			I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
+	if (start_address != 0) {
+		struct ti_i2c_firmware_rec *firmware_version;
+		u8 *record;
+
+		dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n",
+				__func__);
+
+		firmware_version = kmalloc(sizeof(*firmware_version),
+							GFP_KERNEL);
+		if (!firmware_version) {
+			kfree(rom_desc);
+			kfree(ti_manuf_desc);
 			return -ENOMEM;
+		}
 
-		status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
+		/*
+		 * Validate version number
+		 * Read the descriptor data
+		 */
+		status = read_rom(serial, start_address +
+				sizeof(struct ti_i2c_desc),
+				sizeof(struct ti_i2c_firmware_rec),
+				(__u8 *)firmware_version);
 		if (status) {
+			kfree(firmware_version);
+			kfree(rom_desc);
 			kfree(ti_manuf_desc);
 			return status;
 		}
 
-		/* Check version number of ION descriptor */
-		if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
-			dev_dbg(dev, "%s - Wrong CPU Rev %d (Must be 2)\n",
-				__func__, ti_cpu_rev(ti_manuf_desc));
-			kfree(ti_manuf_desc);
-			return -EINVAL;
-  		}
+		/*
+		 * Check version number of download with current
+		 * version in I2c
+		 */
+		download_cur_ver = (firmware_version->Ver_Major << 8) +
+				   (firmware_version->Ver_Minor);
+		download_new_ver = (fw_hdr->major_version << 8) +
+				   (fw_hdr->minor_version);
 
-		rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
-		if (!rom_desc) {
-			kfree(ti_manuf_desc);
-			return -ENOMEM;
-		}
+		dev_dbg(dev, "%s - >> FW Versions Device %d.%d  Driver %d.%d\n",
+			__func__, firmware_version->Ver_Major,
+			firmware_version->Ver_Minor,
+			fw_hdr->major_version, fw_hdr->minor_version);
 
-		/* Search for type 2 record (firmware record) */
-		start_address = get_descriptor_addr(serial,
-				I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
-		if (start_address != 0) {
-			struct ti_i2c_firmware_rec *firmware_version;
-			u8 *record;
-
-			dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n", __func__);
+		/*
+		 * Check if we have an old version in the I2C and
+		 * update if necessary
+		 */
+		if (download_cur_ver < download_new_ver) {
+			dev_dbg(dev, "%s - Update I2C dld from %d.%d to %d.%d\n",
+				__func__,
+				firmware_version->Ver_Major,
+				firmware_version->Ver_Minor,
+				fw_hdr->major_version,
+				fw_hdr->minor_version);
 
-			firmware_version = kmalloc(sizeof(*firmware_version),
-								GFP_KERNEL);
-			if (!firmware_version) {
+			record = kmalloc(1, GFP_KERNEL);
+			if (!record) {
+				kfree(firmware_version);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
 				return -ENOMEM;
 			}
+			/*
+			 * In order to update the I2C firmware we must
+			 * change the type 2 record to type 0xF2. This
+			 * will force the UMP to come up in Boot Mode.
+			 * Then while in boot mode, the driver will
+			 * download the latest firmware (padded to
+			 * 15.5k) into the UMP ram. Finally when the
+			 * device comes back up in download mode the
+			 * driver will cause the new firmware to be
+			 * copied from the UMP Ram to I2C and the
+			 * firmware will update the record type from
+			 * 0xf2 to 0x02.
+			 */
+			*record = I2C_DESC_TYPE_FIRMWARE_BLANK;
 
-			/* Validate version number
-			 * Read the descriptor data
+			/*
+			 * Change the I2C Firmware record type to
+			 * 0xf2 to trigger an update
 			 */
-			status = read_rom(serial, start_address +
-					sizeof(struct ti_i2c_desc),
-					sizeof(struct ti_i2c_firmware_rec),
-					(__u8 *)firmware_version);
+			status = write_rom(serial, start_address,
+					sizeof(*record), record);
 			if (status) {
+				kfree(record);
 				kfree(firmware_version);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
 				return status;
 			}
 
-			/* Check version number of download with current
-			   version in I2c */
-			download_cur_ver = (firmware_version->Ver_Major << 8) +
-					   (firmware_version->Ver_Minor);
-			download_new_ver = (fw_hdr->major_version << 8) +
-					   (fw_hdr->minor_version);
-
-			dev_dbg(dev, "%s - >> FW Versions Device %d.%d  Driver %d.%d\n",
-				__func__, firmware_version->Ver_Major,
-				firmware_version->Ver_Minor,
-				fw_hdr->major_version, fw_hdr->minor_version);
+			/*
+			 * verify the write -- must do this in order
+			 * for write to complete before we do the
+			 * hardware reset
+			 */
+			status = read_rom(serial,
+						start_address,
+						sizeof(*record),
+						record);
+			if (status) {
+				kfree(record);
+				kfree(firmware_version);
+				kfree(rom_desc);
+				kfree(ti_manuf_desc);
+				return status;
+			}
 
-			/* Check if we have an old version in the I2C and
-			   update if necessary */
-			if (download_cur_ver < download_new_ver) {
-				dev_dbg(dev, "%s - Update I2C dld from %d.%d to %d.%d\n",
-					__func__,
-					firmware_version->Ver_Major,
-					firmware_version->Ver_Minor,
-					fw_hdr->major_version,
-					fw_hdr->minor_version);
-
-				record = kmalloc(1, GFP_KERNEL);
-				if (!record) {
-					kfree(firmware_version);
-					kfree(rom_desc);
-					kfree(ti_manuf_desc);
-					return -ENOMEM;
-				}
-				/* In order to update the I2C firmware we must
-				 * change the type 2 record to type 0xF2. This
-				 * will force the UMP to come up in Boot Mode.
-				 * Then while in boot mode, the driver will
-				 * download the latest firmware (padded to
-				 * 15.5k) into the UMP ram. Finally when the
-				 * device comes back up in download mode the
-				 * driver will cause the new firmware to be
-				 * copied from the UMP Ram to I2C and the
-				 * firmware will update the record type from
-				 * 0xf2 to 0x02.
-				 */
-				*record = I2C_DESC_TYPE_FIRMWARE_BLANK;
-
-				/* Change the I2C Firmware record type to
-				   0xf2 to trigger an update */
-				status = write_rom(serial, start_address,
-						sizeof(*record), record);
-				if (status) {
-					kfree(record);
-					kfree(firmware_version);
-					kfree(rom_desc);
-					kfree(ti_manuf_desc);
-					return status;
-				}
-
-				/* verify the write -- must do this in order
-				 * for write to complete before we do the
-				 * hardware reset
-				 */
-				status = read_rom(serial,
-							start_address,
-							sizeof(*record),
-							record);
-				if (status) {
-					kfree(record);
-					kfree(firmware_version);
-					kfree(rom_desc);
-					kfree(ti_manuf_desc);
-					return status;
-				}
-
-				if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
-					dev_err(dev, "%s - error resetting device\n", __func__);
-					kfree(record);
-					kfree(firmware_version);
-					kfree(rom_desc);
-					kfree(ti_manuf_desc);
-					return -ENODEV;
-				}
-
-				dev_dbg(dev, "%s - HARDWARE RESET\n", __func__);
-
-				/* Reset UMP -- Back to BOOT MODE */
-				status = ti_vsend_sync(serial->serial->dev,
-						UMPC_HARDWARE_RESET,
-						0, 0, NULL, 0,
-						TI_VSEND_TIMEOUT_DEFAULT);
-
-				dev_dbg(dev, "%s - HARDWARE RESET return %d\n", __func__, status);
-
-				/* return an error on purpose. */
+			if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
+				dev_err(dev, "%s - error resetting device\n",
+						__func__);
 				kfree(record);
 				kfree(firmware_version);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
 				return -ENODEV;
-			} else {
-				/* Same or newer fw version is already loaded */
-				serial->fw_version = download_cur_ver;
 			}
+
+			dev_dbg(dev, "%s - HARDWARE RESET\n", __func__);
+
+			/* Reset UMP -- Back to BOOT MODE */
+			status = ti_vsend_sync(serial->serial->dev,
+					UMPC_HARDWARE_RESET,
+					0, 0, NULL, 0,
+					TI_VSEND_TIMEOUT_DEFAULT);
+
+			dev_dbg(dev, "%s - HARDWARE RESET return %d\n",
+					__func__, status);
+
+			/* return an error on purpose. */
+			kfree(record);
 			kfree(firmware_version);
+			kfree(rom_desc);
+			kfree(ti_manuf_desc);
+			return -ENODEV;
 		}
-		/* Search for type 0xF2 record (firmware blank record) */
-		else if ((start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) {
+		/* Same or newer fw version is already loaded */
+		serial->fw_version = download_cur_ver;
+		kfree(firmware_version);
+	}
+	/* Search for type 0xF2 record (firmware blank record) */
+	else {
+		start_address = get_descriptor_addr(serial,
+				I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc);
+		if (start_address != 0) {
 #define HEADER_SIZE	(sizeof(struct ti_i2c_desc) + \
-					sizeof(struct ti_i2c_firmware_rec))
+				sizeof(struct ti_i2c_firmware_rec))
 			__u8 *header;
 			__u8 *vheader;
 
@@ -1232,7 +1287,8 @@ static int download_fw(struct edgeport_serial *serial,
 				return -ENOMEM;
 			}
 
-			dev_dbg(dev, "%s - Found Type BLANK FIRMWARE (Type F2) record\n", __func__);
+			dev_dbg(dev, "%s - Found Type BLANK FIRMWARE (Type F2) record\n",
+					__func__);
 
 			/*
 			 * In order to update the I2C firmware we must change
@@ -1245,7 +1301,7 @@ static int download_fw(struct edgeport_serial *serial,
 			 * UMP Ram to I2C and the firmware will update the
 			 * record type from 0xf2 to 0x02.
 			 */
-			status = build_i2c_fw_hdr(header, dev, fw);
+			status = build_i2c_fw_hdr(header, fw);
 			if (status) {
 				kfree(vheader);
 				kfree(header);
@@ -1254,8 +1310,10 @@ static int download_fw(struct edgeport_serial *serial,
 				return -EINVAL;
 			}
 
-			/* Update I2C with type 0xf2 record with correct
-			   size and checksum */
+			/*
+			 * Update I2C with type 0xf2 record with correct
+			 * size and checksum
+			 */
 			status = write_rom(serial,
 						start_address,
 						HEADER_SIZE,
@@ -1268,13 +1326,16 @@ static int download_fw(struct edgeport_serial *serial,
 				return -EINVAL;
 			}
 
-			/* verify the write -- must do this in order for
-			   write to complete before we do the hardware reset */
+			/*
+			 * verify the write -- must do this in order for
+			 * write to complete before we do the hardware reset
+			 */
 			status = read_rom(serial, start_address,
 							HEADER_SIZE, vheader);
 
 			if (status) {
-				dev_dbg(dev, "%s - can't read header back\n", __func__);
+				dev_dbg(dev, "%s - can't read header back\n",
+						__func__);
 				kfree(vheader);
 				kfree(header);
 				kfree(rom_desc);
@@ -1282,7 +1343,8 @@ static int download_fw(struct edgeport_serial *serial,
 				return status;
 			}
 			if (memcmp(vheader, header, HEADER_SIZE)) {
-				dev_dbg(dev, "%s - write download record failed\n", __func__);
+				dev_dbg(dev, "%s - write download record failed\n",
+						__func__);
 				kfree(vheader);
 				kfree(header);
 				kfree(rom_desc);
@@ -1301,26 +1363,33 @@ static int download_fw(struct edgeport_serial *serial,
 					0, 0, NULL, 0,
 					TI_VSEND_TIMEOUT_FW_DOWNLOAD);
 
-		  	dev_dbg(dev, "%s - Update complete 0x%x\n", __func__, status);
+			dev_dbg(dev, "%s - Update complete 0x%x\n", __func__,
+					status);
 			if (status) {
 				dev_err(dev,
 					"%s - UMPC_COPY_DNLD_TO_I2C failed\n",
-								__func__);
+					__func__);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
 				return status;
 			}
 		}
-
-		// The device is running the download code
-		kfree(rom_desc);
-		kfree(ti_manuf_desc);
-		return 0;
 	}
 
-	/********************************************************************/
-	/* Boot Mode */
-	/********************************************************************/
+	/* The device is running the download code */
+	kfree(rom_desc);
+	kfree(ti_manuf_desc);
+	return 0;
+}
+
+static int do_boot_mode(struct edgeport_serial *serial,
+		const struct firmware *fw)
+{
+	struct device *dev = &serial->serial->interface->dev;
+	int status = 0;
+	struct edge_ti_manuf_descriptor *ti_manuf_desc;
+	struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
+
 	dev_dbg(dev, "%s - RUNNING IN BOOT MODE\n", __func__);
 
 	/* Configure the TI device so we can use the BULK pipes for download */
@@ -1336,8 +1405,10 @@ static int download_fw(struct edgeport_serial *serial,
 		goto stayinbootmode;
 	}
 
-	/* We have an ION device (I2c Must be programmed)
-	   Determine I2C image type */
+	/*
+	 * We have an ION device (I2c Must be programmed)
+	 * Determine I2C image type
+	 */
 	if (i2c_type_bootmode(serial))
 		goto stayinbootmode;
 
@@ -1349,7 +1420,8 @@ static int download_fw(struct edgeport_serial *serial,
 		__u8 *buffer;
 		int buffer_size;
 
-		/* Validate Hardware version number
+		/*
+		 * Validate Hardware version number
 		 * Read Manufacturing Descriptor from TI Based Edgeport
 		 */
 		ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
@@ -1439,7 +1511,6 @@ static int download_fw(struct edgeport_serial *serial,
 	return 0;
 }
 
-
 static int ti_do_config(struct edgeport_port *port, int feature, int on)
 {
 	int port_number = port->port->port_number;
@@ -1450,7 +1521,6 @@ static int ti_do_config(struct edgeport_port *port, int feature, int on)
 			on, NULL, 0);
 }
 
-
 static int restore_mcr(struct edgeport_port *port, __u8 mcr)
 {
 	int status = 0;
@@ -1556,7 +1626,6 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
 		icount->frame++;
 }
 
-
 static void edge_interrupt_callback(struct urb *urb)
 {
 	struct edgeport_serial *edge_serial = urb->context;
@@ -1616,8 +1685,9 @@ static void edge_interrupt_callback(struct urb *urb)
 	case TIUMP_INTERRUPT_CODE_LSR:
 		lsr = map_line_status(data[1]);
 		if (lsr & UMP_UART_LSR_DATA_MASK) {
-			/* Save the LSR event for bulk read
-			   completion routine */
+			/*
+			 * Save the LSR event for bulk read completion routine
+			 */
 			dev_dbg(dev, "%s - LSR Event Port %u LSR Status = %02x\n",
 				__func__, port_number, lsr);
 			edge_port->lsr_event = 1;
@@ -1925,8 +1995,10 @@ static void edge_close(struct usb_serial_port *port)
 	if (edge_serial == NULL || edge_port == NULL)
 		return;
 
-	/* The bulkreadcompletion routine will check
-	 * this flag and dump add read data */
+	/*
+	 * The bulkreadcompletion routine will check
+	 * this flag and dump add read data
+	 */
 	edge_port->close_pending = 1;
 
 	usb_kill_urb(port->read_urb);
@@ -2016,8 +2088,10 @@ static void edge_send(struct usb_serial_port *port, struct tty_struct *tty)
 	} else
 		edge_port->port->icount.tx += count;
 
-	/* wakeup any process waiting for writes to complete */
-	/* there is now more room in the buffer for new writes */
+	/*
+	 * wakeup any process waiting for writes to complete
+	 * there is now more room in the buffer for new writes
+	 */
 	if (tty)
 		tty_wakeup(tty);
 }
@@ -2089,8 +2163,10 @@ static void edge_throttle(struct tty_struct *tty)
 		}
 	}
 
-	/* if we are implementing RTS/CTS, stop reads */
-	/* and the Edgeport will clear the RTS line */
+	/*
+	 * if we are implementing RTS/CTS, stop reads
+	 * and the Edgeport will clear the RTS line
+	 */
 	if (C_CRTSCTS(tty))
 		stop_read(edge_port);
 
@@ -2113,8 +2189,10 @@ static void edge_unthrottle(struct tty_struct *tty)
 			dev_err(&port->dev, "%s - failed to write start character, %d\n", __func__, status);
 		}
 	}
-	/* if we are implementing RTS/CTS, restart reads */
-	/* are the Edgeport will assert the RTS line */
+	/*
+	 * if we are implementing RTS/CTS, restart reads
+	 * are the Edgeport will assert the RTS line
+	 */
 	if (C_CRTSCTS(tty)) {
 		status = restart_read(edge_port);
 		if (status)
@@ -2236,8 +2314,10 @@ static void change_port_settings(struct tty_struct *tty,
 		restart_read(edge_port);
 	}
 
-	/* if we are implementing XON/XOFF, set the start and stop
-	   character in the device */
+	/*
+	 * if we are implementing XON/XOFF, set the start and stop
+	 * character in the device
+	 */
 	config->cXon  = START_CHAR(tty);
 	config->cXoff = STOP_CHAR(tty);
 
@@ -2467,9 +2547,6 @@ static int edge_startup(struct usb_serial *serial)
 {
 	struct edgeport_serial *edge_serial;
 	int status;
-	const struct firmware *fw;
-	const char *fw_name = "edgeport/down3.bin";
-	struct device *dev = &serial->interface->dev;
 	u16 product_id;
 
 	/* create our private serial structure */
@@ -2481,16 +2558,7 @@ static int edge_startup(struct usb_serial *serial)
 	edge_serial->serial = serial;
 	usb_set_serial_data(serial, edge_serial);
 
-	status = request_firmware(&fw, fw_name, dev);
-	if (status) {
-		dev_err(dev, "Failed to load image \"%s\" err %d\n",
-				fw_name, status);
-		kfree(edge_serial);
-		return status;
-	}
-
-	status = download_fw(edge_serial, fw);
-	release_firmware(fw);
+	status = download_fw(edge_serial);
 	if (status) {
 		kfree(edge_serial);
 		return status;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 6956c4f6221614a79a09429c6b9f541dc54baa5e..685fef71d3d14e28ce125983b3508ae73ed6579c 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -48,7 +48,6 @@ static int  option_probe(struct usb_serial *serial,
 			const struct usb_device_id *id);
 static int option_attach(struct usb_serial *serial);
 static void option_release(struct usb_serial *serial);
-static int option_send_setup(struct usb_serial_port *port);
 static void option_instat_callback(struct urb *urb);
 
 /* Vendor and product IDs */
@@ -234,8 +233,6 @@ static void option_instat_callback(struct urb *urb);
 
 #define QUALCOMM_VENDOR_ID			0x05C6
 
-#define SIERRA_VENDOR_ID			0x1199
-
 #define CMOTECH_VENDOR_ID			0x16d8
 #define CMOTECH_PRODUCT_6001			0x6001
 #define CMOTECH_PRODUCT_CMU_300			0x6002
@@ -611,11 +608,6 @@ static const struct option_blacklist_info telit_le920_blacklist = {
 	.reserved = BIT(1) | BIT(5),
 };
 
-static const struct option_blacklist_info sierra_mc73xx_blacklist = {
-	.sendsetup = BIT(0) | BIT(2),
-	.reserved = BIT(8) | BIT(10) | BIT(11),
-};
-
 static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -1113,10 +1105,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
-	{ USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x68c0, 0xff),
-	  .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */
-	{ USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x9041, 0xff),
-	  .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC7305/MC7355 */
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
@@ -1835,10 +1823,6 @@ static struct usb_serial_driver * const serial_drivers[] = {
 	&option_1port_device, NULL
 };
 
-struct option_private {
-	u8 bInterfaceNumber;
-};
-
 module_usb_serial_driver(serial_drivers, option_ids);
 
 static int option_probe(struct usb_serial *serial,
@@ -1882,29 +1866,19 @@ static int option_attach(struct usb_serial *serial)
 	struct usb_interface_descriptor *iface_desc;
 	const struct option_blacklist_info *blacklist;
 	struct usb_wwan_intf_private *data;
-	struct option_private *priv;
 
 	data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		kfree(data);
-		return -ENOMEM;
-	}
-
 	/* Retrieve blacklist info stored at probe. */
 	blacklist = usb_get_serial_data(serial);
 
 	iface_desc = &serial->interface->cur_altsetting->desc;
 
-	priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
-	data->private = priv;
-
 	if (!blacklist || !test_bit(iface_desc->bInterfaceNumber,
 						&blacklist->sendsetup)) {
-		data->send_setup = option_send_setup;
+		data->use_send_setup = 1;
 	}
 	spin_lock_init(&data->susp_lock);
 
@@ -1916,9 +1890,7 @@ static int option_attach(struct usb_serial *serial)
 static void option_release(struct usb_serial *serial)
 {
 	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
-	struct option_private *priv = intfdata->private;
 
-	kfree(priv);
 	kfree(intfdata);
 }
 
@@ -1977,40 +1949,6 @@ static void option_instat_callback(struct urb *urb)
 	}
 }
 
-/** send RTS/DTR state to the port.
- *
- * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
- * CDC.
-*/
-static int option_send_setup(struct usb_serial_port *port)
-{
-	struct usb_serial *serial = port->serial;
-	struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
-	struct option_private *priv = intfdata->private;
-	struct usb_wwan_port_private *portdata;
-	int val = 0;
-	int res;
-
-	portdata = usb_get_serial_port_data(port);
-
-	if (portdata->dtr_state)
-		val |= 0x01;
-	if (portdata->rts_state)
-		val |= 0x02;
-
-	res = usb_autopm_get_interface(serial->interface);
-	if (res)
-		return res;
-
-	res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-				0x22, 0x21, val, priv->bInterfaceNumber, NULL,
-				0, USB_CTRL_SET_TIMEOUT);
-
-	usb_autopm_put_interface(serial->interface);
-
-	return res;
-}
-
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index ebcec8cda85840d4d336f92b2558747f6efb2843..5022fcfa02605a604f6998ef7dcbf0d3f0b2b590 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -143,9 +143,11 @@ static const struct usb_device_id id_table[] = {
 	{DEVICE_SWI(0x0f3d, 0x68a2)},	/* Sierra Wireless MC7700 */
 	{DEVICE_SWI(0x114f, 0x68a2)},	/* Sierra Wireless MC7750 */
 	{DEVICE_SWI(0x1199, 0x68a2)},	/* Sierra Wireless MC7710 */
+	{DEVICE_SWI(0x1199, 0x68c0)},	/* Sierra Wireless MC7304/MC7354 */
 	{DEVICE_SWI(0x1199, 0x901c)},	/* Sierra Wireless EM7700 */
 	{DEVICE_SWI(0x1199, 0x901f)},	/* Sierra Wireless EM7355 */
 	{DEVICE_SWI(0x1199, 0x9040)},	/* Sierra Wireless Modem */
+	{DEVICE_SWI(0x1199, 0x9041)},	/* Sierra Wireless MC7305/MC7355 */
 	{DEVICE_SWI(0x1199, 0x9051)},	/* Netgear AirCard 340U */
 	{DEVICE_SWI(0x1199, 0x9053)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9054)},	/* Sierra Wireless Modem */
@@ -153,6 +155,8 @@ static const struct usb_device_id id_table[] = {
 	{DEVICE_SWI(0x1199, 0x9056)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9060)},	/* Sierra Wireless Modem */
 	{DEVICE_SWI(0x1199, 0x9061)},	/* Sierra Wireless Modem */
+	{DEVICE_SWI(0x1199, 0x9070)},	/* Sierra Wireless MC74xx/EM74xx */
+	{DEVICE_SWI(0x1199, 0x9071)},	/* Sierra Wireless MC74xx/EM74xx */
 	{DEVICE_SWI(0x413c, 0x81a2)},	/* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a3)},	/* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
 	{DEVICE_SWI(0x413c, 0x81a4)},	/* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
@@ -175,6 +179,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 	__u8 nintf;
 	__u8 ifnum;
 	int altsetting = -1;
+	bool sendsetup = false;
 
 	nintf = serial->dev->actconfig->desc.bNumInterfaces;
 	dev_dbg(dev, "Num Interfaces = %d\n", nintf);
@@ -286,6 +291,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 			break;
 		case 3:
 			dev_dbg(dev, "Modem port found\n");
+			sendsetup = true;
 			break;
 		default:
 			/* don't claim any unsupported interface */
@@ -337,17 +343,25 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 		}
 	}
 
+	if (!retval)
+		usb_set_serial_data(serial, (void *)(unsigned long)sendsetup);
+
 	return retval;
 }
 
 static int qc_attach(struct usb_serial *serial)
 {
 	struct usb_wwan_intf_private *data;
+	bool sendsetup;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
+	sendsetup = !!(unsigned long)(usb_get_serial_data(serial));
+	if (sendsetup)
+		data->use_send_setup = 1;
+
 	spin_lock_init(&data->susp_lock);
 
 	usb_set_serial_data(serial, data);
@@ -374,6 +388,7 @@ static struct usb_serial_driver qcdevice = {
 	.probe               = qcprobe,
 	.open		     = usb_wwan_open,
 	.close		     = usb_wwan_close,
+	.dtr_rts	     = usb_wwan_dtr_rts,
 	.write		     = usb_wwan_write,
 	.write_room	     = usb_wwan_write_room,
 	.chars_in_buffer     = usb_wwan_chars_in_buffer,
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index f22dff58b587a4c1da3fae281069dfb8bd6759df..44b25c08c68a15aa7db54056621576313a6bff48 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -34,9 +34,9 @@ extern int usb_wwan_resume(struct usb_serial *serial);
 struct usb_wwan_intf_private {
 	spinlock_t susp_lock;
 	unsigned int suspended:1;
+	unsigned int use_send_setup:1;
 	int in_flight;
 	unsigned int open_ports;
-	int (*send_setup) (struct usb_serial_port *port);
 	void *private;
 };
 
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 825305cb71d9dda11ce5a429feaed075a959a508..be9cb61b4d1987659828e32a7d461f8c92a09847 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -36,6 +36,40 @@
 #include <linux/serial.h>
 #include "usb-wwan.h"
 
+/*
+ * Generate DTR/RTS signals on the port using the SET_CONTROL_LINE_STATE request
+ * in CDC ACM.
+ */
+static int usb_wwan_send_setup(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct usb_wwan_port_private *portdata;
+	int val = 0;
+	int ifnum;
+	int res;
+
+	portdata = usb_get_serial_port_data(port);
+
+	if (portdata->dtr_state)
+		val |= 0x01;
+	if (portdata->rts_state)
+		val |= 0x02;
+
+	ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
+
+	res = usb_autopm_get_interface(serial->interface);
+	if (res)
+		return res;
+
+	res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				0x22, 0x21, val, ifnum, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
+
+	usb_autopm_put_interface(port->serial->interface);
+
+	return res;
+}
+
 void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
 {
 	struct usb_wwan_port_private *portdata;
@@ -43,7 +77,7 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
 
 	intfdata = usb_get_serial_data(port->serial);
 
-	if (!intfdata->send_setup)
+	if (!intfdata->use_send_setup)
 		return;
 
 	portdata = usb_get_serial_port_data(port);
@@ -51,7 +85,7 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
 	portdata->rts_state = on;
 	portdata->dtr_state = on;
 
-	intfdata->send_setup(port);
+	usb_wwan_send_setup(port);
 }
 EXPORT_SYMBOL(usb_wwan_dtr_rts);
 
@@ -84,7 +118,7 @@ int usb_wwan_tiocmset(struct tty_struct *tty,
 	portdata = usb_get_serial_port_data(port);
 	intfdata = usb_get_serial_data(port->serial);
 
-	if (!intfdata->send_setup)
+	if (!intfdata->use_send_setup)
 		return -EINVAL;
 
 	/* FIXME: what locks portdata fields ? */
@@ -97,7 +131,7 @@ int usb_wwan_tiocmset(struct tty_struct *tty,
 		portdata->rts_state = 0;
 	if (clear & TIOCM_DTR)
 		portdata->dtr_state = 0;
-	return intfdata->send_setup(port);
+	return usb_wwan_send_setup(port);
 }
 EXPORT_SYMBOL(usb_wwan_tiocmset);
 
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 1bac215202d20b0783890b28d9dbef886a5af35b..39afd7045c43d3148ee746f428a89a99cb7ad458 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1456,30 +1456,26 @@ static void isd200_free_info_ptrs(void *info_)
  */
 static int isd200_init_info(struct us_data *us)
 {
-	int retStatus = ISD200_GOOD;
 	struct isd200_info *info;
 
 	info = kzalloc(sizeof(struct isd200_info), GFP_KERNEL);
 	if (!info)
-		retStatus = ISD200_ERROR;
-	else {
-		info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
-		info->RegsBuf = kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
-		info->srb.sense_buffer =
-				kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
-		if (!info->id || !info->RegsBuf || !info->srb.sense_buffer) {
-			isd200_free_info_ptrs(info);
-			kfree(info);
-			retStatus = ISD200_ERROR;
-		}
-	}
+		return ISD200_ERROR;
 
-	if (retStatus == ISD200_GOOD) {
-		us->extra = info;
-		us->extra_destructor = isd200_free_info_ptrs;
+	info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
+	info->RegsBuf = kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
+	info->srb.sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+
+	if (!info->id || !info->RegsBuf || !info->srb.sense_buffer) {
+		isd200_free_info_ptrs(info);
+		kfree(info);
+		return ISD200_ERROR;
 	}
 
-	return retStatus;
+	us->extra = info;
+	us->extra_destructor = isd200_free_info_ptrs;
+
+	return ISD200_GOOD;
 }
 
 /**************************************************************************
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index f689219095526a76076010eee2d1e3df82fa8e73..48ca9c204354168f079a1e9e5ceaf2ac4b74a0f5 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -257,17 +257,16 @@ static void uas_stat_cmplt(struct urb *urb)
 	struct uas_cmd_info *cmdinfo;
 	unsigned long flags;
 	unsigned int idx;
+	int status = urb->status;
 
 	spin_lock_irqsave(&devinfo->lock, flags);
 
 	if (devinfo->resetting)
 		goto out;
 
-	if (urb->status) {
-		if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
-			dev_err(&urb->dev->dev, "stat urb: status %d\n",
-				urb->status);
-		}
+	if (status) {
+		if (status != -ENOENT && status != -ECONNRESET && status != -ESHUTDOWN)
+			dev_err(&urb->dev->dev, "stat urb: status %d\n", status);
 		goto out;
 	}
 
@@ -348,6 +347,7 @@ static void uas_data_cmplt(struct urb *urb)
 	struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
 	struct scsi_data_buffer *sdb = NULL;
 	unsigned long flags;
+	int status = urb->status;
 
 	spin_lock_irqsave(&devinfo->lock, flags);
 
@@ -374,9 +374,9 @@ static void uas_data_cmplt(struct urb *urb)
 		goto out;
 	}
 
-	if (urb->status) {
-		if (urb->status != -ENOENT && urb->status != -ECONNRESET)
-			uas_log_cmd_state(cmnd, "data cmplt err", urb->status);
+	if (status) {
+		if (status != -ENOENT && status != -ECONNRESET && status != -ESHUTDOWN)
+			uas_log_cmd_state(cmnd, "data cmplt err", status);
 		/* error: no data transfered */
 		sdb->resid = sdb->length;
 	} else {
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index e9ef1eccdace88f1c4f9adb93d8ab566eb759de6..7fbe19d5279e5c11159f141fdd20b6a3ac7ff568 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -218,7 +218,7 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
 	memset(desc, 0, sizeof(*desc));
 	desc->bDescriptorType = USB_DT_HUB;
 	desc->bDescLength = 9;
-	desc->wHubCharacteristics = __constant_cpu_to_le16(
+	desc->wHubCharacteristics = cpu_to_le16(
 		HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM);
 	desc->bNbrPorts = VHCI_NPORTS;
 	desc->u.hs.DeviceRemovable[0] = 0xff;
@@ -565,7 +565,9 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 	usb_hcd_unlink_urb_from_ep(hcd, urb);
 no_need_unlink:
 	spin_unlock(&the_controller->lock);
-	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
+	if (!ret)
+		usb_hcd_giveback_urb(vhci_to_hcd(the_controller),
+				     urb, urb->status);
 	return ret;
 }
 
@@ -629,7 +631,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 		/* URB was never linked! or will be soon given back by
 		 * vhci_rx. */
 		spin_unlock(&the_controller->lock);
-		return 0;
+		return -EIDRM;
 	}
 
 	{
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 8fc1b787dceddd333b6c98cb99a4ea95fa81ec08..38d0504a1bbc50a29a3d639a772648ef385e5692 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -642,9 +642,7 @@ static void uwb_drp_handle_alien_drp(struct uwb_rc *rc, struct uwb_ie_drp *drp_i
 	}
 
 	INIT_LIST_HEAD(&cnflt->rc_node);
-	init_timer(&cnflt->timer);
-	cnflt->timer.function = uwb_cnflt_timer;
-	cnflt->timer.data     = (unsigned long)cnflt;
+	setup_timer(&cnflt->timer, uwb_cnflt_timer, (unsigned long)cnflt);
 
 	cnflt->rc = rc;
 	INIT_WORK(&cnflt->cnflt_update_work, uwb_cnflt_update_work);
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c
index 8cb71bb333c2ea830881ddc8bf19afd4096b3d60..36b5cb62c15dba7b734ffa61460fdeb3a31e79cc 100644
--- a/drivers/uwb/neh.c
+++ b/drivers/uwb/neh.c
@@ -223,9 +223,7 @@ struct uwb_rc_neh *uwb_rc_neh_add(struct uwb_rc *rc, struct uwb_rccb *cmd,
 
 	kref_init(&neh->kref);
 	INIT_LIST_HEAD(&neh->list_node);
-	init_timer(&neh->timer);
-	neh->timer.function = uwb_rc_neh_timer;
-	neh->timer.data     = (unsigned long)neh;
+	setup_timer(&neh->timer, uwb_rc_neh_timer, (unsigned long)neh);
 
 	neh->rc = rc;
 	neh->evt_type = expected_type;
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c
index 536ad42b0a4b1d7ed0091e4e943a19abf9d0980d..f5e27247a38feac0a0294a57fa49ad0a260be637 100644
--- a/drivers/uwb/rsv.c
+++ b/drivers/uwb/rsv.c
@@ -470,9 +470,7 @@ static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc)
 	INIT_LIST_HEAD(&rsv->rc_node);
 	INIT_LIST_HEAD(&rsv->pal_node);
 	kref_init(&rsv->kref);
-	init_timer(&rsv->timer);
-	rsv->timer.function = uwb_rsv_timer;
-	rsv->timer.data     = (unsigned long)rsv;
+	setup_timer(&rsv->timer, uwb_rsv_timer, (unsigned long)rsv);
 
 	rsv->rc = rc;
 	INIT_WORK(&rsv->handle_timeout_work, uwb_rsv_handle_timeout_work);
@@ -989,9 +987,8 @@ void uwb_rsv_init(struct uwb_rc *rc)
 	rc->bow.can_reserve_extra_mases = true;
 	rc->bow.total_expired = 0;
 	rc->bow.window = UWB_DRP_BACKOFF_WIN_MIN >> 1;
-	init_timer(&rc->bow.timer);
-	rc->bow.timer.function = uwb_rsv_backoff_win_timer;
-	rc->bow.timer.data     = (unsigned long)&rc->bow;
+	setup_timer(&rc->bow.timer, uwb_rsv_backoff_win_timer,
+			(unsigned long)&rc->bow);
 
 	bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS);
 }
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index c121ddf74f7ff403696ecfe9521b84ab71bb4b0c..bdc0ee8e84e938d702cb6ed16e3b6e54b424d7a2 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -25,15 +25,6 @@
  */
 #define ATMEL_MAX_UART	7
 
- /* USB Device */
-struct at91_udc_data {
-	int	vbus_pin;		/* high == host powering us */
-	u8	vbus_active_low;	/* vbus polarity */
-	u8	vbus_polled;		/* Use polling, not interrupt */
-	int	pullup_pin;		/* active == D+ pulled up */
-	u8	pullup_active_low;	/* true == pullup_pin is active low */
-};
-
  /* Compact Flash */
 struct at91_cf_data {
 	int	irq_pin;		/* I/O IRQ */
diff --git a/include/linux/platform_data/s3c-hsotg.h b/include/linux/platform_data/s3c-hsotg.h
index 3f1cbf95ec3ba9cd98849ae92e846cb14a19e90f..3982586ba6df43f6cf294834c3599bce2b352070 100644
--- a/include/linux/platform_data/s3c-hsotg.h
+++ b/include/linux/platform_data/s3c-hsotg.h
@@ -17,19 +17,19 @@
 
 struct platform_device;
 
-enum s3c_hsotg_dmamode {
+enum dwc2_hsotg_dmamode {
 	S3C_HSOTG_DMA_NONE,	/* do not use DMA at-all */
 	S3C_HSOTG_DMA_ONLY,	/* always use DMA */
 	S3C_HSOTG_DMA_DRV,	/* DMA is chosen by driver */
 };
 
 /**
- * struct s3c_hsotg_plat - platform data for high-speed otg/udc
+ * struct dwc2_hsotg_plat - platform data for high-speed otg/udc
  * @dma: Whether to use DMA or not.
  * @is_osc: The clock source is an oscillator, not a crystal
  */
-struct s3c_hsotg_plat {
-	enum s3c_hsotg_dmamode	dma;
+struct dwc2_hsotg_plat {
+	enum dwc2_hsotg_dmamode	dma;
 	unsigned int		is_osc:1;
 	int                     phy_type;
 
@@ -37,6 +37,6 @@ struct s3c_hsotg_plat {
 	int (*phy_exit)(struct platform_device *pdev, int type);
 };
 
-extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd);
+extern void dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd);
 
 #endif /* __LINUX_USB_S3C_HSOTG_H */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 447fe29b55b451148c452b82cb0043d510a26eae..b9a28074210f218e05383099b8c043d4ca9fff93 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -122,6 +122,8 @@ enum usb_interface_condition {
  *	has been deferred.
  * @needs_binding: flag set when the driver should be re-probed or unbound
  *	following a reset or suspend operation it doesn't support.
+ * @authorized: This allows to (de)authorize individual interfaces instead
+ *	a whole device in contrast to the device authorization.
  * @dev: driver model's view of this device
  * @usb_dev: if an interface is bound to the USB major, this will point
  *	to the sysfs representation for that device.
@@ -178,6 +180,7 @@ struct usb_interface {
 	unsigned needs_altsetting0:1;	/* switch to altsetting 0 is pending */
 	unsigned needs_binding:1;	/* needs delayed unbind/rebind */
 	unsigned resetting_device:1;	/* true: bandwidth alloc after reset */
+	unsigned authorized:1;		/* used for interface authorization */
 
 	struct device dev;		/* interface specific device info */
 	struct device *usb_dev;
@@ -325,6 +328,7 @@ struct usb_host_bos {
 	/* wireless cap descriptor is handled by wusb */
 	struct usb_ext_cap_descriptor	*ext_cap;
 	struct usb_ss_cap_descriptor	*ss_cap;
+	struct usb_ssp_cap_descriptor	*ssp_cap;
 	struct usb_ss_container_id_descriptor	*ss_id;
 };
 
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 27603bcbb9b99dccd86f9ac7f720e13fde4c8bd0..6cc96bb12ddcf4f02fae841b801b3a9870ca5c2a 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -32,9 +32,9 @@
 #ifndef __LINUX_USB_CH9_H
 #define __LINUX_USB_CH9_H
 
+#include <linux/device.h>
 #include <uapi/linux/usb/ch9.h>
 
-
 /**
  * usb_speed_string() - Returns human readable-name of the speed.
  * @speed: The speed to return human-readable name for.  If it's not
@@ -43,6 +43,15 @@
  */
 extern const char *usb_speed_string(enum usb_device_speed speed);
 
+/**
+ * usb_get_maximum_speed - Get maximum requested speed for a given USB
+ * controller.
+ * @dev: Pointer to the given USB controller device
+ *
+ * The function gets the maximum speed string from property "maximum-speed",
+ * and returns the corresponding enum usb_device_speed.
+ */
+extern enum usb_device_speed usb_get_maximum_speed(struct device *dev);
 
 /**
  * usb_state_string - Returns human readable name for the state.
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index a41833cd184c64dbc99a02731b508ade382e2538..5dd75fa47dd823fbfd2c58ae19d65bb27ee120e1 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -5,9 +5,28 @@
 #ifndef __LINUX_USB_CHIPIDEA_H
 #define __LINUX_USB_CHIPIDEA_H
 
+#include <linux/extcon.h>
 #include <linux/usb/otg.h>
 
 struct ci_hdrc;
+
+/**
+ * struct ci_hdrc_cable - structure for external connector cable state tracking
+ * @state: current state of the line
+ * @changed: set to true when extcon event happen
+ * @edev: device which generate events
+ * @ci: driver state of the chipidea device
+ * @nb: hold event notification callback
+ * @conn: used for notification registration
+ */
+struct ci_hdrc_cable {
+	bool				state;
+	bool				changed;
+	struct extcon_dev		*edev;
+	struct ci_hdrc			*ci;
+	struct notifier_block		nb;
+};
+
 struct ci_hdrc_platform_data {
 	const char	*name;
 	/* offset of the capability registers */
@@ -48,6 +67,11 @@ struct ci_hdrc_platform_data {
 	u32			ahb_burst_config;
 	u32			tx_burst_size;
 	u32			rx_burst_size;
+
+	/* VBUS and ID signal state tracking, using extcon framework */
+	struct ci_hdrc_cable		vbus_extcon;
+	struct ci_hdrc_cable		id_extcon;
+	u32			phy_clkgate_delay_us;
 };
 
 /* Default offset of capability registers */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index c14a69b36d27b14afc1da26ab616797e7daaaf8d..3d583a10b9269bd7a0f77c0eca1b1b037e11392d 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -215,6 +215,7 @@ struct usb_ep {
 	struct list_head	ep_list;
 	struct usb_ep_caps	caps;
 	bool			claimed;
+	bool			enabled;
 	unsigned		maxpacket:16;
 	unsigned		maxpacket_limit:16;
 	unsigned		max_streams:16;
@@ -264,7 +265,18 @@ static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
  */
 static inline int usb_ep_enable(struct usb_ep *ep)
 {
-	return ep->ops->enable(ep, ep->desc);
+	int ret;
+
+	if (ep->enabled)
+		return 0;
+
+	ret = ep->ops->enable(ep, ep->desc);
+	if (ret)
+		return ret;
+
+	ep->enabled = true;
+
+	return 0;
 }
 
 /**
@@ -281,7 +293,18 @@ static inline int usb_ep_enable(struct usb_ep *ep)
  */
 static inline int usb_ep_disable(struct usb_ep *ep)
 {
-	return ep->ops->disable(ep);
+	int ret;
+
+	if (!ep->enabled)
+		return 0;
+
+	ret = ep->ops->disable(ep);
+	if (ret)
+		return ret;
+
+	ep->enabled = false;
+
+	return 0;
 }
 
 /**
@@ -1233,6 +1256,8 @@ extern struct usb_ep *usb_ep_autoconfig_ss(struct usb_gadget *,
 			struct usb_endpoint_descriptor *,
 			struct usb_ss_ep_comp_descriptor *);
 
+extern void usb_ep_autoconfig_release(struct usb_ep *);
+
 extern void usb_ep_autoconfig_reset(struct usb_gadget *);
 
 #endif /* __LINUX_USB_GADGET_H */
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index d2784c10bfe2ce23dfcd64d773dbe3beaeb34c22..f89c24bd53a4cc071db1d1fc8c585f8a07cc696b 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -58,12 +58,6 @@
  *
  * Since "struct usb_bus" is so thin, you can't share much code in it.
  * This framework is a layer over that, and should be more sharable.
- *
- * @authorized_default: Specifies if new devices are authorized to
- *                      connect by default or they require explicit
- *                      user space authorization; this bit is settable
- *                      through /sys/class/usb_host/X/authorized_default.
- *                      For the rest is RO, so we don't lock to r/w it.
  */
 
 /*-------------------------------------------------------------------------*/
@@ -120,6 +114,8 @@ struct usb_hcd {
 #define HCD_FLAG_WAKEUP_PENDING		4	/* root hub is resuming? */
 #define HCD_FLAG_RH_RUNNING		5	/* root hub is running? */
 #define HCD_FLAG_DEAD			6	/* controller has died? */
+#define HCD_FLAG_INTF_AUTHORIZED	7	/* authorize interfaces? */
+#define HCD_FLAG_DEV_AUTHORIZED		8	/* authorize devices? */
 
 	/* The flags can be tested using these macros; they are likely to
 	 * be slightly faster than test_bit().
@@ -131,6 +127,22 @@ struct usb_hcd {
 #define HCD_RH_RUNNING(hcd)	((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING))
 #define HCD_DEAD(hcd)		((hcd)->flags & (1U << HCD_FLAG_DEAD))
 
+	/*
+	 * Specifies if interfaces are authorized by default
+	 * or they require explicit user space authorization; this bit is
+	 * settable through /sys/class/usb_host/X/interface_authorized_default
+	 */
+#define HCD_INTF_AUTHORIZED(hcd) \
+	((hcd)->flags & (1U << HCD_FLAG_INTF_AUTHORIZED))
+
+	/*
+	 * Specifies if devices are authorized by default
+	 * or they require explicit user space authorization; this bit is
+	 * settable through /sys/class/usb_host/X/authorized_default
+	 */
+#define HCD_DEV_AUTHORIZED(hcd) \
+	((hcd)->flags & (1U << HCD_FLAG_DEV_AUTHORIZED))
+
 	/* Flags that get set only during HCD registration or removal. */
 	unsigned		rh_registered:1;/* is root hub registered? */
 	unsigned		rh_pollable:1;	/* may we poll the root hub? */
@@ -141,7 +153,6 @@ struct usb_hcd {
 	 * support the new root-hub polling mechanism. */
 	unsigned		uses_new_polling:1;
 	unsigned		wireless:1;	/* Wireless USB HCD */
-	unsigned		authorized_default:1;
 	unsigned		has_tt:1;	/* Integrated TT in root hub */
 	unsigned		amd_resume_bug:1; /* AMD remote wakeup quirk */
 	unsigned		can_do_streams:1; /* HC supports streams */
@@ -239,6 +250,7 @@ struct hc_driver {
 #define	HCD_USB2	0x0020		/* USB 2.0 */
 #define	HCD_USB25	0x0030		/* Wireless USB 1.0 (USB 2.5)*/
 #define	HCD_USB3	0x0040		/* USB 3.0 */
+#define	HCD_USB31	0x0050		/* USB 3.1 */
 #define	HCD_MASK	0x0070
 #define	HCD_BH		0x0100		/* URB complete in BH context */
 
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index a4ee1b582183119557ccc2b59b3d188ad173d8e6..fa6dc132bd1b9b298ee2503871e245a4aa37de94 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -95,7 +95,7 @@ struct musb_hdrc_config {
 	/* musb CLKIN in Blackfin in MHZ */
 	unsigned char   clkin;
 #endif
-
+	u32		maximum_speed;
 };
 
 struct musb_hdrc_platform_data {
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index 8c5a818ec2447aca31ce542e1cbb087f7b6fb04e..c3fe9e48ce27cb251e069247e0dec09b9848a09d 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -12,22 +12,10 @@
 #include <linux/usb/phy.h>
 
 #if IS_ENABLED(CONFIG_OF)
-enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np);
-enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np);
 bool of_usb_host_tpl_support(struct device_node *np);
 int of_usb_update_otg_caps(struct device_node *np,
 			struct usb_otg_caps *otg_caps);
 #else
-static inline enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
-{
-	return USB_DR_MODE_UNKNOWN;
-}
-
-static inline enum usb_device_speed
-of_usb_get_maximum_speed(struct device_node *np)
-{
-	return USB_SPEED_UNKNOWN;
-}
 static inline bool of_usb_host_tpl_support(struct device_node *np)
 {
 	return false;
diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
index bd1dcf8161009d78153082c23e7890a57f1b6b4f..67929df86df5df44ffb3db4fd89ad0a317a6c3cd 100644
--- a/include/linux/usb/otg.h
+++ b/include/linux/usb/otg.h
@@ -119,4 +119,13 @@ enum usb_dr_mode {
 	USB_DR_MODE_OTG,
 };
 
+/**
+ * usb_get_dr_mode - Get dual role mode for given device
+ * @dev: Pointer to the given device
+ *
+ * The function gets phy interface string from property 'dr_mode',
+ * and returns the correspondig enum usb_dr_mode
+ */
+extern enum usb_dr_mode usb_get_dr_mode(struct device *dev);
+
 #endif /* __LINUX_USB_OTG_H */
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index e39f251cf861e08483a411493fd5030d2bf319dc..31a8068c42a56aded5bbdf0d779eebc5b9d628c2 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -63,7 +63,7 @@ enum usb_otg_state {
 struct usb_phy;
 struct usb_otg;
 
-/* for transceivers connected thru an ULPI interface, the user must
+/* for phys connected thru an ULPI interface, the user must
  * provide access ops
  */
 struct usb_phy_io_ops {
@@ -92,10 +92,10 @@ struct usb_phy {
 	u16			port_status;
 	u16			port_change;
 
-	/* to support controllers that have multiple transceivers */
+	/* to support controllers that have multiple phys */
 	struct list_head	head;
 
-	/* initialize/shutdown the OTG controller */
+	/* initialize/shutdown the phy */
 	int	(*init)(struct usb_phy *x);
 	void	(*shutdown)(struct usb_phy *x);
 
@@ -106,7 +106,7 @@ struct usb_phy {
 	int	(*set_power)(struct usb_phy *x,
 				unsigned mA);
 
-	/* Set transceiver into suspend mode */
+	/* Set phy into suspend mode */
 	int	(*set_suspend)(struct usb_phy *x,
 				int suspend);
 
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index f7adc6e01f9ea4544363d6f1bfa446854c813dec..4338eb7b09b3ad705f766fa1c3e1f8a100ae049e 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -866,6 +866,35 @@ struct usb_ss_container_id_descriptor {
 } __attribute__((packed));
 
 #define USB_DT_USB_SS_CONTN_ID_SIZE	20
+
+/*
+ * SuperSpeed Plus USB Capability descriptor: Defines the set of
+ * SuperSpeed Plus USB specific device level capabilities
+ */
+#define	USB_SSP_CAP_TYPE	0xa
+struct usb_ssp_cap_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+	__u8  bReserved;
+	__le32 bmAttributes;
+#define USB_SSP_SUBLINK_SPEED_ATTRIBS	(0x1f << 0) /* sublink speed entries */
+#define USB_SSP_SUBLINK_SPEED_IDS	(0xf << 5)  /* speed ID entries */
+	__u16  wFunctionalitySupport;
+#define USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID	(0xf)
+#define USB_SSP_MIN_RX_LANE_COUNT		(0xf << 8)
+#define USB_SSP_MIN_TX_LANE_COUNT		(0xf << 12)
+	__le16 wReserved;
+	__le32 bmSublinkSpeedAttr[1]; /* list of sublink speed attrib entries */
+#define USB_SSP_SUBLINK_SPEED_SSID	(0xf)		/* sublink speed ID */
+#define USB_SSP_SUBLINK_SPEED_LSE	(0x3 << 4)	/* Lanespeed exponent */
+#define USB_SSP_SUBLINK_SPEED_ST	(0x3 << 6)	/* Sublink type */
+#define USB_SSP_SUBLINK_SPEED_RSVD	(0x3f << 8)	/* Reserved */
+#define USB_SSP_SUBLINK_SPEED_LP	(0x3 << 14)	/* Link protocol */
+#define USB_SSP_SUBLINK_SPEED_LSM	(0xff << 16)	/* Lanespeed mantissa */
+} __attribute__((packed));
+
+
 /*-------------------------------------------------------------------------*/
 
 /* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with
diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c
index 879f9870a6bcb0c9df42ce683e1ab99041b6e932..0692d99b6d8f3076fc073e5fc8dee05b40e6740b 100644
--- a/tools/usb/testusb.c
+++ b/tools/usb/testusb.c
@@ -394,7 +394,7 @@ int main (int argc, char **argv)
 	 *      low speed, interrupt    8 *  1     =     8
 	 */
 	param.iterations = 1000;
-	param.length = 512;
+	param.length = 1024;
 	param.vary = 512;
 	param.sglen = 32;
 
@@ -454,10 +454,10 @@ int main (int argc, char **argv)
 			"\t-t testnum	only run specified case\n"
 			"\t-n		no test running, show devices to be tested\n"
 			"Case arguments:\n"
-			"\t-c iterations	default 1000\n"
-			"\t-s packetsize	default 512\n"
-			"\t-g sglen	default 32\n"
-			"\t-v vary		default 512\n",
+			"\t-c iterations		default 1000\n"
+			"\t-s transfer length	default 1024\n"
+			"\t-g sglen		default 32\n"
+			"\t-v vary			default 512\n",
 			argv[0]);
 		return 1;
 	}
diff --git a/tools/usb/usbip/src/usbip_detach.c b/tools/usb/usbip/src/usbip_detach.c
index 05c6d15856eb649d1b1e46e685988ebb1accdb46..9db9d21bb2ecee75c89c027ccb07cfdeb21062de 100644
--- a/tools/usb/usbip/src/usbip_detach.c
+++ b/tools/usb/usbip/src/usbip_detach.c
@@ -47,7 +47,9 @@ static int detach_port(char *port)
 	uint8_t portnum;
 	char path[PATH_MAX+1];
 
-	for (unsigned int i = 0; i < strlen(port); i++)
+	unsigned int port_len = strlen(port);
+
+	for (unsigned int i = 0; i < port_len; i++)
 		if (!isdigit(port[i])) {
 			err("invalid port %s", port);
 			return -1;