summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-platform-usbip-vudc35
-rw-r--r--Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt21
-rw-r--r--Documentation/devicetree/bindings/phy/brcm-sata-phy.txt (renamed from Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt)15
-rw-r--r--Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt4
-rw-r--r--Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt8
-rw-r--r--Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt12
-rw-r--r--Documentation/devicetree/bindings/phy/samsung-phy.txt18
-rw-r--r--Documentation/devicetree/bindings/usb/dwc3.txt6
-rw-r--r--Documentation/devicetree/bindings/usb/qcom,dwc3.txt1
-rw-r--r--Documentation/usb/chipidea.txt13
-rw-r--r--drivers/phy/Kconfig33
-rw-r--r--drivers/phy/Makefile3
-rw-r--r--drivers/phy/phy-bcm-ns-usb2.c137
-rw-r--r--drivers/phy/phy-brcm-sata.c412
-rw-r--r--drivers/phy/phy-brcmstb-sata.c250
-rw-r--r--drivers/phy/phy-exynos-mipi-video.c321
-rw-r--r--drivers/phy/phy-mt65xx-usb3.c77
-rw-r--r--drivers/phy/phy-rcar-gen2.c1
-rw-r--r--drivers/phy/phy-rcar-gen3-usb2.c88
-rw-r--r--drivers/phy/phy-rockchip-usb.c2
-rw-r--r--drivers/usb/Kconfig3
-rw-r--r--drivers/usb/atm/ueagle-atm.c10
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c4
-rw-r--r--drivers/usb/common/usb-otg-fsm.c10
-rw-r--r--drivers/usb/core/buffer.c3
-rw-r--r--drivers/usb/core/devio.c11
-rw-r--r--drivers/usb/core/driver.c40
-rw-r--r--drivers/usb/core/hcd.c16
-rw-r--r--drivers/usb/core/hub.c10
-rw-r--r--drivers/usb/core/message.c48
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--drivers/usb/dwc2/gadget.c8
-rw-r--r--drivers/usb/dwc2/hcd.c1
-rw-r--r--drivers/usb/dwc2/hcd.h1
-rw-r--r--drivers/usb/dwc2/hcd_queue.c3
-rw-r--r--drivers/usb/dwc2/platform.c2
-rw-r--r--drivers/usb/dwc3/core.c118
-rw-r--r--drivers/usb/dwc3/core.h84
-rw-r--r--drivers/usb/dwc3/debug.h6
-rw-r--r--drivers/usb/dwc3/debugfs.c358
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c9
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c18
-rw-r--r--drivers/usb/dwc3/ep0.c43
-rw-r--r--drivers/usb/dwc3/gadget.c427
-rw-r--r--drivers/usb/dwc3/gadget.h6
-rw-r--r--drivers/usb/dwc3/platform_data.h2
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/composite.c22
-rw-r--r--drivers/usb/gadget/function/f_fs.c2
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c36
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.h2
-rw-r--r--drivers/usb/gadget/legacy/acm_ms.c4
-rw-r--r--drivers/usb/gadget/legacy/mass_storage.c4
-rw-r--r--drivers/usb/gadget/legacy/multi.c12
-rw-r--r--drivers/usb/gadget/legacy/nokia.c7
-rw-r--r--drivers/usb/gadget/udc/at91_udc.c5
-rw-r--r--drivers/usb/gadget/udc/pch_udc.c175
-rw-r--r--drivers/usb/gadget/udc/r8a66597-udc.c2
-rw-r--r--drivers/usb/gadget/udc/udc-core.c26
-rw-r--r--drivers/usb/host/Kconfig3
-rw-r--r--drivers/usb/host/bcma-hcd.c6
-rw-r--r--drivers/usb/host/ehci-dbg.c86
-rw-r--r--drivers/usb/host/ehci-exynos.c2
-rw-r--r--drivers/usb/host/ehci-msm.c2
-rw-r--r--drivers/usb/host/ehci-omap.c2
-rw-r--r--drivers/usb/host/ehci-spear.c2
-rw-r--r--drivers/usb/host/fhci-sched.c2
-rw-r--r--drivers/usb/host/fotg210-hcd.c8
-rw-r--r--drivers/usb/host/whci/hcd.c7
-rw-r--r--drivers/usb/host/whci/qset.c8
-rw-r--r--drivers/usb/host/xhci-mvebu.c7
-rw-r--r--drivers/usb/host/xhci-mvebu.h7
-rw-r--r--drivers/usb/host/xhci-plat.c60
-rw-r--r--drivers/usb/host/xhci-plat.h20
-rw-r--r--drivers/usb/host/xhci-rcar.c34
-rw-r--r--drivers/usb/host/xhci-ring.c478
-rw-r--r--drivers/usb/host/xhci.c41
-rw-r--r--drivers/usb/host/xhci.h14
-rw-r--r--drivers/usb/isp1760/isp1760-if.c2
-rw-r--r--drivers/usb/misc/Kconfig26
-rw-r--r--drivers/usb/misc/Makefile1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c4
-rw-r--r--drivers/usb/misc/ucsi.c478
-rw-r--r--drivers/usb/misc/ucsi.h215
-rw-r--r--drivers/usb/misc/usbtest.c7
-rw-r--r--drivers/usb/phy/phy-qcom-8x16-usb.c5
-rw-r--r--drivers/usb/phy/phy-twl6030-usb.c10
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c16
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c9
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c3
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c30
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h6
-rw-r--r--drivers/usb/serial/cp210x.c102
-rw-r--r--drivers/usb/serial/ftdi_sio.c16
-rw-r--r--drivers/usb/serial/io_edgeport.c56
-rw-r--r--drivers/usb/serial/keyspan.c72
-rw-r--r--drivers/usb/serial/mxuport.c10
-rw-r--r--drivers/usb/serial/option.c155
-rw-r--r--drivers/usb/serial/quatech2.c1
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c55
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h8
-rw-r--r--drivers/usb/serial/usb-serial.c5
-rw-r--r--drivers/usb/storage/alauda.c22
-rw-r--r--drivers/usb/storage/cypress_atacb.c34
-rw-r--r--drivers/usb/storage/datafab.c22
-rw-r--r--drivers/usb/storage/debug.c3
-rw-r--r--drivers/usb/storage/debug.h3
-rw-r--r--drivers/usb/storage/ene_ub6250.c25
-rw-r--r--drivers/usb/storage/freecom.c75
-rw-r--r--drivers/usb/storage/initializers.c15
-rw-r--r--drivers/usb/storage/initializers.h15
-rw-r--r--drivers/usb/storage/isd200.c51
-rw-r--r--drivers/usb/storage/jumpshot.c22
-rw-r--r--drivers/usb/storage/karma.c3
-rw-r--r--drivers/usb/storage/option_ms.c6
-rw-r--r--drivers/usb/storage/protocol.c12
-rw-r--r--drivers/usb/storage/protocol.h3
-rw-r--r--drivers/usb/storage/realtek_cr.c12
-rw-r--r--drivers/usb/storage/scsiglue.c169
-rw-r--r--drivers/usb/storage/scsiglue.h3
-rw-r--r--drivers/usb/storage/sddr09.c82
-rw-r--r--drivers/usb/storage/sddr55.c45
-rw-r--r--drivers/usb/storage/shuttle_usbat.c16
-rw-r--r--drivers/usb/storage/sierra_ms.c3
-rw-r--r--drivers/usb/storage/transport.c165
-rw-r--r--drivers/usb/storage/transport.h3
-rw-r--r--drivers/usb/storage/uas.c3
-rw-r--r--drivers/usb/storage/unusual_alauda.h3
-rw-r--r--drivers/usb/storage/unusual_cypress.h3
-rw-r--r--drivers/usb/storage/unusual_datafab.h6
-rw-r--r--drivers/usb/storage/unusual_devs.h334
-rw-r--r--drivers/usb/storage/unusual_freecom.h3
-rw-r--r--drivers/usb/storage/unusual_isd200.h3
-rw-r--r--drivers/usb/storage/unusual_jumpshot.h3
-rw-r--r--drivers/usb/storage/unusual_karma.h3
-rw-r--r--drivers/usb/storage/unusual_onetouch.h6
-rw-r--r--drivers/usb/storage/unusual_realtek.h3
-rw-r--r--drivers/usb/storage/unusual_sddr09.h3
-rw-r--r--drivers/usb/storage/unusual_sddr55.h3
-rw-r--r--drivers/usb/storage/unusual_uas.h3
-rw-r--r--drivers/usb/storage/unusual_usbat.h3
-rw-r--r--drivers/usb/storage/usb.c98
-rw-r--r--drivers/usb/storage/usb.h14
-rw-r--r--drivers/usb/storage/usual-tables.c3
-rw-r--r--drivers/usb/usbip/Kconfig17
-rw-r--r--drivers/usb/usbip/Makefile3
-rw-r--r--drivers/usb/usbip/stub.h1
-rw-r--r--drivers/usb/usbip/stub_dev.c7
-rw-r--r--drivers/usb/usbip/stub_rx.c19
-rw-r--r--drivers/usb/usbip/stub_tx.c11
-rw-r--r--drivers/usb/usbip/usbip_common.c17
-rw-r--r--drivers/usb/usbip/usbip_common.h14
-rw-r--r--drivers/usb/usbip/usbip_event.c168
-rw-r--r--drivers/usb/usbip/vudc.h190
-rw-r--r--drivers/usb/usbip/vudc_dev.c661
-rw-r--r--drivers/usb/usbip/vudc_main.c113
-rw-r--r--drivers/usb/usbip/vudc_rx.c234
-rw-r--r--drivers/usb/usbip/vudc_sysfs.c229
-rw-r--r--drivers/usb/usbip/vudc_transfer.c506
-rw-r--r--drivers/usb/usbip/vudc_tx.c289
-rw-r--r--drivers/usb/wusbcore/crypto.c6
-rw-r--r--drivers/usb/wusbcore/devconnect.c1
-rw-r--r--include/linux/bcma/bcma.h1
-rw-r--r--include/linux/bcma/bcma_driver_arm_c9.h15
-rw-r--r--include/linux/mfd/syscon/exynos5-pmu.h3
-rw-r--r--include/linux/usb.h11
-rw-r--r--include/linux/usb/gadget.h4
-rw-r--r--include/linux/usb/hcd.h1
-rw-r--r--include/linux/usb/otg-fsm.h91
-rw-r--r--include/uapi/linux/usb/ch9.h121
-rw-r--r--tools/usb/usbip/libsrc/Makefile.am4
-rw-r--r--tools/usb/usbip/libsrc/usbip_common.h3
-rw-r--r--tools/usb/usbip/libsrc/usbip_device_driver.c163
-rw-r--r--tools/usb/usbip/libsrc/usbip_device_driver.h34
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_common.c273
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_common.h104
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_driver.c269
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_driver.h27
-rw-r--r--tools/usb/usbip/src/usbip_attach.c10
-rw-r--r--tools/usb/usbip/src/usbip_list.c96
-rw-r--r--tools/usb/usbip/src/usbip_port.c13
-rw-r--r--tools/usb/usbip/src/usbipd.c42
182 files changed, 7630 insertions, 2525 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-usbip-vudc b/Documentation/ABI/testing/sysfs-platform-usbip-vudc
new file mode 100644
index 000000000000..81fcfb454913
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-usbip-vudc
@@ -0,0 +1,35 @@
+What:		/sys/devices/platform/usbip-vudc.%d/dev_desc
+Date:		April 2016
+KernelVersion:	4.6
+Contact:	Krzysztof Opasiak <k.opasiak@samsung.com>
+Description:
+		This file allows to read device descriptor of
+		gadget driver which is currently bound to this
+		controller. It is possible to read this file
+		only if gadget driver is bound, otherwise error
+		is returned.
+
+What:		/sys/devices/platform/usbip-vudc.%d/usbip_status
+Date:		April 2016
+KernelVersion:	4.6
+Contact:	Krzysztof Opasiak <k.opasiak@samsung.com>
+Description:
+		Current status of the device.
+		Allowed values:
+		1 - Device is available and can be exported
+		2 - Device is currently exported
+		3 - Fatal error occurred during communication
+		  with peer
+
+What:		/sys/devices/platform/usbip-vudc.%d/usbip_sockfd
+Date:		April 2016
+KernelVersion:	4.6
+Contact:	Krzysztof Opasiak <k.opasiak@samsung.com>
+Description:
+		This file allows to export usb device to
+		connection peer. It is done by writing to this
+		file socket fd (as a string for example "8")
+		associated with a connection to remote peer who
+		would like to use this device. It is possible to
+		close the connection by writing -1 instead of
+		socked fd.
diff --git a/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt
new file mode 100644
index 000000000000..a7aee9ea8926
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/bcm-ns-usb2-phy.txt
@@ -0,0 +1,21 @@
+Driver for Broadcom Northstar USB 2.0 PHY
+
+Required properties:
+- compatible: brcm,ns-usb2-phy
+- reg: iomem address range of DMU (Device Management Unit)
+- reg-names: "dmu", the only needed & supported reg right now
+- clocks: USB PHY reference clock
+- clock-names: "phy-ref-clk", the only needed & supported clock right now
+
+To initialize USB 2.0 PHY driver needs to setup PLL correctly. To do this it
+requires passing phandle to the USB PHY reference clock.
+
+Example:
+	usb2-phy {
+		compatible = "brcm,ns-usb2-phy";
+		reg = <0x1800c000 0x1000>;
+		reg-names = "dmu";
+		#phy-cells = <0>;
+		clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
+		clock-names = "phy-ref-clk";
+	};
diff --git a/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt
index d87ab7c127b8..d0231209d846 100644
--- a/Documentation/devicetree/bindings/phy/brcm,brcmstb-sata-phy.txt
+++ b/Documentation/devicetree/bindings/phy/brcm-sata-phy.txt
@@ -1,14 +1,17 @@
-* Broadcom SATA3 PHY for STB
+* Broadcom SATA3 PHY
 
 Required properties:
 - compatible: should be one or more of
      "brcm,bcm7425-sata-phy"
      "brcm,bcm7445-sata-phy"
+     "brcm,iproc-ns2-sata-phy"
      "brcm,phy-sata3"
 - address-cells: should be 1
 - size-cells: should be 0
-- reg: register range for the PHY PCB interface
-- reg-names: should be "phy"
+- reg: register ranges for the PHY PCB interface
+- reg-names: should be "phy" and "phy-ctrl"
+     The "phy-ctrl" registers are only required for
+     "brcm,iproc-ns2-sata-phy".
 
 Sub-nodes:
   Each port's PHY should be represented as a sub-node.
@@ -16,12 +19,12 @@ Sub-nodes:
 Sub-nodes required properties:
 - reg: the PHY number
 - phy-cells: generic PHY binding; must be 0
-Optional:
-- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port
 
+Sub-nodes optional properties:
+- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port
+     This property is not applicable for "brcm,iproc-ns2-sata-phy".
 
 Example:
-
 	sata-phy@f0458100 {
 		compatible = "brcm,bcm7445-sata-phy", "brcm,phy-sata3";
 		reg = <0xf0458100 0x1e00>, <0xf045804c 0x10>;
diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
index 00100cf3e037..33a2b1ee3f3e 100644
--- a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
+++ b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
@@ -4,7 +4,9 @@ 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"
+ - compatible	: should be one of
+		  "mediatek,mt2701-u3phy"
+		  "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
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt b/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt
index d564ba4f1cf6..91da947ae9b6 100644
--- a/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt
+++ b/Documentation/devicetree/bindings/phy/rcar-gen2-phy.txt
@@ -7,6 +7,12 @@ Required properties:
 - compatible: "renesas,usb-phy-r8a7790" if the device is a part of R8A7790 SoC.
 	      "renesas,usb-phy-r8a7791" if the device is a part of R8A7791 SoC.
 	      "renesas,usb-phy-r8a7794" if the device is a part of R8A7794 SoC.
+	      "renesas,rcar-gen2-usb-phy" for a generic R-Car Gen2 compatible device.
+
+	      When compatible with the generic version, nodes must list the
+	      SoC-specific version corresponding to the platform first
+	      followed by the generic version.
+
 - reg: offset and length of the register block.
 - #address-cells: number of address cells for the USB channel subnodes, must
 		  be <1>.
@@ -34,7 +40,7 @@ the USB channel; see the selector meanings below:
 Example (Lager board):
 
 	usb-phy@e6590100 {
-		compatible = "renesas,usb-phy-r8a7790";
+		compatible = "renesas,usb-phy-r8a7790", "renesas,rcar-gen2-usb-phy";
 		reg = <0 0xe6590100 0 0x100>;
 		#address-cells = <1>;
 		#size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
index eaf7e9b7ce6b..2281d6cdecb1 100644
--- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
+++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt
@@ -6,6 +6,12 @@ This file provides information on what the device node for the R-Car generation
 Required properties:
 - compatible: "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795
 	      SoC.
+	      "renesas,rcar-gen3-usb2-phy" for a generic R-Car Gen3 compatible device.
+
+	      When compatible with the generic version, nodes must list the
+	      SoC-specific version corresponding to the platform first
+	      followed by the generic version.
+
 - reg: offset and length of the partial USB 2.0 Host register block.
 - clocks: clock phandle and specifier pair(s).
 - #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
@@ -15,18 +21,20 @@ To use a USB channel where USB 2.0 Host and HSUSB (USB 2.0 Peripheral) are
 combined, the device tree node should set interrupt properties to use the
 channel as USB OTG:
 - interrupts: interrupt specifier for the PHY.
+- vbus-supply: Phandle to a regulator that provides power to the VBUS. This
+	       regulator will be managed during the PHY power on/off sequence.
 
 Example (R-Car H3):
 
 	usb-phy@ee080200 {
-		compatible = "renesas,usb2-phy-r8a7795";
+		compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy";
 		reg = <0 0xee080200 0 0x700>;
 		interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>;
 	};
 
 	usb-phy@ee0a0200 {
-		compatible = "renesas,usb2-phy-r8a7795";
+		compatible = "renesas,usb2-phy-r8a7795", "renesas,rcar-gen3-usb2-phy";
 		reg = <0 0xee0a0200 0 0x700>;
 		clocks = <&mstp7_clks R8A7795_CLK_EHCI0>;
 	};
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 0289d3b07853..9872ba8546bd 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -2,9 +2,20 @@ Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY
 -------------------------------------------------
 
 Required properties:
-- compatible : should be "samsung,s5pv210-mipi-video-phy";
+- compatible : should be one of the listed compatibles:
+	- "samsung,s5pv210-mipi-video-phy"
+	- "samsung,exynos5420-mipi-video-phy"
+	- "samsung,exynos5433-mipi-video-phy"
 - #phy-cells : from the generic phy bindings, must be 1;
-- syscon - phandle to the PMU system controller;
+
+In case of s5pv210 and exynos5420 compatible PHYs:
+- syscon - phandle to the PMU system controller
+
+In case of exynos5433 compatible PHY:
+ - samsung,pmu-syscon - phandle to the PMU system controller
+ - samsung,disp-sysreg - phandle to the DISP system registers controller
+ - samsung,cam0-sysreg - phandle to the CAM0 system registers controller
+ - samsung,cam1-sysreg - phandle to the CAM1 system registers controller
 
 For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
 the PHY specifier identifies the PHY and its meaning is as follows:
@@ -12,6 +23,9 @@ the PHY specifier identifies the PHY and its meaning is as follows:
   1 - MIPI DSIM 0,
   2 - MIPI CSIS 1,
   3 - MIPI DSIM 1.
+"samsung,exynos5420-mipi-video-phy" and "samsung,exynos5433-mipi-video-phy"
+supports additional fifth PHY:
+  4 - MIPI CSIS 2.
 
 Samsung EXYNOS SoC series Display Port PHY
 -------------------------------------------------
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index fb2ad0acedbd..7d7ce089b003 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -14,7 +14,6 @@ Optional properties:
    the second element is expected to be a handle to the USB3/SS PHY
  - phys: from the *Generic PHY* bindings
  - phy-names: from the *Generic PHY* bindings
- - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
  - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable
  - snps,disable_scramble_quirk: true when SW should disable data scrambling.
 	Only really useful for FPGA builds.
@@ -38,6 +37,8 @@ Optional properties:
  - 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,dis_rxdet_inp3_quirk: when set core will disable receiver detection
+			in PHY P3 power state.
  - 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
@@ -47,6 +48,8 @@ Optional properties:
 	register for post-silicon frame length adjustment when the
 	fladj_30mhz_sdbnd signal is invalid or incorrect.
 
+ - <DEPRECATED> tx-fifo-resize: determines if the FIFO *has* to be reallocated.
+
 This is usually a subnode to DWC3 glue to which it is connected.
 
 dwc3@4a030000 {
@@ -54,5 +57,4 @@ dwc3@4a030000 {
 	reg = <0x4a030000 0xcfff>;
 	interrupts = <0 92 4>
 	usb-phy = <&usb2_phy>, <&usb3,phy>;
-	tx-fifo-resize;
 };
diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
index ca164e71dd50..39acb084bce9 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt
@@ -59,7 +59,6 @@ Example device nodes:
 				interrupts = <0 205 0x4>;
 				phys = <&hs_phy>, <&ss_phy>;
 				phy-names = "usb2-phy", "usb3-phy";
-				tx-fifo-resize;
 				dr_mode = "host";
 			};
 		};
diff --git a/Documentation/usb/chipidea.txt b/Documentation/usb/chipidea.txt
index 678741b0f213..edf7cdfddc88 100644
--- a/Documentation/usb/chipidea.txt
+++ b/Documentation/usb/chipidea.txt
@@ -3,14 +3,17 @@
 To show how to demo OTG HNP and SRP functions via sys input files
 with 2 Freescale i.MX6Q sabre SD boards.
 
-1.1 How to enable OTG FSM in menuconfig
+1.1 How to enable OTG FSM
 ---------------------------------------
-Select CONFIG_USB_OTG_FSM, rebuild kernel Image and modules.
-If you want to check some internal variables for otg fsm,
-mount debugfs, there are 2 files which can show otg fsm
-variables and some controller registers value:
+1.1.1 Select CONFIG_USB_OTG_FSM in menuconfig, rebuild kernel
+Image and modules. If you want to check some internal
+variables for otg fsm, mount debugfs, there are 2 files
+which can show otg fsm variables and some controller registers value:
 cat /sys/kernel/debug/ci_hdrc.0/otg
 cat /sys/kernel/debug/ci_hdrc.0/registers
+1.1.2 Add below entries in your dts file for your controller node
+	otg-rev = <0x0200>;
+	adp-disable;
 
 1.2 Test operations
 -------------------
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 27e5f6ee9a2a..b869b98835f4 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -15,6 +15,15 @@ config GENERIC_PHY
 	  phy users can obtain reference to the PHY. All the users of this
 	  framework should select this config.
 
+config PHY_BCM_NS_USB2
+	tristate "Broadcom Northstar USB 2.0 PHY Driver"
+	depends on ARCH_BCM_IPROC || COMPILE_TEST
+	depends on HAS_IOMEM && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support Broadcom USB 2.0 PHY connected to the USB
+	  controller on Northstar family.
+
 config PHY_BERLIN_USB
 	tristate "Marvell Berlin USB PHY Driver"
 	depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF
@@ -113,14 +122,15 @@ config PHY_MIPHY365X
 
 config PHY_RCAR_GEN2
 	tristate "Renesas R-Car generation 2 USB PHY driver"
-	depends on ARCH_SHMOBILE
+	depends on ARCH_RENESAS
 	depends on GENERIC_PHY
 	help
 	  Support for USB PHY found on Renesas R-Car generation 2 SoCs.
 
 config PHY_RCAR_GEN3_USB2
 	tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
-	depends on OF && ARCH_SHMOBILE
+	depends on ARCH_RENESAS
+	depends on EXTCON
 	select GENERIC_PHY
 	help
 	  Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
@@ -218,9 +228,8 @@ config PHY_MT65XX_USB3
 	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.
+	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver,
+	  it supports multiple usb2.0 and usb3.0 ports.
 
 config PHY_HI6220_USB
 	tristate "hi6220 USB PHY support"
@@ -250,7 +259,8 @@ config PHY_SUN9I_USB
 	tristate "Allwinner sun9i SoC USB PHY driver"
 	depends on ARCH_SUNXI && HAS_IOMEM && OF
 	depends on RESET_CONTROLLER
-	depends on USB_COMMON
+	depends on USB_SUPPORT
+	select USB_COMMON
 	select GENERIC_PHY
 	help
 	  Enable this to support the transceiver that is part of Allwinner
@@ -403,14 +413,15 @@ config PHY_TUSB1210
 	help
 	  Support for TI TUSB1210 USB ULPI PHY.
 
-config PHY_BRCMSTB_SATA
-	tristate "Broadcom STB SATA PHY driver"
-	depends on ARCH_BRCMSTB || BMIPS_GENERIC
+config PHY_BRCM_SATA
+	tristate "Broadcom SATA PHY driver"
+	depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST
 	depends on OF
 	select GENERIC_PHY
+	default ARCH_BCM_IPROC
 	help
-	  Enable this to support the SATA3 PHY on 28nm or 40nm Broadcom STB SoCs.
-	  Likely useful only with CONFIG_SATA_BRCMSTB enabled.
+	  Enable this to support the Broadcom SATA PHY.
+	  If unsure, say N.
 
 config PHY_CYGNUS_PCIE
 	tristate "Broadcom Cygnus PCIe PHY driver"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d4f06e69fd9a..9c3e73ccabc4 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
+obj-$(CONFIG_PHY_BCM_NS_USB2)		+= phy-bcm-ns-usb2.o
 obj-$(CONFIG_PHY_BERLIN_USB)		+= phy-berlin-usb.o
 obj-$(CONFIG_PHY_BERLIN_SATA)		+= phy-berlin-sata.o
 obj-$(CONFIG_PHY_DM816X_USB)		+= phy-dm816x-usb.o
@@ -49,7 +50,7 @@ obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) 	+= phy-qcom-ufs-qmp-20nm.o
 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_BRCM_SATA)		+= phy-brcm-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-ns-usb2.c b/drivers/phy/phy-bcm-ns-usb2.c
new file mode 100644
index 000000000000..95ab6b2a0de5
--- /dev/null
+++ b/drivers/phy/phy-bcm-ns-usb2.c
@@ -0,0 +1,137 @@
+/*
+ * Broadcom Northstar USB 2.0 PHY Driver
+ *
+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bcma/bcma.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct bcm_ns_usb2 {
+	struct device *dev;
+	struct clk *ref_clk;
+	struct phy *phy;
+	void __iomem *dmu;
+};
+
+static int bcm_ns_usb2_phy_init(struct phy *phy)
+{
+	struct bcm_ns_usb2 *usb2 = phy_get_drvdata(phy);
+	struct device *dev = usb2->dev;
+	void __iomem *dmu = usb2->dmu;
+	u32 ref_clk_rate, usb2ctl, usb_pll_ndiv, usb_pll_pdiv;
+	int err = 0;
+
+	err = clk_prepare_enable(usb2->ref_clk);
+	if (err < 0) {
+		dev_err(dev, "Failed to prepare ref clock: %d\n", err);
+		goto err_out;
+	}
+
+	ref_clk_rate = clk_get_rate(usb2->ref_clk);
+	if (!ref_clk_rate) {
+		dev_err(dev, "Failed to get ref clock rate\n");
+		err = -EINVAL;
+		goto err_clk_off;
+	}
+
+	usb2ctl = readl(dmu + BCMA_DMU_CRU_USB2_CONTROL);
+
+	if (usb2ctl & BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK) {
+		usb_pll_pdiv = usb2ctl;
+		usb_pll_pdiv &= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK;
+		usb_pll_pdiv >>= BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT;
+	} else {
+		usb_pll_pdiv = 1 << 3;
+	}
+
+	/* Calculate ndiv based on a solid 1920 MHz that is for USB2 PHY */
+	usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
+
+	/* Unlock DMU PLL settings with some magic value */
+	writel(0x0000ea68, dmu + BCMA_DMU_CRU_CLKSET_KEY);
+
+	/* Write USB 2.0 PLL control setting */
+	usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
+	usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
+	writel(usb2ctl, dmu + BCMA_DMU_CRU_USB2_CONTROL);
+
+	/* Lock DMU PLL settings */
+	writel(0x00000000, dmu + BCMA_DMU_CRU_CLKSET_KEY);
+
+err_clk_off:
+	clk_disable_unprepare(usb2->ref_clk);
+err_out:
+	return err;
+}
+
+static const struct phy_ops ops = {
+	.init		= bcm_ns_usb2_phy_init,
+	.owner		= THIS_MODULE,
+};
+
+static int bcm_ns_usb2_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcm_ns_usb2 *usb2;
+	struct resource *res;
+	struct phy_provider *phy_provider;
+
+	usb2 = devm_kzalloc(&pdev->dev, sizeof(*usb2), GFP_KERNEL);
+	if (!usb2)
+		return -ENOMEM;
+	usb2->dev = dev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmu");
+	usb2->dmu = devm_ioremap_resource(dev, res);
+	if (IS_ERR(usb2->dmu)) {
+		dev_err(dev, "Failed to map DMU regs\n");
+		return PTR_ERR(usb2->dmu);
+	}
+
+	usb2->ref_clk = devm_clk_get(dev, "phy-ref-clk");
+	if (IS_ERR(usb2->ref_clk)) {
+		dev_err(dev, "Clock not defined\n");
+		return PTR_ERR(usb2->ref_clk);
+	}
+
+	usb2->phy = devm_phy_create(dev, NULL, &ops);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	phy_set_drvdata(usb2->phy, usb2);
+	platform_set_drvdata(pdev, usb2);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id bcm_ns_usb2_id_table[] = {
+	{ .compatible = "brcm,ns-usb2-phy", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, bcm_ns_usb2_id_table);
+
+static struct platform_driver bcm_ns_usb2_driver = {
+	.probe		= bcm_ns_usb2_probe,
+	.driver = {
+		.name = "bcm_ns_usb2",
+		.of_match_table = bcm_ns_usb2_id_table,
+	},
+};
+module_platform_driver(bcm_ns_usb2_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/phy-brcm-sata.c b/drivers/phy/phy-brcm-sata.c
new file mode 100644
index 000000000000..6c4c5cb791ca
--- /dev/null
+++ b/drivers/phy/phy-brcm-sata.c
@@ -0,0 +1,412 @@
+/*
+ * Broadcom SATA3 AHCI Controller PHY Driver
+ *
+ * Copyright (C) 2016 Broadcom
+ *
+ * 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, 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#define SATA_PCB_BANK_OFFSET				0x23c
+#define SATA_PCB_REG_OFFSET(ofs)			((ofs) * 4)
+
+#define MAX_PORTS					2
+
+/* Register offset between PHYs in PCB space */
+#define SATA_PCB_REG_28NM_SPACE_SIZE			0x1000
+
+/* The older SATA PHY registers duplicated per port registers within the map,
+ * rather than having a separate map per port.
+ */
+#define SATA_PCB_REG_40NM_SPACE_SIZE			0x10
+
+/* Register offset between PHYs in PHY control space */
+#define SATA_PHY_CTRL_REG_28NM_SPACE_SIZE		0x8
+
+enum brcm_sata_phy_version {
+	BRCM_SATA_PHY_STB_28NM,
+	BRCM_SATA_PHY_STB_40NM,
+	BRCM_SATA_PHY_IPROC_NS2,
+};
+
+struct brcm_sata_port {
+	int portnum;
+	struct phy *phy;
+	struct brcm_sata_phy *phy_priv;
+	bool ssc_en;
+};
+
+struct brcm_sata_phy {
+	struct device *dev;
+	void __iomem *phy_base;
+	void __iomem *ctrl_base;
+	enum brcm_sata_phy_version version;
+
+	struct brcm_sata_port phys[MAX_PORTS];
+};
+
+enum sata_phy_regs {
+	BLOCK0_REG_BANK				= 0x000,
+	BLOCK0_XGXSSTATUS			= 0x81,
+	BLOCK0_XGXSSTATUS_PLL_LOCK		= BIT(12),
+	BLOCK0_SPARE				= 0x8d,
+	BLOCK0_SPARE_OOB_CLK_SEL_MASK		= 0x3,
+	BLOCK0_SPARE_OOB_CLK_SEL_REFBY2		= 0x1,
+
+	PLL_REG_BANK_0				= 0x050,
+	PLL_REG_BANK_0_PLLCONTROL_0		= 0x81,
+
+	PLL1_REG_BANK				= 0x060,
+	PLL1_ACTRL2				= 0x82,
+	PLL1_ACTRL3				= 0x83,
+	PLL1_ACTRL4				= 0x84,
+
+	OOB_REG_BANK				= 0x150,
+	OOB_CTRL1				= 0x80,
+	OOB_CTRL1_BURST_MAX_MASK		= 0xf,
+	OOB_CTRL1_BURST_MAX_SHIFT		= 12,
+	OOB_CTRL1_BURST_MIN_MASK		= 0xf,
+	OOB_CTRL1_BURST_MIN_SHIFT		= 8,
+	OOB_CTRL1_WAKE_IDLE_MAX_MASK		= 0xf,
+	OOB_CTRL1_WAKE_IDLE_MAX_SHIFT		= 4,
+	OOB_CTRL1_WAKE_IDLE_MIN_MASK		= 0xf,
+	OOB_CTRL1_WAKE_IDLE_MIN_SHIFT		= 0,
+	OOB_CTRL2				= 0x81,
+	OOB_CTRL2_SEL_ENA_SHIFT			= 15,
+	OOB_CTRL2_SEL_ENA_RC_SHIFT		= 14,
+	OOB_CTRL2_RESET_IDLE_MAX_MASK		= 0x3f,
+	OOB_CTRL2_RESET_IDLE_MAX_SHIFT		= 8,
+	OOB_CTRL2_BURST_CNT_MASK		= 0x3,
+	OOB_CTRL2_BURST_CNT_SHIFT		= 6,
+	OOB_CTRL2_RESET_IDLE_MIN_MASK		= 0x3f,
+	OOB_CTRL2_RESET_IDLE_MIN_SHIFT		= 0,
+
+	TXPMD_REG_BANK				= 0x1a0,
+	TXPMD_CONTROL1				= 0x81,
+	TXPMD_CONTROL1_TX_SSC_EN_FRC		= BIT(0),
+	TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL	= BIT(1),
+	TXPMD_TX_FREQ_CTRL_CONTROL1		= 0x82,
+	TXPMD_TX_FREQ_CTRL_CONTROL2		= 0x83,
+	TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK	= 0x3ff,
+	TXPMD_TX_FREQ_CTRL_CONTROL3		= 0x84,
+	TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK	= 0x3ff,
+};
+
+enum sata_phy_ctrl_regs {
+	PHY_CTRL_1				= 0x0,
+	PHY_CTRL_1_RESET			= BIT(0),
+};
+
+static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port)
+{
+	struct brcm_sata_phy *priv = port->phy_priv;
+	u32 size = 0;
+
+	switch (priv->version) {
+	case BRCM_SATA_PHY_STB_28NM:
+	case BRCM_SATA_PHY_IPROC_NS2:
+		size = SATA_PCB_REG_28NM_SPACE_SIZE;
+		break;
+	case BRCM_SATA_PHY_STB_40NM:
+		size = SATA_PCB_REG_40NM_SPACE_SIZE;
+		break;
+	default:
+		dev_err(priv->dev, "invalid phy version\n");
+		break;
+	};
+
+	return priv->phy_base + (port->portnum * size);
+}
+
+static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port)
+{
+	struct brcm_sata_phy *priv = port->phy_priv;
+	u32 size = 0;
+
+	switch (priv->version) {
+	case BRCM_SATA_PHY_IPROC_NS2:
+		size = SATA_PHY_CTRL_REG_28NM_SPACE_SIZE;
+		break;
+	default:
+		dev_err(priv->dev, "invalid phy version\n");
+		break;
+	};
+
+	return priv->ctrl_base + (port->portnum * size);
+}
+
+static void brcm_sata_phy_wr(void __iomem *pcb_base, u32 bank,
+			     u32 ofs, u32 msk, u32 value)
+{
+	u32 tmp;
+
+	writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
+	tmp = readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
+	tmp = (tmp & msk) | value;
+	writel(tmp, pcb_base + SATA_PCB_REG_OFFSET(ofs));
+}
+
+static u32 brcm_sata_phy_rd(void __iomem *pcb_base, u32 bank, u32 ofs)
+{
+	writel(bank, pcb_base + SATA_PCB_BANK_OFFSET);
+	return readl(pcb_base + SATA_PCB_REG_OFFSET(ofs));
+}
+
+/* These defaults were characterized by H/W group */
+#define STB_FMIN_VAL_DEFAULT	0x3df
+#define STB_FMAX_VAL_DEFAULT	0x3df
+#define STB_FMAX_VAL_SSC	0x83
+
+static int brcm_stb_sata_init(struct brcm_sata_port *port)
+{
+	void __iomem *base = brcm_sata_pcb_base(port);
+	struct brcm_sata_phy *priv = port->phy_priv;
+	u32 tmp;
+
+	/* override the TX spread spectrum setting */
+	tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
+	brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
+
+	/* set fixed min freq */
+	brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
+			 ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
+			 STB_FMIN_VAL_DEFAULT);
+
+	/* set fixed max freq depending on SSC config */
+	if (port->ssc_en) {
+		dev_info(priv->dev, "enabling SSC on port%d\n", port->portnum);
+		tmp = STB_FMAX_VAL_SSC;
+	} else {
+		tmp = STB_FMAX_VAL_DEFAULT;
+	}
+
+	brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
+			  ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
+
+	return 0;
+}
+
+/* NS2 SATA PLL1 defaults were characterized by H/W group */
+#define NS2_PLL1_ACTRL2_MAGIC	0x1df8
+#define NS2_PLL1_ACTRL3_MAGIC	0x2b00
+#define NS2_PLL1_ACTRL4_MAGIC	0x8824
+
+static int brcm_ns2_sata_init(struct brcm_sata_port *port)
+{
+	int try;
+	unsigned int val;
+	void __iomem *base = brcm_sata_pcb_base(port);
+	void __iomem *ctrl_base = brcm_sata_ctrl_base(port);
+	struct device *dev = port->phy_priv->dev;
+
+	/* Configure OOB control */
+	val = 0x0;
+	val |= (0xc << OOB_CTRL1_BURST_MAX_SHIFT);
+	val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT);
+	val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT);
+	val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT);
+	brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
+	val = 0x0;
+	val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT);
+	val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT);
+	val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT);
+	brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
+
+	/* Configure PHY PLL register bank 1 */
+	val = NS2_PLL1_ACTRL2_MAGIC;
+	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
+	val = NS2_PLL1_ACTRL3_MAGIC;
+	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
+	val = NS2_PLL1_ACTRL4_MAGIC;
+	brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
+
+	/* Configure PHY BLOCK0 register bank */
+	/* Set oob_clk_sel to refclk/2 */
+	brcm_sata_phy_wr(base, BLOCK0_REG_BANK, BLOCK0_SPARE,
+			 ~BLOCK0_SPARE_OOB_CLK_SEL_MASK,
+			 BLOCK0_SPARE_OOB_CLK_SEL_REFBY2);
+
+	/* Strobe PHY reset using PHY control register */
+	writel(PHY_CTRL_1_RESET, ctrl_base + PHY_CTRL_1);
+	mdelay(1);
+	writel(0x0, ctrl_base + PHY_CTRL_1);
+	mdelay(1);
+
+	/* Wait for PHY PLL lock by polling pll_lock bit */
+	try = 50;
+	while (try) {
+		val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
+					BLOCK0_XGXSSTATUS);
+		if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
+			break;
+		msleep(20);
+		try--;
+	}
+	if (!try) {
+		/* PLL did not lock; give up */
+		dev_err(dev, "port%d PLL did not lock\n", port->portnum);
+		return -ETIMEDOUT;
+	}
+
+	dev_dbg(dev, "port%d initialized\n", port->portnum);
+
+	return 0;
+}
+
+static int brcm_sata_phy_init(struct phy *phy)
+{
+	int rc;
+	struct brcm_sata_port *port = phy_get_drvdata(phy);
+
+	switch (port->phy_priv->version) {
+	case BRCM_SATA_PHY_STB_28NM:
+	case BRCM_SATA_PHY_STB_40NM:
+		rc = brcm_stb_sata_init(port);
+		break;
+	case BRCM_SATA_PHY_IPROC_NS2:
+		rc = brcm_ns2_sata_init(port);
+		break;
+	default:
+		rc = -ENODEV;
+	};
+
+	return 0;
+}
+
+static const struct phy_ops phy_ops = {
+	.init		= brcm_sata_phy_init,
+	.owner		= THIS_MODULE,
+};
+
+static const struct of_device_id brcm_sata_phy_of_match[] = {
+	{ .compatible	= "brcm,bcm7445-sata-phy",
+	  .data = (void *)BRCM_SATA_PHY_STB_28NM },
+	{ .compatible	= "brcm,bcm7425-sata-phy",
+	  .data = (void *)BRCM_SATA_PHY_STB_40NM },
+	{ .compatible	= "brcm,iproc-ns2-sata-phy",
+	  .data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
+
+static int brcm_sata_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *dn = dev->of_node, *child;
+	const struct of_device_id *of_id;
+	struct brcm_sata_phy *priv;
+	struct resource *res;
+	struct phy_provider *provider;
+	int ret, count = 0;
+
+	if (of_get_child_count(dn) == 0)
+		return -ENODEV;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	dev_set_drvdata(dev, priv);
+	priv->dev = dev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
+	priv->phy_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->phy_base))
+		return PTR_ERR(priv->phy_base);
+
+	of_id = of_match_node(brcm_sata_phy_of_match, dn);
+	if (of_id)
+		priv->version = (enum brcm_sata_phy_version)of_id->data;
+	else
+		priv->version = BRCM_SATA_PHY_STB_28NM;
+
+	if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   "phy-ctrl");
+		priv->ctrl_base = devm_ioremap_resource(dev, res);
+		if (IS_ERR(priv->ctrl_base))
+			return PTR_ERR(priv->ctrl_base);
+	}
+
+	for_each_available_child_of_node(dn, child) {
+		unsigned int id;
+		struct brcm_sata_port *port;
+
+		if (of_property_read_u32(child, "reg", &id)) {
+			dev_err(dev, "missing reg property in node %s\n",
+					child->name);
+			ret = -EINVAL;
+			goto put_child;
+		}
+
+		if (id >= MAX_PORTS) {
+			dev_err(dev, "invalid reg: %u\n", id);
+			ret = -EINVAL;
+			goto put_child;
+		}
+		if (priv->phys[id].phy) {
+			dev_err(dev, "already registered port %u\n", id);
+			ret = -EINVAL;
+			goto put_child;
+		}
+
+		port = &priv->phys[id];
+		port->portnum = id;
+		port->phy_priv = priv;
+		port->phy = devm_phy_create(dev, child, &phy_ops);
+		port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
+		if (IS_ERR(port->phy)) {
+			dev_err(dev, "failed to create PHY\n");
+			ret = PTR_ERR(port->phy);
+			goto put_child;
+		}
+
+		phy_set_drvdata(port->phy, port);
+		count++;
+	}
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider)) {
+		dev_err(dev, "could not register PHY provider\n");
+		return PTR_ERR(provider);
+	}
+
+	dev_info(dev, "registered %d port(s)\n", count);
+
+	return 0;
+put_child:
+	of_node_put(child);
+	return ret;
+}
+
+static struct platform_driver brcm_sata_phy_driver = {
+	.probe	= brcm_sata_phy_probe,
+	.driver	= {
+		.of_match_table	= brcm_sata_phy_of_match,
+		.name		= "brcm-sata-phy",
+	}
+};
+module_platform_driver(brcm_sata_phy_driver);
+
+MODULE_DESCRIPTION("Broadcom SATA PHY driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marc Carino");
+MODULE_AUTHOR("Brian Norris");
+MODULE_ALIAS("platform:phy-brcm-sata");
diff --git a/drivers/phy/phy-brcmstb-sata.c b/drivers/phy/phy-brcmstb-sata.c
deleted file mode 100644
index a23172ff40e3..000000000000
--- a/drivers/phy/phy-brcmstb-sata.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Broadcom SATA3 AHCI Controller PHY Driver
- *
- * Copyright © 2009-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; either version 2, 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.
- */
-
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/phy/phy.h>
-#include <linux/platform_device.h>
-
-#define SATA_MDIO_BANK_OFFSET				0x23c
-#define SATA_MDIO_REG_OFFSET(ofs)			((ofs) * 4)
-
-#define MAX_PORTS					2
-
-/* Register offset between PHYs in PCB space */
-#define SATA_MDIO_REG_28NM_SPACE_SIZE			0x1000
-
-/* The older SATA PHY registers duplicated per port registers within the map,
- * rather than having a separate map per port.
- */
-#define SATA_MDIO_REG_40NM_SPACE_SIZE			0x10
-
-enum brcm_sata_phy_version {
-	BRCM_SATA_PHY_28NM,
-	BRCM_SATA_PHY_40NM,
-};
-
-struct brcm_sata_port {
-	int portnum;
-	struct phy *phy;
-	struct brcm_sata_phy *phy_priv;
-	bool ssc_en;
-};
-
-struct brcm_sata_phy {
-	struct device *dev;
-	void __iomem *phy_base;
-	enum brcm_sata_phy_version version;
-
-	struct brcm_sata_port phys[MAX_PORTS];
-};
-
-enum sata_mdio_phy_regs {
-	PLL_REG_BANK_0				= 0x50,
-	PLL_REG_BANK_0_PLLCONTROL_0		= 0x81,
-
-	TXPMD_REG_BANK				= 0x1a0,
-	TXPMD_CONTROL1				= 0x81,
-	TXPMD_CONTROL1_TX_SSC_EN_FRC		= BIT(0),
-	TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL	= BIT(1),
-	TXPMD_TX_FREQ_CTRL_CONTROL1		= 0x82,
-	TXPMD_TX_FREQ_CTRL_CONTROL2		= 0x83,
-	TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK	= 0x3ff,
-	TXPMD_TX_FREQ_CTRL_CONTROL3		= 0x84,
-	TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK	= 0x3ff,
-};
-
-static inline void __iomem *brcm_sata_phy_base(struct brcm_sata_port *port)
-{
-	struct brcm_sata_phy *priv = port->phy_priv;
-	u32 offset = 0;
-
-	if (priv->version == BRCM_SATA_PHY_28NM)
-		offset = SATA_MDIO_REG_28NM_SPACE_SIZE;
-	else if (priv->version == BRCM_SATA_PHY_40NM)
-		offset = SATA_MDIO_REG_40NM_SPACE_SIZE;
-	else
-		dev_err(priv->dev, "invalid phy version\n");
-
-	return priv->phy_base + (port->portnum * offset);
-}
-
-static void brcm_sata_mdio_wr(void __iomem *addr, u32 bank, u32 ofs,
-			      u32 msk, u32 value)
-{
-	u32 tmp;
-
-	writel(bank, addr + SATA_MDIO_BANK_OFFSET);
-	tmp = readl(addr + SATA_MDIO_REG_OFFSET(ofs));
-	tmp = (tmp & msk) | value;
-	writel(tmp, addr + SATA_MDIO_REG_OFFSET(ofs));
-}
-
-/* These defaults were characterized by H/W group */
-#define FMIN_VAL_DEFAULT	0x3df
-#define FMAX_VAL_DEFAULT	0x3df
-#define FMAX_VAL_SSC		0x83
-
-static void brcm_sata_cfg_ssc(struct brcm_sata_port *port)
-{
-	void __iomem *base = brcm_sata_phy_base(port);
-	struct brcm_sata_phy *priv = port->phy_priv;
-	u32 tmp;
-
-	/* override the TX spread spectrum setting */
-	tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC;
-	brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp);
-
-	/* set fixed min freq */
-	brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2,
-			  ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK,
-			  FMIN_VAL_DEFAULT);
-
-	/* set fixed max freq depending on SSC config */
-	if (port->ssc_en) {
-		dev_info(priv->dev, "enabling SSC on port %d\n", port->portnum);
-		tmp = FMAX_VAL_SSC;
-	} else {
-		tmp = FMAX_VAL_DEFAULT;
-	}
-
-	brcm_sata_mdio_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3,
-			  ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp);
-}
-
-static int brcm_sata_phy_init(struct phy *phy)
-{
-	struct brcm_sata_port *port = phy_get_drvdata(phy);
-
-	brcm_sata_cfg_ssc(port);
-
-	return 0;
-}
-
-static const struct phy_ops phy_ops = {
-	.init		= brcm_sata_phy_init,
-	.owner		= THIS_MODULE,
-};
-
-static const struct of_device_id brcm_sata_phy_of_match[] = {
-	{ .compatible	= "brcm,bcm7445-sata-phy",
-	  .data = (void *)BRCM_SATA_PHY_28NM },
-	{ .compatible	= "brcm,bcm7425-sata-phy",
-	  .data = (void *)BRCM_SATA_PHY_40NM },
-	{},
-};
-MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
-
-static int brcm_sata_phy_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *dn = dev->of_node, *child;
-	const struct of_device_id *of_id;
-	struct brcm_sata_phy *priv;
-	struct resource *res;
-	struct phy_provider *provider;
-	int ret, count = 0;
-
-	if (of_get_child_count(dn) == 0)
-		return -ENODEV;
-
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	dev_set_drvdata(dev, priv);
-	priv->dev = dev;
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
-	priv->phy_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(priv->phy_base))
-		return PTR_ERR(priv->phy_base);
-
-	of_id = of_match_node(brcm_sata_phy_of_match, dn);
-	if (of_id)
-		priv->version = (enum brcm_sata_phy_version)of_id->data;
-	else
-		priv->version = BRCM_SATA_PHY_28NM;
-
-	for_each_available_child_of_node(dn, child) {
-		unsigned int id;
-		struct brcm_sata_port *port;
-
-		if (of_property_read_u32(child, "reg", &id)) {
-			dev_err(dev, "missing reg property in node %s\n",
-					child->name);
-			ret = -EINVAL;
-			goto put_child;
-		}
-
-		if (id >= MAX_PORTS) {
-			dev_err(dev, "invalid reg: %u\n", id);
-			ret = -EINVAL;
-			goto put_child;
-		}
-		if (priv->phys[id].phy) {
-			dev_err(dev, "already registered port %u\n", id);
-			ret = -EINVAL;
-			goto put_child;
-		}
-
-		port = &priv->phys[id];
-		port->portnum = id;
-		port->phy_priv = priv;
-		port->phy = devm_phy_create(dev, child, &phy_ops);
-		port->ssc_en = of_property_read_bool(child, "brcm,enable-ssc");
-		if (IS_ERR(port->phy)) {
-			dev_err(dev, "failed to create PHY\n");
-			ret = PTR_ERR(port->phy);
-			goto put_child;
-		}
-
-		phy_set_drvdata(port->phy, port);
-		count++;
-	}
-
-	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	if (IS_ERR(provider)) {
-		dev_err(dev, "could not register PHY provider\n");
-		return PTR_ERR(provider);
-	}
-
-	dev_info(dev, "registered %d port(s)\n", count);
-
-	return 0;
-put_child:
-	of_node_put(child);
-	return ret;
-}
-
-static struct platform_driver brcm_sata_phy_driver = {
-	.probe	= brcm_sata_phy_probe,
-	.driver	= {
-		.of_match_table	= brcm_sata_phy_of_match,
-		.name		= "brcmstb-sata-phy",
-	}
-};
-module_platform_driver(brcm_sata_phy_driver);
-
-MODULE_DESCRIPTION("Broadcom STB SATA PHY driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marc Carino");
-MODULE_AUTHOR("Brian Norris");
-MODULE_ALIAS("platform:phy-brcmstb-sata");
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c
index 2a54caba93b4..cc093ebfda94 100644
--- a/drivers/phy/phy-exynos-mipi-video.c
+++ b/drivers/phy/phy-exynos-mipi-video.c
@@ -1,7 +1,7 @@
 /*
  * Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
  *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2013,2016 Samsung Electronics Co., Ltd.
  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -13,96 +13,276 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon/exynos4-pmu.h>
+#include <linux/mfd/syscon/exynos5-pmu.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/phy/phy.h>
-#include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/spinlock.h>
 #include <linux/mfd/syscon.h>
 
-/* MIPI_PHYn_CONTROL reg. offset (for base address from ioremap): n = 0..1 */
-#define EXYNOS_MIPI_PHY_CONTROL(n)	((n) * 4)
-
 enum exynos_mipi_phy_id {
+	EXYNOS_MIPI_PHY_ID_NONE = -1,
 	EXYNOS_MIPI_PHY_ID_CSIS0,
 	EXYNOS_MIPI_PHY_ID_DSIM0,
 	EXYNOS_MIPI_PHY_ID_CSIS1,
 	EXYNOS_MIPI_PHY_ID_DSIM1,
+	EXYNOS_MIPI_PHY_ID_CSIS2,
 	EXYNOS_MIPI_PHYS_NUM
 };
 
-#define is_mipi_dsim_phy_id(id) \
-	((id) == EXYNOS_MIPI_PHY_ID_DSIM0 || (id) == EXYNOS_MIPI_PHY_ID_DSIM1)
+enum exynos_mipi_phy_regmap_id {
+	EXYNOS_MIPI_REGMAP_PMU,
+	EXYNOS_MIPI_REGMAP_DISP,
+	EXYNOS_MIPI_REGMAP_CAM0,
+	EXYNOS_MIPI_REGMAP_CAM1,
+	EXYNOS_MIPI_REGMAPS_NUM
+};
+
+struct mipi_phy_device_desc {
+	int num_phys;
+	int num_regmaps;
+	const char *regmap_names[EXYNOS_MIPI_REGMAPS_NUM];
+	struct exynos_mipi_phy_desc {
+		enum exynos_mipi_phy_id	coupled_phy_id;
+		u32 enable_val;
+		unsigned int enable_reg;
+		enum exynos_mipi_phy_regmap_id enable_map;
+		u32 resetn_val;
+		unsigned int resetn_reg;
+		enum exynos_mipi_phy_regmap_id resetn_map;
+	} phys[EXYNOS_MIPI_PHYS_NUM];
+};
+
+static const struct mipi_phy_device_desc s5pv210_mipi_phy = {
+	.num_regmaps = 1,
+	.regmap_names = {"syscon"},
+	.num_phys = 4,
+	.phys = {
+		{
+			/* EXYNOS_MIPI_PHY_ID_CSIS0 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
+			.enable_val = EXYNOS4_MIPI_PHY_ENABLE,
+			.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
+			.resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_DSIM0 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
+			.enable_val = EXYNOS4_MIPI_PHY_ENABLE,
+			.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS4_MIPI_PHY_MRESETN,
+			.resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(0),
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_CSIS1 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1,
+			.enable_val = EXYNOS4_MIPI_PHY_ENABLE,
+			.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS4_MIPI_PHY_SRESETN,
+			.resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_DSIM1 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1,
+			.enable_val = EXYNOS4_MIPI_PHY_ENABLE,
+			.enable_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS4_MIPI_PHY_MRESETN,
+			.resetn_reg = EXYNOS4_MIPI_PHY_CONTROL(1),
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		},
+	},
+};
+
+static const struct mipi_phy_device_desc exynos5420_mipi_phy = {
+	.num_regmaps = 1,
+	.regmap_names = {"syscon"},
+	.num_phys = 5,
+	.phys = {
+		{
+			/* EXYNOS_MIPI_PHY_ID_CSIS0 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN,
+			.resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_DSIM0 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS5_MIPI_PHY_M_RESETN,
+			.resetn_reg = EXYNOS5420_MIPI_PHY0_CONTROL,
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_CSIS1 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM1,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN,
+			.resetn_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_DSIM1 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS1,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS5_MIPI_PHY_M_RESETN,
+			.resetn_reg = EXYNOS5420_MIPI_PHY1_CONTROL,
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_CSIS2 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5420_MIPI_PHY2_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = EXYNOS5_MIPI_PHY_S_RESETN,
+			.resetn_reg = EXYNOS5420_MIPI_PHY2_CONTROL,
+			.resetn_map = EXYNOS_MIPI_REGMAP_PMU,
+		},
+	},
+};
+
+#define EXYNOS5433_SYSREG_DISP_MIPI_PHY		0x100C
+#define EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON	0x1014
+#define EXYNOS5433_SYSREG_CAM1_MIPI_DPHY_CON	0x1020
+
+static const struct mipi_phy_device_desc exynos5433_mipi_phy = {
+	.num_regmaps = 4,
+	.regmap_names = {
+		"samsung,pmu-syscon",
+		"samsung,disp-sysreg",
+		"samsung,cam0-sysreg",
+		"samsung,cam1-sysreg"
+	},
+	.num_phys = 5,
+	.phys = {
+		{
+			/* EXYNOS_MIPI_PHY_ID_CSIS0 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_DSIM0,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5433_MIPI_PHY0_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = BIT(0),
+			.resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON,
+			.resetn_map = EXYNOS_MIPI_REGMAP_CAM0,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_DSIM0 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_CSIS0,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5433_MIPI_PHY0_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = BIT(0),
+			.resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY,
+			.resetn_map = EXYNOS_MIPI_REGMAP_DISP,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_CSIS1 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5433_MIPI_PHY1_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = BIT(1),
+			.resetn_reg = EXYNOS5433_SYSREG_CAM0_MIPI_DPHY_CON,
+			.resetn_map = EXYNOS_MIPI_REGMAP_CAM0,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_DSIM1 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5433_MIPI_PHY1_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = BIT(1),
+			.resetn_reg = EXYNOS5433_SYSREG_DISP_MIPI_PHY,
+			.resetn_map = EXYNOS_MIPI_REGMAP_DISP,
+		}, {
+			/* EXYNOS_MIPI_PHY_ID_CSIS2 */
+			.coupled_phy_id = EXYNOS_MIPI_PHY_ID_NONE,
+			.enable_val = EXYNOS5_PHY_ENABLE,
+			.enable_reg = EXYNOS5433_MIPI_PHY2_CONTROL,
+			.enable_map = EXYNOS_MIPI_REGMAP_PMU,
+			.resetn_val = BIT(0),
+			.resetn_reg = EXYNOS5433_SYSREG_CAM1_MIPI_DPHY_CON,
+			.resetn_map = EXYNOS_MIPI_REGMAP_CAM1,
+		},
+	},
+};
 
 struct exynos_mipi_video_phy {
+	struct regmap *regmaps[EXYNOS_MIPI_REGMAPS_NUM];
+	int num_phys;
 	struct video_phy_desc {
 		struct phy *phy;
 		unsigned int index;
+		const struct exynos_mipi_phy_desc *data;
 	} phys[EXYNOS_MIPI_PHYS_NUM];
 	spinlock_t slock;
-	void __iomem *regs;
-	struct regmap *regmap;
 };
 
-static int __set_phy_state(struct exynos_mipi_video_phy *state,
-			enum exynos_mipi_phy_id id, unsigned int on)
+static inline int __is_running(const struct exynos_mipi_phy_desc *data,
+			struct exynos_mipi_video_phy *state)
 {
-	const unsigned int offset = EXYNOS4_MIPI_PHY_CONTROL(id / 2);
-	void __iomem *addr;
-	u32 val, reset;
+	u32 val;
 
-	if (is_mipi_dsim_phy_id(id))
-		reset = EXYNOS4_MIPI_PHY_MRESETN;
-	else
-		reset = EXYNOS4_MIPI_PHY_SRESETN;
+	regmap_read(state->regmaps[data->resetn_map], data->resetn_reg, &val);
+	return val & data->resetn_val;
+}
+
+static int __set_phy_state(const struct exynos_mipi_phy_desc *data,
+			   struct exynos_mipi_video_phy *state, unsigned int on)
+{
+	u32 val;
 
 	spin_lock(&state->slock);
 
-	if (!IS_ERR(state->regmap)) {
-		regmap_read(state->regmap, offset, &val);
-		if (on)
-			val |= reset;
-		else
-			val &= ~reset;
-		regmap_write(state->regmap, offset, val);
-		if (on)
-			val |= EXYNOS4_MIPI_PHY_ENABLE;
-		else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK))
-			val &= ~EXYNOS4_MIPI_PHY_ENABLE;
-		regmap_write(state->regmap, offset, val);
-	} else {
-		addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
-
-		val = readl(addr);
-		if (on)
-			val |= reset;
-		else
-			val &= ~reset;
-		writel(val, addr);
-		/* Clear ENABLE bit only if MRESETN, SRESETN bits are not set */
-		if (on)
-			val |= EXYNOS4_MIPI_PHY_ENABLE;
-		else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK))
-			val &= ~EXYNOS4_MIPI_PHY_ENABLE;
-
-		writel(val, addr);
+	/* disable in PMU sysreg */
+	if (!on && data->coupled_phy_id >= 0 &&
+	    !__is_running(state->phys[data->coupled_phy_id].data, state)) {
+		regmap_read(state->regmaps[data->enable_map], data->enable_reg,
+			    &val);
+		val &= ~data->enable_val;
+		regmap_write(state->regmaps[data->enable_map], data->enable_reg,
+			     val);
+	}
+
+	/* PHY reset */
+	regmap_read(state->regmaps[data->resetn_map], data->resetn_reg, &val);
+	val = on ? (val | data->resetn_val) : (val & ~data->resetn_val);
+	regmap_write(state->regmaps[data->resetn_map], data->resetn_reg, val);
+
+	/* enable in PMU sysreg */
+	if (on) {
+		regmap_read(state->regmaps[data->enable_map], data->enable_reg,
+			    &val);
+		val |= data->enable_val;
+		regmap_write(state->regmaps[data->enable_map], data->enable_reg,
+			     val);
 	}
 
 	spin_unlock(&state->slock);
+
 	return 0;
 }
 
 #define to_mipi_video_phy(desc) \
-	container_of((desc), struct exynos_mipi_video_phy, phys[(desc)->index]);
+	container_of((desc), struct exynos_mipi_video_phy, phys[(desc)->index])
 
 static int exynos_mipi_video_phy_power_on(struct phy *phy)
 {
 	struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
 	struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
 
-	return __set_phy_state(state, phy_desc->index, 1);
+	return __set_phy_state(phy_desc->data, state, 1);
 }
 
 static int exynos_mipi_video_phy_power_off(struct phy *phy)
@@ -110,7 +290,7 @@ static int exynos_mipi_video_phy_power_off(struct phy *phy)
 	struct video_phy_desc *phy_desc = phy_get_drvdata(phy);
 	struct exynos_mipi_video_phy *state = to_mipi_video_phy(phy_desc);
 
-	return __set_phy_state(state, phy_desc->index, 0);
+	return __set_phy_state(phy_desc->data, state, 0);
 }
 
 static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
@@ -118,7 +298,7 @@ static struct phy *exynos_mipi_video_phy_xlate(struct device *dev,
 {
 	struct exynos_mipi_video_phy *state = dev_get_drvdata(dev);
 
-	if (WARN_ON(args->args[0] >= EXYNOS_MIPI_PHYS_NUM))
+	if (WARN_ON(args->args[0] >= state->num_phys))
 		return ERR_PTR(-ENODEV);
 
 	return state->phys[args->args[0]].phy;
@@ -132,32 +312,33 @@ static const struct phy_ops exynos_mipi_video_phy_ops = {
 
 static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
 {
+	const struct mipi_phy_device_desc *phy_dev;
 	struct exynos_mipi_video_phy *state;
 	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct phy_provider *phy_provider;
 	unsigned int i;
 
+	phy_dev = of_device_get_match_data(dev);
+	if (!phy_dev)
+		return -ENODEV;
+
 	state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return -ENOMEM;
 
-	state->regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
-	if (IS_ERR(state->regmap)) {
-		struct resource *res;
-
-		dev_info(dev, "regmap lookup failed: %ld\n",
-			 PTR_ERR(state->regmap));
-
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		state->regs = devm_ioremap_resource(dev, res);
-		if (IS_ERR(state->regs))
-			return PTR_ERR(state->regs);
+	for (i = 0; i < phy_dev->num_regmaps; i++) {
+		state->regmaps[i] = syscon_regmap_lookup_by_phandle(np,
+						phy_dev->regmap_names[i]);
+		if (IS_ERR(state->regmaps[i]))
+			return PTR_ERR(state->regmaps[i]);
 	}
+	state->num_phys = phy_dev->num_phys;
+	spin_lock_init(&state->slock);
 
 	dev_set_drvdata(dev, state);
-	spin_lock_init(&state->slock);
 
-	for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
+	for (i = 0; i < state->num_phys; i++) {
 		struct phy *phy = devm_phy_create(dev, NULL,
 						  &exynos_mipi_video_phy_ops);
 		if (IS_ERR(phy)) {
@@ -167,6 +348,7 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
 
 		state->phys[i].phy = phy;
 		state->phys[i].index = i;
+		state->phys[i].data = &phy_dev->phys[i];
 		phy_set_drvdata(phy, &state->phys[i]);
 	}
 
@@ -177,8 +359,17 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id exynos_mipi_video_phy_of_match[] = {
-	{ .compatible = "samsung,s5pv210-mipi-video-phy" },
-	{ },
+	{
+		.compatible = "samsung,s5pv210-mipi-video-phy",
+		.data = &s5pv210_mipi_phy,
+	}, {
+		.compatible = "samsung,exynos5420-mipi-video-phy",
+		.data = &exynos5420_mipi_phy,
+	}, {
+		.compatible = "samsung,exynos5433-mipi-video-phy",
+		.data = &exynos5433_mipi_phy,
+	},
+	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, exynos_mipi_video_phy_of_match);
 
diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
index c0e7b4b0cf5c..4d85e730ccab 100644
--- a/drivers/phy/phy-mt65xx-usb3.c
+++ b/drivers/phy/phy-mt65xx-usb3.c
@@ -134,6 +134,11 @@
 #define U3P_SR_COEF_DIVISOR	1000
 #define U3P_FM_DET_CYCLE_CNT	1024
 
+struct mt65xx_phy_pdata {
+	/* avoid RX sensitivity level degradation only for mt8173 */
+	bool avoid_rx_sen_degradation;
+};
+
 struct mt65xx_phy_instance {
 	struct phy *phy;
 	void __iomem *port_base;
@@ -145,6 +150,7 @@ 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 */
+	const struct mt65xx_phy_pdata *pdata;
 	struct mt65xx_phy_instance **phys;
 	int nphys;
 };
@@ -241,22 +247,26 @@ static void phy_instance_init(struct mt65xx_u3phy *u3phy,
 		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);
+	if (u3phy->pdata->avoid_rx_sen_degradation) {
+		if (!index) {
+			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);
+		}
 	}
 
 	tmp = readl(port_base + U3P_USBPHYACR6);
@@ -318,7 +328,7 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
 		tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
 		writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
 
-		/* [mt8173]switch 100uA current to SSUSB */
+		/* switch 100uA current to SSUSB */
 		tmp = readl(port_base + U3P_USBPHYACR5);
 		tmp |= PA5_RG_U2_HS_100U_U3_EN;
 		writel(tmp, port_base + U3P_USBPHYACR5);
@@ -335,7 +345,7 @@ static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
 	tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
 	writel(tmp, port_base + U3P_USBPHYACR5);
 
-	if (index) {
+	if (u3phy->pdata->avoid_rx_sen_degradation && index) {
 		tmp = readl(port_base + U3D_U2PHYDCR0);
 		tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
 		writel(tmp, port_base + U3D_U2PHYDCR0);
@@ -386,7 +396,9 @@ static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
 		tmp = readl(port_base + U3P_U3_PHYA_REG0);
 		tmp &= ~P3A_RG_U3_VUSB10_ON;
 		writel(tmp, port_base + U3P_U3_PHYA_REG0);
-	} else {
+	}
+
+	if (u3phy->pdata->avoid_rx_sen_degradation && index) {
 		tmp = readl(port_base + U3D_U2PHYDCR0);
 		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
 		writel(tmp, port_base + U3D_U2PHYDCR0);
@@ -402,7 +414,7 @@ static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
 	u32 index = instance->index;
 	u32 tmp;
 
-	if (index) {
+	if (u3phy->pdata->avoid_rx_sen_degradation && index) {
 		tmp = readl(port_base + U3D_U2PHYDCR0);
 		tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
 		writel(tmp, port_base + U3D_U2PHYDCR0);
@@ -502,8 +514,24 @@ static struct phy_ops mt65xx_u3phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+static const struct mt65xx_phy_pdata mt2701_pdata = {
+	.avoid_rx_sen_degradation = false,
+};
+
+static const struct mt65xx_phy_pdata mt8173_pdata = {
+	.avoid_rx_sen_degradation = true,
+};
+
+static const struct of_device_id mt65xx_u3phy_id_table[] = {
+	{ .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata },
+	{ .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
+
 static int mt65xx_u3phy_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *match;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct device_node *child_np;
@@ -513,10 +541,15 @@ static int mt65xx_u3phy_probe(struct platform_device *pdev)
 	struct resource res;
 	int port, retval;
 
+	match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node);
+	if (!match)
+		return -EINVAL;
+
 	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
 	if (!u3phy)
 		return -ENOMEM;
 
+	u3phy->pdata = match->data;
 	u3phy->nphys = of_get_child_count(np);
 	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
 				       sizeof(*u3phy->phys), GFP_KERNEL);
@@ -587,12 +620,6 @@ put_child:
 	return retval;
 }
 
-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		= {
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index c7a05996d5c1..97d4dd6ea924 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -195,6 +195,7 @@ static const struct of_device_id rcar_gen2_phy_match_table[] = {
 	{ .compatible = "renesas,usb-phy-r8a7790" },
 	{ .compatible = "renesas,usb-phy-r8a7791" },
 	{ .compatible = "renesas,usb-phy-r8a7794" },
+	{ .compatible = "renesas,rcar-gen2-usb-phy" },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
index bc4f7dd821aa..76bb88f0700a 100644
--- a/drivers/phy/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/phy-rcar-gen3-usb2.c
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/extcon.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -19,6 +20,7 @@
 #include <linux/of_address.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 
 /******* USB2.0 Host registers (original offset is +0x200) *******/
 #define USB2_INT_ENABLE		0x000
@@ -74,20 +76,17 @@
 #define USB2_ADPCTRL_IDPULLUP		BIT(5)	/* 1 = ID sampling is enabled */
 #define USB2_ADPCTRL_DRVVBUS		BIT(4)
 
-struct rcar_gen3_data {
-	void __iomem *base;
-	struct clk *clk;
-};
-
 struct rcar_gen3_chan {
-	struct rcar_gen3_data usb2;
+	void __iomem *base;
+	struct extcon_dev *extcon;
 	struct phy *phy;
+	struct regulator *vbus;
 	bool has_otg;
 };
 
 static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
 {
-	void __iomem *usb2_base = ch->usb2.base;
+	void __iomem *usb2_base = ch->base;
 	u32 val = readl(usb2_base + USB2_COMMCTRL);
 
 	dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, host);
@@ -100,7 +99,7 @@ static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
 
 static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
 {
-	void __iomem *usb2_base = ch->usb2.base;
+	void __iomem *usb2_base = ch->base;
 	u32 val = readl(usb2_base + USB2_LINECTRL1);
 
 	dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm);
@@ -114,7 +113,7 @@ static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
 
 static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 {
-	void __iomem *usb2_base = ch->usb2.base;
+	void __iomem *usb2_base = ch->base;
 	u32 val = readl(usb2_base + USB2_ADPCTRL);
 
 	dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, vbus);
@@ -130,6 +129,9 @@ static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
 	rcar_gen3_set_linectrl(ch, 1, 1);
 	rcar_gen3_set_host_mode(ch, 1);
 	rcar_gen3_enable_vbus_ctrl(ch, 1);
+
+	extcon_set_cable_state_(ch->extcon, EXTCON_USB_HOST, true);
+	extcon_set_cable_state_(ch->extcon, EXTCON_USB, false);
 }
 
 static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
@@ -137,17 +139,20 @@ static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
 	rcar_gen3_set_linectrl(ch, 0, 1);
 	rcar_gen3_set_host_mode(ch, 0);
 	rcar_gen3_enable_vbus_ctrl(ch, 0);
+
+	extcon_set_cable_state_(ch->extcon, EXTCON_USB_HOST, false);
+	extcon_set_cable_state_(ch->extcon, EXTCON_USB, true);
 }
 
 static bool rcar_gen3_check_vbus(struct rcar_gen3_chan *ch)
 {
-	return !!(readl(ch->usb2.base + USB2_ADPCTRL) &
+	return !!(readl(ch->base + USB2_ADPCTRL) &
 		  USB2_ADPCTRL_OTGSESSVLD);
 }
 
 static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 {
-	return !!(readl(ch->usb2.base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
+	return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
 }
 
 static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
@@ -166,7 +171,7 @@ static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
 
 static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 {
-	void __iomem *usb2_base = ch->usb2.base;
+	void __iomem *usb2_base = ch->base;
 	u32 val;
 
 	val = readl(usb2_base + USB2_VBCTRL);
@@ -187,7 +192,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 static int rcar_gen3_phy_usb2_init(struct phy *p)
 {
 	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
-	void __iomem *usb2_base = channel->usb2.base;
+	void __iomem *usb2_base = channel->base;
 
 	/* Initialize USB2 part */
 	writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE);
@@ -205,7 +210,7 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
 {
 	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
 
-	writel(0, channel->usb2.base + USB2_INT_ENABLE);
+	writel(0, channel->base + USB2_INT_ENABLE);
 
 	return 0;
 }
@@ -213,8 +218,15 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
 static int rcar_gen3_phy_usb2_power_on(struct phy *p)
 {
 	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
-	void __iomem *usb2_base = channel->usb2.base;
+	void __iomem *usb2_base = channel->base;
 	u32 val;
+	int ret;
+
+	if (channel->vbus) {
+		ret = regulator_enable(channel->vbus);
+		if (ret)
+			return ret;
+	}
 
 	val = readl(usb2_base + USB2_USBCTR);
 	val |= USB2_USBCTR_PLL_RST;
@@ -225,17 +237,29 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
 	return 0;
 }
 
+static int rcar_gen3_phy_usb2_power_off(struct phy *p)
+{
+	struct rcar_gen3_chan *channel = phy_get_drvdata(p);
+	int ret = 0;
+
+	if (channel->vbus)
+		ret = regulator_disable(channel->vbus);
+
+	return ret;
+}
+
 static struct phy_ops rcar_gen3_phy_usb2_ops = {
 	.init		= rcar_gen3_phy_usb2_init,
 	.exit		= rcar_gen3_phy_usb2_exit,
 	.power_on	= rcar_gen3_phy_usb2_power_on,
+	.power_off	= rcar_gen3_phy_usb2_power_off,
 	.owner		= THIS_MODULE,
 };
 
 static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 {
 	struct rcar_gen3_chan *ch = _ch;
-	void __iomem *usb2_base = ch->usb2.base;
+	void __iomem *usb2_base = ch->base;
 	u32 status = readl(usb2_base + USB2_OBINTSTA);
 	irqreturn_t ret = IRQ_NONE;
 
@@ -251,10 +275,17 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 
 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
 	{ .compatible = "renesas,usb2-phy-r8a7795" },
+	{ .compatible = "renesas,rcar-gen3-usb2-phy" },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table);
 
+static const unsigned int rcar_gen3_phy_cable[] = {
+	EXTCON_USB,
+	EXTCON_USB_HOST,
+	EXTCON_NONE,
+};
+
 static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -273,18 +304,30 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	channel->usb2.base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(channel->usb2.base))
-		return PTR_ERR(channel->usb2.base);
+	channel->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(channel->base))
+		return PTR_ERR(channel->base);
 
 	/* call request_irq for OTG */
 	irq = platform_get_irq(pdev, 0);
 	if (irq >= 0) {
+		int ret;
+
 		irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
 				       IRQF_SHARED, dev_name(dev), channel);
 		if (irq < 0)
 			dev_err(dev, "No irq handler (%d)\n", irq);
 		channel->has_otg = true;
+		channel->extcon = devm_extcon_dev_allocate(dev,
+							rcar_gen3_phy_cable);
+		if (IS_ERR(channel->extcon))
+			return PTR_ERR(channel->extcon);
+
+		ret = devm_extcon_dev_register(dev, channel->extcon);
+		if (ret < 0) {
+			dev_err(dev, "Failed to register extcon\n");
+			return ret;
+		}
 	}
 
 	/* devm_phy_create() will call pm_runtime_enable(dev); */
@@ -294,6 +337,13 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 		return PTR_ERR(channel->phy);
 	}
 
+	channel->vbus = devm_regulator_get_optional(dev, "vbus");
+	if (IS_ERR(channel->vbus)) {
+		if (PTR_ERR(channel->vbus) == -EPROBE_DEFER)
+			return PTR_ERR(channel->vbus);
+		channel->vbus = NULL;
+	}
+
 	phy_set_drvdata(channel->phy, channel);
 
 	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c
index f62d899063a3..d60b149cff0f 100644
--- a/drivers/phy/phy-rockchip-usb.c
+++ b/drivers/phy/phy-rockchip-usb.c
@@ -216,7 +216,7 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
 			init.parent_names = &clk_name;
 			init.num_parents = 1;
 		} else {
-			init.flags = CLK_IS_ROOT;
+			init.flags = 0;
 			init.parent_names = NULL;
 			init.num_parents = 0;
 		}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 8ed451dd651e..8689dcba5201 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -31,8 +31,6 @@ if USB_SUPPORT
 
 config USB_COMMON
 	tristate
-	default y
-	depends on USB || USB_GADGET
 
 config USB_ARCH_HAS_HCD
 	def_bool y
@@ -41,6 +39,7 @@ config USB_ARCH_HAS_HCD
 config USB
 	tristate "Support for Host-side USB"
 	depends on USB_ARCH_HAS_HCD
+	select USB_COMMON
 	select NLS  # for UTF-8 strings
 	---help---
 	  Universal Serial Bus (USB) is a specification for a serial bus
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index a2ae88dbda78..4333dc576a12 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -173,10 +173,10 @@ struct uea_softc {
 	const struct firmware *dsp_firm;
 	struct urb *urb_int;
 
-	void (*dispatch_cmv) (struct uea_softc *, struct intr_pkt *);
-	void (*schedule_load_page) (struct uea_softc *, struct intr_pkt *);
-	int (*stat) (struct uea_softc *);
-	int (*send_cmvs) (struct uea_softc *);
+	void (*dispatch_cmv)(struct uea_softc *, struct intr_pkt *);
+	void (*schedule_load_page)(struct uea_softc *, struct intr_pkt *);
+	int (*stat)(struct uea_softc *);
+	int (*send_cmvs)(struct uea_softc *);
 
 	/* keep in sync with eaglectl */
 	struct uea_stats {
@@ -2454,7 +2454,7 @@ UEA_ATTR(firmid, 0);
 
 /* Retrieve the device End System Identifier (MAC) */
 
-static int uea_getesi(struct uea_softc *sc, u_char * esi)
+static int uea_getesi(struct uea_softc *sc, u_char *esi)
 {
 	unsigned char mac_str[2 * ETH_ALEN + 1];
 	int i;
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 9ce8c9f91674..dedc33e589f4 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -292,10 +292,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 	if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
 		data->supports_runtime_pm = true;
 
-	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		goto err_clk;
-
 	ret = imx_usbmisc_init(data->usbmisc_data);
 	if (ret) {
 		dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n", ret);
diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c
index 504708f59b93..9059b7dc185e 100644
--- a/drivers/usb/common/usb-otg-fsm.c
+++ b/drivers/usb/common/usb-otg-fsm.c
@@ -61,8 +61,6 @@ static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 	return 0;
 }
 
-static int state_changed;
-
 /* Called when leaving a state.  Do state clean up jobs here */
 static void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
 {
@@ -208,7 +206,6 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm)
 /* Called when entering a state */
 static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 {
-	state_changed = 1;
 	if (fsm->otg->state == new_state)
 		return 0;
 	VDBG("Set state: %s\n", usb_otg_state_string(new_state));
@@ -324,6 +321,7 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 	}
 
 	fsm->otg->state = new_state;
+	fsm->state_changed = 1;
 	return 0;
 }
 
@@ -335,7 +333,7 @@ int otg_statemachine(struct otg_fsm *fsm)
 	mutex_lock(&fsm->lock);
 
 	state = fsm->otg->state;
-	state_changed = 0;
+	fsm->state_changed = 0;
 	/* State machine state change judgement */
 
 	switch (state) {
@@ -448,7 +446,7 @@ int otg_statemachine(struct otg_fsm *fsm)
 	}
 	mutex_unlock(&fsm->lock);
 
-	VDBG("quit statemachine, changed = %d\n", state_changed);
-	return state_changed;
+	VDBG("quit statemachine, changed = %d\n", fsm->state_changed);
+	return fsm->state_changed;
 }
 EXPORT_SYMBOL_GPL(otg_statemachine);
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 2741566ee4f2..98e39f91723a 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -122,6 +122,9 @@ void *hcd_buffer_alloc(
 	struct usb_hcd		*hcd = bus_to_hcd(bus);
 	int			i;
 
+	if (size == 0)
+		return NULL;
+
 	/* some USB hosts just use PIO */
 	if (!IS_ENABLED(CONFIG_HAS_DMA) ||
 	    (!bus->controller->dma_mask &&
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 52c4461dfccd..e9f5043a2167 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -216,7 +216,7 @@ static void usbdev_vm_close(struct vm_area_struct *vma)
 	dec_usb_memory_use_count(usbm, &usbm->vma_use_count);
 }
 
-struct vm_operations_struct usbdev_vm_ops = {
+static struct vm_operations_struct usbdev_vm_ops = {
 	.open = usbdev_vm_open,
 	.close = usbdev_vm_close
 };
@@ -1316,10 +1316,11 @@ static int proc_getdriver(struct usb_dev_state *ps, void __user *arg)
 
 static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg)
 {
-	struct usbdevfs_connectinfo ci = {
-		.devnum = ps->dev->devnum,
-		.slow = ps->dev->speed == USB_SPEED_LOW
-	};
+	struct usbdevfs_connectinfo ci;
+
+	memset(&ci, 0, sizeof(ci));
+	ci.devnum = ps->dev->devnum;
+	ci.slow = ps->dev->speed == USB_SPEED_LOW;
 
 	if (copy_to_user(arg, &ci, sizeof(ci)))
 		return -EFAULT;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 2057d91d8336..dadd1e8dfe09 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -284,7 +284,7 @@ static int usb_probe_interface(struct device *dev)
 	struct usb_device *udev = interface_to_usbdev(intf);
 	const struct usb_device_id *id;
 	int error = -ENODEV;
-	int lpm_disable_error;
+	int lpm_disable_error = -ENODEV;
 
 	dev_dbg(dev, "%s\n", __func__);
 
@@ -336,12 +336,14 @@ static int usb_probe_interface(struct device *dev)
 	 * setting during probe, that should also be fine.  usb_set_interface()
 	 * will attempt to disable LPM, and fail if it can't disable it.
 	 */
-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
-	if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
-		dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
-				__func__, driver->name);
-		error = lpm_disable_error;
-		goto err;
+	if (driver->disable_hub_initiated_lpm) {
+		lpm_disable_error = usb_unlocked_disable_lpm(udev);
+		if (lpm_disable_error) {
+			dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
+					__func__, driver->name);
+			error = lpm_disable_error;
+			goto err;
+		}
 	}
 
 	/* Carry out a deferred switch to altsetting 0 */
@@ -391,7 +393,8 @@ static int usb_unbind_interface(struct device *dev)
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct usb_host_endpoint *ep, **eps = NULL;
 	struct usb_device *udev;
-	int i, j, error, r, lpm_disable_error;
+	int i, j, error, r;
+	int lpm_disable_error = -ENODEV;
 
 	intf->condition = USB_INTERFACE_UNBINDING;
 
@@ -399,12 +402,13 @@ static int usb_unbind_interface(struct device *dev)
 	udev = interface_to_usbdev(intf);
 	error = usb_autoresume_device(udev);
 
-	/* Hub-initiated LPM policy may change, so attempt to disable LPM until
+	/* If hub-initiated LPM policy may change, attempt to disable LPM until
 	 * the driver is unbound.  If LPM isn't disabled, that's fine because it
 	 * wouldn't be enabled unless all the bound interfaces supported
 	 * hub-initiated LPM.
 	 */
-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
+	if (driver->disable_hub_initiated_lpm)
+		lpm_disable_error = usb_unlocked_disable_lpm(udev);
 
 	/*
 	 * Terminate all URBs for this interface unless the driver
@@ -505,7 +509,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 	struct device *dev;
 	struct usb_device *udev;
 	int retval = 0;
-	int lpm_disable_error;
+	int lpm_disable_error = -ENODEV;
 
 	if (!iface)
 		return -ENODEV;
@@ -526,12 +530,14 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 
 	iface->condition = USB_INTERFACE_BOUND;
 
-	/* Disable LPM until this driver is bound. */
-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
-	if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
-		dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
-				__func__, driver->name);
-		return -ENOMEM;
+	/* See the comment about disabling LPM in usb_probe_interface(). */
+	if (driver->disable_hub_initiated_lpm) {
+		lpm_disable_error = usb_unlocked_disable_lpm(udev);
+		if (lpm_disable_error) {
+			dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
+					__func__, driver->name);
+			return -ENOMEM;
+		}
 	}
 
 	/* Claimed interfaces are initially inactive (suspended) and
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 2ca2cef7f681..34b837ae1ed7 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -994,7 +994,7 @@ static void usb_bus_init (struct usb_bus *bus)
 	bus->bandwidth_allocated = 0;
 	bus->bandwidth_int_reqs  = 0;
 	bus->bandwidth_isoc_reqs = 0;
-	mutex_init(&bus->usb_address0_mutex);
+	mutex_init(&bus->devnum_next_mutex);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1118,6 +1118,7 @@ static int register_root_hub(struct usb_hcd *hcd)
 		/* Did the HC die before the root hub was registered? */
 		if (HCD_DEAD(hcd))
 			usb_hc_died (hcd);	/* This time clean up */
+		usb_dev->dev.of_node = parent_dev->of_node;
 	}
 	mutex_unlock(&usb_bus_idr_lock);
 
@@ -2521,6 +2522,14 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
 		return NULL;
 	}
 	if (primary_hcd == NULL) {
+		hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex),
+				GFP_KERNEL);
+		if (!hcd->address0_mutex) {
+			kfree(hcd);
+			dev_dbg(dev, "hcd address0 mutex alloc failed\n");
+			return NULL;
+		}
+		mutex_init(hcd->address0_mutex);
 		hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
 				GFP_KERNEL);
 		if (!hcd->bandwidth_mutex) {
@@ -2532,6 +2541,7 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
 		dev_set_drvdata(dev, hcd);
 	} else {
 		mutex_lock(&usb_port_peer_mutex);
+		hcd->address0_mutex = primary_hcd->address0_mutex;
 		hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;
 		hcd->primary_hcd = primary_hcd;
 		primary_hcd->primary_hcd = primary_hcd;
@@ -2598,8 +2608,10 @@ static void hcd_release(struct kref *kref)
 	struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref);
 
 	mutex_lock(&usb_port_peer_mutex);
-	if (usb_hcd_is_primary_hcd(hcd))
+	if (usb_hcd_is_primary_hcd(hcd)) {
+		kfree(hcd->address0_mutex);
 		kfree(hcd->bandwidth_mutex);
+	}
 	if (hcd->shared_hcd) {
 		struct usb_hcd *peer = hcd->shared_hcd;
 
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 38cc4bae0a82..bee13517676f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -104,6 +104,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev);
 
 static inline char *portspeed(struct usb_hub *hub, int portstatus)
 {
+	if (hub_is_superspeedplus(hub->hdev))
+		return "10.0 Gb/s";
 	if (hub_is_superspeed(hub->hdev))
 		return "5.0 Gb/s";
 	if (portstatus & USB_PORT_STAT_HIGH_SPEED)
@@ -2080,7 +2082,7 @@ static void choose_devnum(struct usb_device *udev)
 	struct usb_bus	*bus = udev->bus;
 
 	/* be safe when more hub events are proceed in parallel */
-	mutex_lock(&bus->usb_address0_mutex);
+	mutex_lock(&bus->devnum_next_mutex);
 	if (udev->wusb) {
 		devnum = udev->portnum + 1;
 		BUG_ON(test_bit(devnum, bus->devmap.devicemap));
@@ -2098,7 +2100,7 @@ static void choose_devnum(struct usb_device *udev)
 		set_bit(devnum, bus->devmap.devicemap);
 		udev->devnum = devnum;
 	}
-	mutex_unlock(&bus->usb_address0_mutex);
+	mutex_unlock(&bus->devnum_next_mutex);
 }
 
 static void release_devnum(struct usb_device *udev)
@@ -4364,7 +4366,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
 	if (oldspeed == USB_SPEED_LOW)
 		delay = HUB_LONG_RESET_TIME;
 
-	mutex_lock(&hdev->bus->usb_address0_mutex);
+	mutex_lock(hcd->address0_mutex);
 
 	/* Reset the device; full speed may morph to high speed */
 	/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
@@ -4650,7 +4652,7 @@ fail:
 		hub_port_disable(hub, port1, 0);
 		update_devnum(udev, devnum);	/* for disconnect processing */
 	}
-	mutex_unlock(&hdev->bus->usb_address0_mutex);
+	mutex_unlock(hcd->address0_mutex);
 	return retval;
 }
 
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 8e641b5893ed..ea681f157368 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -302,9 +302,10 @@ static void sg_complete(struct urb *urb)
 		 */
 		spin_unlock(&io->lock);
 		for (i = 0, found = 0; i < io->entries; i++) {
-			if (!io->urbs[i] || !io->urbs[i]->dev)
+			if (!io->urbs[i])
 				continue;
 			if (found) {
+				usb_block_urb(io->urbs[i]);
 				retval = usb_unlink_urb(io->urbs[i]);
 				if (retval != -EINPROGRESS &&
 				    retval != -ENODEV &&
@@ -515,12 +516,10 @@ void usb_sg_wait(struct usb_sg_request *io)
 		int retval;
 
 		io->urbs[i]->dev = io->dev;
-		retval = usb_submit_urb(io->urbs[i], GFP_ATOMIC);
-
-		/* after we submit, let completions or cancellations fire;
-		 * we handshake using io->status.
-		 */
 		spin_unlock_irq(&io->lock);
+
+		retval = usb_submit_urb(io->urbs[i], GFP_NOIO);
+
 		switch (retval) {
 			/* maybe we retrying will recover */
 		case -ENXIO:	/* hc didn't queue this one */
@@ -578,31 +577,28 @@ EXPORT_SYMBOL_GPL(usb_sg_wait);
 void usb_sg_cancel(struct usb_sg_request *io)
 {
 	unsigned long flags;
+	int i, retval;
 
 	spin_lock_irqsave(&io->lock, flags);
+	if (io->status) {
+		spin_unlock_irqrestore(&io->lock, flags);
+		return;
+	}
+	/* shut everything down */
+	io->status = -ECONNRESET;
+	spin_unlock_irqrestore(&io->lock, flags);
 
-	/* shut everything down, if it didn't already */
-	if (!io->status) {
-		int i;
-
-		io->status = -ECONNRESET;
-		spin_unlock(&io->lock);
-		for (i = 0; i < io->entries; i++) {
-			int retval;
+	for (i = io->entries - 1; i >= 0; --i) {
+		usb_block_urb(io->urbs[i]);
 
-			if (!io->urbs[i]->dev)
-				continue;
-			retval = usb_unlink_urb(io->urbs[i]);
-			if (retval != -EINPROGRESS
-					&& retval != -ENODEV
-					&& retval != -EBUSY
-					&& retval != -EIDRM)
-				dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
-					__func__, retval);
-		}
-		spin_lock(&io->lock);
+		retval = usb_unlink_urb(io->urbs[i]);
+		if (retval != -EINPROGRESS
+		    && retval != -ENODEV
+		    && retval != -EBUSY
+		    && retval != -EIDRM)
+			dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
+				 __func__, retval);
 	}
-	spin_unlock_irqrestore(&io->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_sg_cancel);
 
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 479187c32571..5e80697ef952 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -466,7 +466,6 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 		dev->route = 0;
 
 		dev->dev.parent = bus->controller;
-		dev->dev.of_node = bus->controller->of_node;
 		dev_set_name(&dev->dev, "usb%d", bus->busnum);
 		root_hub = 1;
 	} else {
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 818f158232bb..4c5e3005e1dc 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -2425,6 +2425,9 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)
 	u32 gintsts;
 	u32 gintmsk;
 
+	if (!dwc2_is_device_mode(hsotg))
+		return IRQ_NONE;
+
 	spin_lock(&hsotg->lock);
 irq_retry:
 	gintsts = dwc2_readl(hsotg->regs + GINTSTS);
@@ -2631,7 +2634,10 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
 		desc->wMaxPacketSize, desc->bInterval);
 
 	/* not to be called for EP0 */
-	WARN_ON(index == 0);
+	if (index == 0) {
+		dev_err(hsotg->dev, "%s: called for EP 0\n", __func__);
+		return -EINVAL;
+	}
 
 	dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0;
 	if (dir_in != hs_ep->dir_in) {
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 1f6255131857..2df3d04d26f5 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4703,6 +4703,7 @@ fail2:
 	spin_unlock_irqrestore(&hsotg->lock, flags);
 	urb->hcpriv = NULL;
 	kfree(qtd);
+	qtd = NULL;
 fail1:
 	if (qh_allocated) {
 		struct dwc2_qtd *qtd2, *qtd2_tmp;
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
index 89fa26cb25f4..7758bfb644ff 100644
--- a/drivers/usb/dwc2/hcd.h
+++ b/drivers/usb/dwc2/hcd.h
@@ -552,6 +552,7 @@ static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
 {
 	list_del(&qtd->qtd_list_entry);
 	kfree(qtd);
+	qtd = NULL;
 }
 
 /* Descriptor DMA support functions */
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 7f634fd771c7..b5c7793a2df2 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -1709,7 +1709,8 @@ 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) {
+	if (!hsotg->periodic_qh_count &&
+	    hsotg->core_params->dma_desc_enable <= 0) {
 		intr_mask = dwc2_readl(hsotg->regs + GINTMSK);
 		intr_mask &= ~GINTSTS_SOF;
 		dwc2_writel(intr_mask, hsotg->regs + GINTMSK);
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 88629bed6614..fc6f5251de5d 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -562,7 +562,7 @@ static int dwc2_driver_probe(struct platform_device *dev)
 
 	retval = dwc2_get_dr_mode(hsotg);
 	if (retval)
-		return retval;
+		goto error;
 
 	/*
 	 * Reset before dwc2_get_hwparams() then it could get power-on real
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 34277ced26bd..a590cd225bb7 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -60,6 +60,20 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 	dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 }
 
+u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
+{
+	struct dwc3		*dwc = dep->dwc;
+	u32			reg;
+
+	dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE,
+			DWC3_GDBGFIFOSPACE_NUM(dep->number) |
+			DWC3_GDBGFIFOSPACE_TYPE(type));
+
+	reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE);
+
+	return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg);
+}
+
 /**
  * dwc3_core_soft_reset - Issues core soft reset and PHY reset
  * @dwc: pointer to our context structure
@@ -203,13 +217,10 @@ static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
 static void dwc3_free_event_buffers(struct dwc3 *dwc)
 {
 	struct dwc3_event_buffer	*evt;
-	int i;
 
-	for (i = 0; i < dwc->num_event_buffers; i++) {
-		evt = dwc->ev_buffs[i];
-		if (evt)
-			dwc3_free_one_event_buffer(dwc, evt);
-	}
+	evt = dwc->ev_buf;
+	if (evt)
+		dwc3_free_one_event_buffer(dwc, evt);
 }
 
 /**
@@ -222,27 +233,14 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
  */
 static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
 {
-	int			num;
-	int			i;
-
-	num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
-	dwc->num_event_buffers = num;
-
-	dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
-			GFP_KERNEL);
-	if (!dwc->ev_buffs)
-		return -ENOMEM;
-
-	for (i = 0; i < num; i++) {
-		struct dwc3_event_buffer	*evt;
+	struct dwc3_event_buffer *evt;
 
-		evt = dwc3_alloc_one_event_buffer(dwc, length);
-		if (IS_ERR(evt)) {
-			dev_err(dwc->dev, "can't allocate event buffer\n");
-			return PTR_ERR(evt);
-		}
-		dwc->ev_buffs[i] = evt;
+	evt = dwc3_alloc_one_event_buffer(dwc, length);
+	if (IS_ERR(evt)) {
+		dev_err(dwc->dev, "can't allocate event buffer\n");
+		return PTR_ERR(evt);
 	}
+	dwc->ev_buf = evt;
 
 	return 0;
 }
@@ -256,25 +254,22 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
 static int dwc3_event_buffers_setup(struct dwc3 *dwc)
 {
 	struct dwc3_event_buffer	*evt;
-	int				n;
 
-	for (n = 0; n < dwc->num_event_buffers; n++) {
-		evt = dwc->ev_buffs[n];
-		dwc3_trace(trace_dwc3_core,
-				"Event buf %p dma %08llx length %d\n",
-				evt->buf, (unsigned long long) evt->dma,
-				evt->length);
-
-		evt->lpos = 0;
-
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
-				lower_32_bits(evt->dma));
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
-				upper_32_bits(evt->dma));
-		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
-				DWC3_GEVNTSIZ_SIZE(evt->length));
-		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
-	}
+	evt = dwc->ev_buf;
+	dwc3_trace(trace_dwc3_core,
+			"Event buf %p dma %08llx length %d\n",
+			evt->buf, (unsigned long long) evt->dma,
+			evt->length);
+
+	evt->lpos = 0;
+
+	dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0),
+			lower_32_bits(evt->dma));
+	dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0),
+			upper_32_bits(evt->dma));
+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
+			DWC3_GEVNTSIZ_SIZE(evt->length));
+	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
 
 	return 0;
 }
@@ -282,19 +277,16 @@ static int dwc3_event_buffers_setup(struct dwc3 *dwc)
 static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
 {
 	struct dwc3_event_buffer	*evt;
-	int				n;
 
-	for (n = 0; n < dwc->num_event_buffers; n++) {
-		evt = dwc->ev_buffs[n];
+	evt = dwc->ev_buf;
 
-		evt->lpos = 0;
+	evt->lpos = 0;
 
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
-		dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
-		dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), DWC3_GEVNTSIZ_INTMASK
-				| DWC3_GEVNTSIZ_SIZE(0));
-		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
-	}
+	dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0);
+	dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0);
+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK
+			| DWC3_GEVNTSIZ_SIZE(0));
+	dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0);
 }
 
 static int dwc3_alloc_scratch_buffers(struct dwc3 *dwc)
@@ -434,6 +426,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
 	if (dwc->u2ss_inp3_quirk)
 		reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
 
+	if (dwc->dis_rxdet_inp3_quirk)
+		reg |= DWC3_GUSB3PIPECTL_DISRXDETINP3;
+
 	if (dwc->req_p1p2p3_quirk)
 		reg |= DWC3_GUSB3PIPECTL_REQP1P2P3;
 
@@ -882,9 +877,6 @@ static int dwc3_probe(struct platform_device *pdev)
 	dwc->usb3_lpm_capable = device_property_read_bool(dev,
 				"snps,usb3_lpm_capable");
 
-	dwc->needs_fifo_resize = device_property_read_bool(dev,
-				"tx-fifo-resize");
-
 	dwc->disable_scramble_quirk = device_property_read_bool(dev,
 				"snps,disable_scramble_quirk");
 	dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
@@ -907,6 +899,8 @@ static int dwc3_probe(struct platform_device *pdev)
 				"snps,dis_u2_susphy_quirk");
 	dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
 				"snps,dis_enblslpm_quirk");
+	dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
+				"snps,dis_rxdet_inp3_quirk");
 
 	dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
 				"snps,tx_de_emphasis_quirk");
@@ -926,7 +920,6 @@ static int dwc3_probe(struct platform_device *pdev)
 		if (pdata->hird_threshold)
 			hird_threshold = pdata->hird_threshold;
 
-		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
 		dwc->usb3_lpm_capable = pdata->usb3_lpm_capable;
 		dwc->dr_mode = pdata->dr_mode;
 
@@ -941,6 +934,7 @@ static int dwc3_probe(struct platform_device *pdev)
 		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->dis_rxdet_inp3_quirk = pdata->dis_rxdet_inp3_quirk;
 
 		dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
 		if (pdata->tx_de_emphasis)
@@ -1050,19 +1044,11 @@ static int dwc3_probe(struct platform_device *pdev)
 	if (ret)
 		goto err5;
 
-	ret = dwc3_debugfs_init(dwc);
-	if (ret) {
-		dev_err(dev, "failed to initialize debugfs\n");
-		goto err6;
-	}
-
+	dwc3_debugfs_init(dwc);
 	pm_runtime_allow(dev);
 
 	return 0;
 
-err6:
-	dwc3_core_exit_mode(dwc);
-
 err5:
 	dwc3_event_buffers_cleanup(dwc);
 
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 6254b2ff9080..7ddf9449a063 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -152,6 +152,24 @@
 
 /* Bit fields */
 
+/* Global Debug Queue/FIFO Space Available Register */
+#define DWC3_GDBGFIFOSPACE_NUM(n)	((n) & 0x1f)
+#define DWC3_GDBGFIFOSPACE_TYPE(n)	(((n) << 5) & 0x1e0)
+#define DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(n) (((n) >> 16) & 0xffff)
+
+#define DWC3_TXFIFOQ		1
+#define DWC3_RXFIFOQ		3
+#define DWC3_TXREQQ		5
+#define DWC3_RXREQQ		7
+#define DWC3_RXINFOQ		9
+#define DWC3_DESCFETCHQ		13
+#define DWC3_EVENTQ		15
+
+/* Global RX Threshold Configuration Register */
+#define DWC3_GRXTHRCFG_MAXRXBURSTSIZE(n) (((n) & 0x1f) << 19)
+#define DWC3_GRXTHRCFG_RXPKTCNT(n) (((n) & 0xf) << 24)
+#define DWC3_GRXTHRCFG_PKTCNTSEL (1 << 29)
+
 /* Global Configuration Register */
 #define DWC3_GCTL_PWRDNSCALE(n)	((n) << 19)
 #define DWC3_GCTL_U2RSTECN	(1 << 16)
@@ -193,6 +211,7 @@
 /* Global USB3 PIPE Control Register */
 #define DWC3_GUSB3PIPECTL_PHYSOFTRST	(1 << 31)
 #define DWC3_GUSB3PIPECTL_U2SSINP3OK	(1 << 29)
+#define DWC3_GUSB3PIPECTL_DISRXDETINP3	(1 << 28)
 #define DWC3_GUSB3PIPECTL_REQP1P2P3	(1 << 24)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3(n)	((n) << 19)
 #define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK	DWC3_GUSB3PIPECTL_DEP1P2P3(7)
@@ -257,6 +276,9 @@
 #define DWC3_DCFG_LOWSPEED	(2 << 0)
 #define DWC3_DCFG_FULLSPEED1	(3 << 0)
 
+#define DWC3_DCFG_NUMP_SHIFT	17
+#define DWC3_DCFG_NUMP(n)	(((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f)
+#define DWC3_DCFG_NUMP_MASK	(0x1f << DWC3_DCFG_NUMP_SHIFT)
 #define DWC3_DCFG_LPM_CAP	(1 << 22)
 
 /* Device Control Register */
@@ -438,18 +460,17 @@ struct dwc3_event_buffer {
 #define DWC3_EP_DIRECTION_TX	true
 #define DWC3_EP_DIRECTION_RX	false
 
-#define DWC3_TRB_NUM		32
-#define DWC3_TRB_MASK		(DWC3_TRB_NUM - 1)
+#define DWC3_TRB_NUM		256
 
 /**
  * struct dwc3_ep - device side endpoint representation
  * @endpoint: usb endpoint
- * @request_list: list of requests for this endpoint
- * @req_queued: list of requests on this ep which have TRBs setup
+ * @pending_list: list of pending requests for this endpoint
+ * @started_list: list of started requests on this endpoint
  * @trb_pool: array of transaction buffers
  * @trb_pool_dma: dma address of @trb_pool
- * @free_slot: next slot which is going to be used
- * @busy_slot: first slot which is owned by HW
+ * @trb_enqueue: enqueue 'pointer' into TRB array
+ * @trb_dequeue: dequeue 'pointer' into TRB array
  * @desc: usb_endpoint_descriptor pointer
  * @dwc: pointer to DWC controller
  * @saved_state: ep state saved during hibernation
@@ -464,13 +485,11 @@ struct dwc3_event_buffer {
  */
 struct dwc3_ep {
 	struct usb_ep		endpoint;
-	struct list_head	request_list;
-	struct list_head	req_queued;
+	struct list_head	pending_list;
+	struct list_head	started_list;
 
 	struct dwc3_trb		*trb_pool;
 	dma_addr_t		trb_pool_dma;
-	u32			free_slot;
-	u32			busy_slot;
 	const struct usb_ss_ep_comp_descriptor *comp_desc;
 	struct dwc3		*dwc;
 
@@ -486,6 +505,18 @@ struct dwc3_ep {
 	/* This last one is specific to EP0 */
 #define DWC3_EP0_DIR_IN		(1 << 31)
 
+	/*
+	 * IMPORTANT: we *know* we have 256 TRBs in our @trb_pool, so we will
+	 * use a u8 type here. If anybody decides to increase number of TRBs to
+	 * anything larger than 256 - I can't see why people would want to do
+	 * this though - then this type needs to be changed.
+	 *
+	 * By using u8 types we ensure that our % operator when incrementing
+	 * enqueue and dequeue get optimized away by the compiler.
+	 */
+	u8			trb_enqueue;
+	u8			trb_dequeue;
+
 	u8			number;
 	u8			type;
 	u8			resource_index;
@@ -557,6 +588,7 @@ enum dwc3_link_state {
 #define DWC3_TRB_CTRL_IOC		(1 << 11)
 #define DWC3_TRB_CTRL_SID_SOFN(n)	(((n) & 0xffff) << 14)
 
+#define DWC3_TRBCTL_TYPE(n)		((n) & (0x3f << 4))
 #define DWC3_TRBCTL_NORMAL		DWC3_TRB_CTRL_TRBCTL(1)
 #define DWC3_TRBCTL_CONTROL_SETUP	DWC3_TRB_CTRL_TRBCTL(2)
 #define DWC3_TRBCTL_CONTROL_STATUS2	DWC3_TRB_CTRL_TRBCTL(3)
@@ -623,19 +655,32 @@ struct dwc3_hwparams {
 /* HWPARAMS7 */
 #define DWC3_RAM1_DEPTH(n)	((n) & 0xffff)
 
+/**
+ * struct dwc3_request - representation of a transfer request
+ * @request: struct usb_request to be transferred
+ * @list: a list_head used for request queueing
+ * @dep: struct dwc3_ep owning this request
+ * @first_trb_index: index to first trb used by this request
+ * @epnum: endpoint number to which this request refers
+ * @trb: pointer to struct dwc3_trb
+ * @trb_dma: DMA address of @trb
+ * @direction: IN or OUT direction flag
+ * @mapped: true when request has been dma-mapped
+ * @queued: true when request has been queued to HW
+ */
 struct dwc3_request {
 	struct usb_request	request;
 	struct list_head	list;
 	struct dwc3_ep		*dep;
-	u32			start_slot;
 
+	u8			first_trb_index;
 	u8			epnum;
 	struct dwc3_trb		*trb;
 	dma_addr_t		trb_dma;
 
 	unsigned		direction:1;
 	unsigned		mapped:1;
-	unsigned		queued:1;
+	unsigned		started:1;
 };
 
 /*
@@ -667,7 +712,6 @@ struct dwc3_scratchpad_array {
  * @regs: base address for our registers
  * @regs_size: address space size
  * @nr_scratch: number of scratch buffers
- * @num_event_buffers: calculated number of event buffers
  * @u1u2: only used on revisions <1.83a for workaround
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
@@ -709,9 +753,7 @@ struct dwc3_scratchpad_array {
  * 	0	- utmi_sleep_n
  * 	1	- utmi_l1_suspend_n
  * @is_fpga: true when we are using the FPGA board
- * @needs_fifo_resize: not all users might want fifo resizing, flag it
  * @pullups_connected: true when Run/Stop bit is set
- * @resize_fifos: tells us it's ok to reconfigure our TxFIFO sizes.
  * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround
  * @start_config_issued: true when StartConfig command has been issued
  * @three_stage_setup: set if we perform a three phase setup
@@ -756,7 +798,7 @@ struct dwc3 {
 	struct platform_device	*xhci;
 	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];
 
-	struct dwc3_event_buffer **ev_buffs;
+	struct dwc3_event_buffer *ev_buf;
 	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
 
 	struct usb_gadget	gadget;
@@ -780,7 +822,6 @@ struct dwc3 {
 	u32			gctl;
 
 	u32			nr_scratch;
-	u32			num_event_buffers;
 	u32			u1u2;
 	u32			maximum_speed;
 
@@ -855,9 +896,7 @@ struct dwc3 {
 	unsigned		has_lpm_erratum:1;
 	unsigned		is_utmi_l1_suspend:1;
 	unsigned		is_fpga:1;
-	unsigned		needs_fifo_resize:1;
 	unsigned		pullups_connected:1;
-	unsigned		resize_fifos:1;
 	unsigned		setup_packet_pending:1;
 	unsigned		three_stage_setup:1;
 	unsigned		usb3_lpm_capable:1;
@@ -873,6 +912,7 @@ struct dwc3 {
 	unsigned		dis_u3_susphy_quirk:1;
 	unsigned		dis_u2_susphy_quirk:1;
 	unsigned		dis_enblslpm_quirk:1;
+	unsigned		dis_rxdet_inp3_quirk:1;
 
 	unsigned		tx_de_emphasis_quirk:1;
 	unsigned		tx_de_emphasis:2;
@@ -938,6 +978,10 @@ struct dwc3_event_depevt {
 #define DEPEVT_STATUS_CONTROL_DATA	1
 #define DEPEVT_STATUS_CONTROL_STATUS	2
 
+/* In response to Start Transfer */
+#define DEPEVT_TRANSFER_NO_RESOURCE	1
+#define DEPEVT_TRANSFER_BUS_EXPIRY	2
+
 	u32	parameters:16;
 } __packed;
 
@@ -1025,7 +1069,7 @@ struct dwc3_gadget_ep_cmd_params {
 
 /* prototypes */
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
-int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
+u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
 
 /* check whether we are on the DWC_usb31 core */
 static inline bool dwc3_is_usb31(struct dwc3 *dwc)
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
index 07fbc2d94fd4..71e318025964 100644
--- a/drivers/usb/dwc3/debug.h
+++ b/drivers/usb/dwc3/debug.h
@@ -217,11 +217,11 @@ static inline const char *dwc3_gadget_event_type_string(u8 event)
 void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);
 
 #ifdef CONFIG_DEBUG_FS
-extern int dwc3_debugfs_init(struct dwc3 *);
+extern void dwc3_debugfs_init(struct dwc3 *);
 extern void dwc3_debugfs_exit(struct dwc3 *);
 #else
-static inline int dwc3_debugfs_init(struct dwc3 *d)
-{  return 0;  }
+static inline void dwc3_debugfs_init(struct dwc3 *d)
+{  }
 static inline void dwc3_debugfs_exit(struct dwc3 *d)
 {  }
 #endif
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index cebf9e38b60a..b1dd3c6d7ef7 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -618,24 +618,323 @@ static const struct file_operations dwc3_link_state_fops = {
 	.release		= single_release,
 };
 
-int dwc3_debugfs_init(struct dwc3 *dwc)
+struct dwc3_ep_file_map {
+	char name[25];
+	int (*show)(struct seq_file *s, void *unused);
+};
+
+static int dwc3_tx_fifo_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_TXFIFOQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_rx_fifo_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_RXFIFOQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_event_queue_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	u32			val;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
+	seq_printf(s, "%u\n", val);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static int dwc3_ep_transfer_type_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	if (!(dep->flags & DWC3_EP_ENABLED) ||
+			!dep->endpoint.desc) {
+		seq_printf(s, "--\n");
+		goto out;
+	}
+
+	switch (usb_endpoint_type(dep->endpoint.desc)) {
+	case USB_ENDPOINT_XFER_CONTROL:
+		seq_printf(s, "control\n");
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		seq_printf(s, "isochronous\n");
+		break;
+	case USB_ENDPOINT_XFER_BULK:
+		seq_printf(s, "bulk\n");
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		seq_printf(s, "interrupt\n");
+		break;
+	default:
+		seq_printf(s, "--\n");
+	}
+
+out:
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static inline const char *dwc3_trb_type_string(struct dwc3_trb *trb)
+{
+	switch (DWC3_TRBCTL_TYPE(trb->ctrl)) {
+	case DWC3_TRBCTL_NORMAL:
+		return "normal";
+	case DWC3_TRBCTL_CONTROL_SETUP:
+		return "control-setup";
+	case DWC3_TRBCTL_CONTROL_STATUS2:
+		return "control-status2";
+	case DWC3_TRBCTL_CONTROL_STATUS3:
+		return "control-status3";
+	case DWC3_TRBCTL_CONTROL_DATA:
+		return "control-data";
+	case DWC3_TRBCTL_ISOCHRONOUS_FIRST:
+		return "isoc-first";
+	case DWC3_TRBCTL_ISOCHRONOUS:
+		return "isoc";
+	case DWC3_TRBCTL_LINK_TRB:
+		return "link";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static int dwc3_ep_trb_ring_show(struct seq_file *s, void *unused)
+{
+	struct dwc3_ep		*dep = s->private;
+	struct dwc3		*dwc = dep->dwc;
+	unsigned long		flags;
+	int			i;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	if (dep->number <= 1) {
+		seq_printf(s, "--\n");
+		goto out;
+	}
+
+	seq_printf(s, "enqueue pointer %d\n", dep->trb_enqueue);
+	seq_printf(s, "dequeue pointer %d\n", dep->trb_dequeue);
+	seq_printf(s, "\n--------------------------------------------------\n\n");
+	seq_printf(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
+
+	for (i = 0; i < DWC3_TRB_NUM; i++) {
+		struct dwc3_trb *trb = &dep->trb_pool[i];
+
+		seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d\n",
+				trb->bph, trb->bpl, trb->size,
+				dwc3_trb_type_string(trb),
+				!!(trb->ctrl & DWC3_TRB_CTRL_IOC),
+				!!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
+				!!(trb->ctrl & DWC3_TRB_CTRL_CSP),
+				!!(trb->ctrl & DWC3_TRB_CTRL_CHN),
+				!!(trb->ctrl & DWC3_TRB_CTRL_LST),
+				!!(trb->ctrl & DWC3_TRB_CTRL_HWO));
+	}
+
+out:
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+
+static struct dwc3_ep_file_map map[] = {
+	{ "tx_fifo_queue", dwc3_tx_fifo_queue_show, },
+	{ "rx_fifo_queue", dwc3_rx_fifo_queue_show, },
+	{ "tx_request_queue", dwc3_tx_request_queue_show, },
+	{ "rx_request_queue", dwc3_rx_request_queue_show, },
+	{ "rx_info_queue", dwc3_rx_info_queue_show, },
+	{ "descriptor_fetch_queue", dwc3_descriptor_fetch_queue_show, },
+	{ "event_queue", dwc3_event_queue_show, },
+	{ "transfer_type", dwc3_ep_transfer_type_show, },
+	{ "trb_ring", dwc3_ep_trb_ring_show, },
+};
+
+static int dwc3_endpoint_open(struct inode *inode, struct file *file)
+{
+	const char		*file_name = file_dentry(file)->d_iname;
+	struct dwc3_ep_file_map	*f_map;
+	int			i;
+
+	for (i = 0; i < ARRAY_SIZE(map); i++) {
+		f_map = &map[i];
+
+		if (strcmp(f_map->name, file_name) == 0)
+			break;
+	}
+
+	return single_open(file, f_map->show, inode->i_private);
+}
+
+static const struct file_operations dwc3_endpoint_fops = {
+	.open			= dwc3_endpoint_open,
+	.read			= seq_read,
+	.llseek			= seq_lseek,
+	.release		= single_release,
+};
+
+static void dwc3_debugfs_create_endpoint_file(struct dwc3_ep *dep,
+		struct dentry *parent, int type)
 {
-	struct dentry		*root;
 	struct dentry		*file;
-	int			ret;
+	struct dwc3_ep_file_map	*ep_file = &map[type];
 
-	root = debugfs_create_dir(dev_name(dwc->dev), NULL);
-	if (!root) {
-		ret = -ENOMEM;
-		goto err0;
+	file = debugfs_create_file(ep_file->name, S_IRUGO, parent, dep,
+			&dwc3_endpoint_fops);
+}
+
+static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
+		struct dentry *parent)
+{
+	int			i;
+
+	for (i = 0; i < ARRAY_SIZE(map); i++)
+		dwc3_debugfs_create_endpoint_file(dep, parent, i);
+}
+
+static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep,
+		struct dentry *parent)
+{
+	struct dentry		*dir;
+
+	dir = debugfs_create_dir(dep->name, parent);
+	if (IS_ERR_OR_NULL(dir))
+		return;
+
+	dwc3_debugfs_create_endpoint_files(dep, dir);
+}
+
+static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
+		struct dentry *parent)
+{
+	int			i;
+
+	for (i = 0; i < dwc->num_in_eps; i++) {
+		u8		epnum = (i << 1) | 1;
+		struct dwc3_ep	*dep = dwc->eps[epnum];
+
+		if (!dep)
+			continue;
+
+		dwc3_debugfs_create_endpoint_dir(dep, parent);
+	}
+
+	for (i = 0; i < dwc->num_out_eps; i++) {
+		u8		epnum = (i << 1);
+		struct dwc3_ep	*dep = dwc->eps[epnum];
+
+		if (!dep)
+			continue;
+
+		dwc3_debugfs_create_endpoint_dir(dep, parent);
 	}
+}
+
+void dwc3_debugfs_init(struct dwc3 *dwc)
+{
+	struct dentry		*root;
+	struct dentry           *file;
 
+	root = debugfs_create_dir(dev_name(dwc->dev), NULL);
+	if (IS_ERR_OR_NULL(root)) {
+		if (!root)
+			dev_err(dwc->dev, "Can't create debugfs root\n");
+		return;
+	}
 	dwc->root = root;
 
 	dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
 	if (!dwc->regset) {
-		ret = -ENOMEM;
-		goto err1;
+		debugfs_remove_recursive(root);
+		return;
 	}
 
 	dwc->regset->regs = dwc3_regs;
@@ -643,47 +942,30 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
 	dwc->regset->base = dwc->regs;
 
 	file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset);
-	if (!file) {
-		ret = -ENOMEM;
-		goto err2;
-	}
+	if (!file)
+		dev_dbg(dwc->dev, "Can't create debugfs regdump\n");
 
 	if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
 		file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
 				dwc, &dwc3_mode_fops);
-		if (!file) {
-			ret = -ENOMEM;
-			goto err2;
-		}
+		if (!file)
+			dev_dbg(dwc->dev, "Can't create debugfs mode\n");
 	}
 
 	if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
 			IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
 		file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
 				dwc, &dwc3_testmode_fops);
-		if (!file) {
-			ret = -ENOMEM;
-			goto err2;
-		}
-
-		file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
-				dwc, &dwc3_link_state_fops);
-		if (!file) {
-			ret = -ENOMEM;
-			goto err2;
-		}
-	}
+		if (!file)
+			dev_dbg(dwc->dev, "Can't create debugfs testmode\n");
 
-	return 0;
+		file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR,
+				root, dwc, &dwc3_link_state_fops);
+		if (!file)
+			dev_dbg(dwc->dev, "Can't create debugfs link_state\n");
 
-err2:
-	kfree(dwc->regset);
-
-err1:
-	debugfs_remove_recursive(root);
-
-err0:
-	return ret;
+		dwc3_debugfs_create_endpoint_dirs(dwc, root);
+	}
 }
 
 void dwc3_debugfs_exit(struct dwc3 *dwc)
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 55da2c7f727f..af264493bbae 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -126,8 +126,6 @@ struct dwc3_omap {
 	u32			debug_offset;
 	u32			irq0_offset;
 
-	u32			dma_status:1;
-
 	struct extcon_dev	*edev;
 	struct notifier_block	vbus_nb;
 	struct notifier_block	id_nb;
@@ -277,9 +275,6 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
 
 	reg = dwc3_omap_read_irqmisc_status(omap);
 
-	if (reg & USBOTGSS_IRQMISC_DMADISABLECLR)
-		omap->dma_status = false;
-
 	dwc3_omap_write_irqmisc_status(omap, reg);
 
 	reg = dwc3_omap_read_irq0_status(omap);
@@ -331,8 +326,6 @@ static void dwc3_omap_disable_irqs(struct dwc3_omap *omap)
 	dwc3_omap_write_irqmisc_clr(omap, reg);
 }
 
-static u64 dwc3_omap_dma_mask = DMA_BIT_MASK(32);
-
 static int dwc3_omap_id_notifier(struct notifier_block *nb,
 	unsigned long event, void *ptr)
 {
@@ -490,7 +483,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
 	omap->irq	= irq;
 	omap->base	= base;
 	omap->vbus_reg	= vbus_reg;
-	dev->dma_mask	= &dwc3_omap_dma_mask;
 
 	pm_runtime_enable(dev);
 	ret = pm_runtime_get_sync(dev);
@@ -504,7 +496,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
 
 	/* check the DMA Status */
 	reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
-	omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE);
 
 	ret = devm_request_irq(dev, omap->irq, dwc3_omap_interrupt, 0,
 			"dwc3-omap", omap);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index adc1e8a624cb..14196cd416b3 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -47,7 +47,7 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
 	{ },
 };
 
-static int dwc3_pci_quirks(struct pci_dev *pdev)
+static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3)
 {
 	if (pdev->vendor == PCI_VENDOR_ID_AMD &&
 	    pdev->device == PCI_DEVICE_ID_AMD_NL_USB) {
@@ -77,8 +77,7 @@ static int dwc3_pci_quirks(struct pci_dev *pdev)
 		pdata.dis_u3_susphy_quirk = true;
 		pdata.dis_u2_susphy_quirk = true;
 
-		return platform_device_add_data(pci_get_drvdata(pdev), &pdata,
-						sizeof(pdata));
+		return platform_device_add_data(dwc3, &pdata, sizeof(pdata));
 	}
 
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
@@ -123,8 +122,7 @@ static int dwc3_pci_quirks(struct pci_dev *pdev)
 		pdata.has_lpm_erratum = true;
 		pdata.dis_enblslpm_quirk = true;
 
-		return platform_device_add_data(pci_get_drvdata(pdev), &pdata,
-						sizeof(pdata));
+		return platform_device_add_data(dwc3, &pdata, sizeof(pdata));
 	}
 
 	return 0;
@@ -169,20 +167,20 @@ static int dwc3_pci_probe(struct pci_dev *pci,
 		return ret;
 	}
 
-	pci_set_drvdata(pci, dwc3);
-	ret = dwc3_pci_quirks(pci);
-	if (ret)
-		goto err;
-
 	dwc3->dev.parent = dev;
 	ACPI_COMPANION_SET(&dwc3->dev, ACPI_COMPANION(dev));
 
+	ret = dwc3_pci_quirks(pci, dwc3);
+	if (ret)
+		goto err;
+
 	ret = platform_device_add(dwc3);
 	if (ret) {
 		dev_err(dev, "failed to register dwc3 device\n");
 		goto err;
 	}
 
+	pci_set_drvdata(pci, dwc3);
 	return 0;
 err:
 	platform_device_put(dwc3);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index eca2e6d8e041..51b52a79dfec 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -70,10 +70,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
 		return 0;
 	}
 
-	trb = &dwc->ep0_trb[dep->free_slot];
+	trb = &dwc->ep0_trb[dep->trb_enqueue];
 
 	if (chain)
-		dep->free_slot++;
+		dep->trb_enqueue++;
 
 	trb->bpl = lower_32_bits(buf_dma);
 	trb->bph = upper_32_bits(buf_dma);
@@ -124,7 +124,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
 	req->request.status	= -EINPROGRESS;
 	req->epnum		= dep->number;
 
-	list_add_tail(&req->list, &dep->request_list);
+	list_add_tail(&req->list, &dep->pending_list);
 
 	/*
 	 * Gadget driver might not be quick enough to queue a request
@@ -240,7 +240,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
 	}
 
 	/* we share one TRB for ep0/1 */
-	if (!list_empty(&dep->request_list)) {
+	if (!list_empty(&dep->pending_list)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -272,10 +272,10 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
 	dep->flags = DWC3_EP_ENABLED;
 	dwc->delayed_status = false;
 
-	if (!list_empty(&dep->request_list)) {
+	if (!list_empty(&dep->pending_list)) {
 		struct dwc3_request	*req;
 
-		req = next_request(&dep->request_list);
+		req = next_request(&dep->pending_list);
 		dwc3_gadget_giveback(dep, req, -ECONNRESET);
 	}
 
@@ -463,8 +463,18 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 			if (!set)
 				return -EINVAL;
 
-			dwc->test_mode_nr = wIndex >> 8;
-			dwc->test_mode = true;
+			switch (wIndex >> 8) {
+			case TEST_J:
+			case TEST_K:
+			case TEST_SE0_NAK:
+			case TEST_PACKET:
+			case TEST_FORCE_EN:
+				dwc->test_mode_nr = wIndex >> 8;
+				dwc->test_mode = true;
+				break;
+			default:
+				return -EINVAL;
+			}
 			break;
 		default:
 			return -EINVAL;
@@ -586,9 +596,6 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 			reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
 			dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-			dwc->resize_fifos = true;
-			dwc3_trace(trace_dwc3_ep0, "resize FIFOs flag SET");
 		}
 		break;
 
@@ -809,7 +816,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 
 	trace_dwc3_complete_trb(ep0, trb);
 
-	r = next_request(&ep0->request_list);
+	r = next_request(&ep0->pending_list);
 	if (!r)
 		return;
 
@@ -848,7 +855,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 			trb++;
 			length = trb->size & DWC3_TRB_SIZE_MASK;
 
-			ep0->free_slot = 0;
+			ep0->trb_enqueue = 0;
 		}
 
 		transfer_size = roundup((ur->length - transfer_size),
@@ -897,8 +904,8 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
 
 	trace_dwc3_complete_trb(dep, trb);
 
-	if (!list_empty(&dep->request_list)) {
-		r = next_request(&dep->request_list);
+	if (!list_empty(&dep->pending_list)) {
+		r = next_request(&dep->pending_list);
 
 		dwc3_gadget_giveback(dep, r, 0);
 	}
@@ -1027,12 +1034,6 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
 
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
-	if (dwc->resize_fifos) {
-		dwc3_trace(trace_dwc3_ep0, "Resizing FIFOs");
-		dwc3_gadget_resize_tx_fifos(dwc);
-		dwc->resize_fifos = 0;
-	}
-
 	WARN_ON(dwc3_ep0_start_control_status(dep));
 }
 
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 8e4a1b195e9b..9a7d0bd15dc3 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -145,90 +145,21 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
 	return -ETIMEDOUT;
 }
 
-/**
- * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
- * @dwc: pointer to our context structure
- *
- * This function will a best effort FIFO allocation in order
- * to improve FIFO usage and throughput, while still allowing
- * us to enable as many endpoints as possible.
- *
- * Keep in mind that this operation will be highly dependent
- * on the configured size for RAM1 - which contains TxFifo -,
- * the amount of endpoints enabled on coreConsultant tool, and
- * the width of the Master Bus.
- *
- * In the ideal world, we would always be able to satisfy the
- * following equation:
- *
- * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \
- * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes
- *
- * Unfortunately, due to many variables that's not always the case.
- */
-int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
+static void dwc3_ep_inc_enq(struct dwc3_ep *dep)
 {
-	int		last_fifo_depth = 0;
-	int		ram1_depth;
-	int		fifo_size;
-	int		mdwidth;
-	int		num;
-
-	if (!dwc->needs_fifo_resize)
-		return 0;
-
-	ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
-	mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
-
-	/* MDWIDTH is represented in bits, we need it in bytes */
-	mdwidth >>= 3;
-
-	/*
-	 * FIXME For now we will only allocate 1 wMaxPacketSize space
-	 * for each enabled endpoint, later patches will come to
-	 * improve this algorithm so that we better use the internal
-	 * FIFO space
-	 */
-	for (num = 0; num < dwc->num_in_eps; num++) {
-		/* bit0 indicates direction; 1 means IN ep */
-		struct dwc3_ep	*dep = dwc->eps[(num << 1) | 1];
-		int		mult = 1;
-		int		tmp;
-
-		if (!(dep->flags & DWC3_EP_ENABLED))
-			continue;
-
-		if (usb_endpoint_xfer_bulk(dep->endpoint.desc)
-				|| usb_endpoint_xfer_isoc(dep->endpoint.desc))
-			mult = 3;
-
-		/*
-		 * REVISIT: the following assumes we will always have enough
-		 * space available on the FIFO RAM for all possible use cases.
-		 * Make sure that's true somehow and change FIFO allocation
-		 * accordingly.
-		 *
-		 * If we have Bulk or Isochronous endpoints, we want
-		 * them to be able to be very, very fast. So we're giving
-		 * those endpoints a fifo_size which is enough for 3 full
-		 * packets
-		 */
-		tmp = mult * (dep->endpoint.maxpacket + mdwidth);
-		tmp += mdwidth;
-
-		fifo_size = DIV_ROUND_UP(tmp, mdwidth);
-
-		fifo_size |= (last_fifo_depth << 16);
-
-		dwc3_trace(trace_dwc3_gadget, "%s: Fifo Addr %04x Size %d",
-				dep->name, last_fifo_depth, fifo_size & 0xffff);
-
-		dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size);
+	dep->trb_enqueue++;
+	dep->trb_enqueue %= DWC3_TRB_NUM;
+}
 
-		last_fifo_depth += (fifo_size & 0xffff);
-	}
+static void dwc3_ep_inc_deq(struct dwc3_ep *dep)
+{
+	dep->trb_dequeue++;
+	dep->trb_dequeue %= DWC3_TRB_NUM;
+}
 
-	return 0;
+static int dwc3_ep_is_last_trb(unsigned int index)
+{
+	return index == DWC3_TRB_NUM - 1;
 }
 
 void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
@@ -237,21 +168,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	struct dwc3			*dwc = dep->dwc;
 	int				i;
 
-	if (req->queued) {
+	if (req->started) {
 		i = 0;
 		do {
-			dep->busy_slot++;
+			dwc3_ep_inc_deq(dep);
 			/*
 			 * Skip LINK TRB. We can't use req->trb and check for
 			 * DWC3_TRBCTL_LINK_TRB because it points the TRB we
 			 * just completed (not the LINK TRB).
 			 */
-			if (((dep->busy_slot & DWC3_TRB_MASK) ==
-				DWC3_TRB_NUM- 1) &&
-				usb_endpoint_xfer_isoc(dep->endpoint.desc))
-				dep->busy_slot++;
+			if (dwc3_ep_is_last_trb(dep->trb_dequeue))
+				dwc3_ep_inc_deq(dep);
 		} while(++i < req->request.num_mapped_sgs);
-		req->queued = false;
+		req->started = false;
 	}
 	list_del(&req->list);
 	req->trb = NULL;
@@ -307,6 +236,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param)
 	} while (1);
 }
 
+static int __dwc3_gadget_wakeup(struct dwc3 *dwc);
+
 int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
 {
@@ -314,8 +245,40 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 	u32			timeout = 500;
 	u32			reg;
 
+	int			susphy = false;
+	int			ret = -EINVAL;
+
 	trace_dwc3_gadget_ep_cmd(dep, cmd, params);
 
+	/*
+	 * Synopsys Databook 2.60a states, on section 6.3.2.5.[1-8], that if
+	 * we're issuing an endpoint command, we must check if
+	 * GUSB2PHYCFG.SUSPHY bit is set. If it is, then we need to clear it.
+	 *
+	 * We will also set SUSPHY bit to what it was before returning as stated
+	 * by the same section on Synopsys databook.
+	 */
+	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+	if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
+		susphy = true;
+		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+		dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+	}
+
+	if (cmd == DWC3_DEPCMD_STARTTRANSFER) {
+		int		needs_wakeup;
+
+		needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 ||
+				dwc->link_state == DWC3_LINK_STATE_U2 ||
+				dwc->link_state == DWC3_LINK_STATE_U3);
+
+		if (unlikely(needs_wakeup)) {
+			ret = __dwc3_gadget_wakeup(dwc);
+			dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
+					ret);
+		}
+	}
+
 	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
 	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
 	dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
@@ -324,12 +287,40 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 	do {
 		reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep));
 		if (!(reg & DWC3_DEPCMD_CMDACT)) {
+			int cmd_status = DWC3_DEPCMD_STATUS(reg);
+
 			dwc3_trace(trace_dwc3_gadget,
 					"Command Complete --> %d",
-					DWC3_DEPCMD_STATUS(reg));
-			if (DWC3_DEPCMD_STATUS(reg))
-				return -EINVAL;
-			return 0;
+					cmd_status);
+
+			switch (cmd_status) {
+			case 0:
+				ret = 0;
+				break;
+			case DEPEVT_TRANSFER_NO_RESOURCE:
+				dwc3_trace(trace_dwc3_gadget, "%s: no resource available");
+				ret = -EINVAL;
+				break;
+			case DEPEVT_TRANSFER_BUS_EXPIRY:
+				/*
+				 * SW issues START TRANSFER command to
+				 * isochronous ep with future frame interval. If
+				 * future interval time has already passed when
+				 * core receives the command, it will respond
+				 * with an error status of 'Bus Expiry'.
+				 *
+				 * Instead of always returning -EINVAL, let's
+				 * give a hint to the gadget driver that this is
+				 * the case by returning -EAGAIN.
+				 */
+				dwc3_trace(trace_dwc3_gadget, "%s: bus expiry");
+				ret = -EAGAIN;
+				break;
+			default:
+				dev_WARN(dwc->dev, "UNKNOWN cmd status\n");
+			}
+
+			break;
 		}
 
 		/*
@@ -340,11 +331,20 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 		if (!timeout) {
 			dwc3_trace(trace_dwc3_gadget,
 					"Command Timed Out");
-			return -ETIMEDOUT;
+			ret = -ETIMEDOUT;
+			break;
 		}
 
 		udelay(1);
 	} while (1);
+
+	if (unlikely(susphy)) {
+		reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+		reg |= DWC3_GUSB2PHYCFG_SUSPHY;
+		dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+	}
+
+	return ret;
 }
 
 static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
@@ -464,9 +464,19 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
 
 	/* Burst size is only needed in SuperSpeed mode */
 	if (dwc->gadget.speed >= USB_SPEED_SUPER) {
-		u32 burst = dep->endpoint.maxburst - 1;
+		u32 burst = dep->endpoint.maxburst;
+		u32 nump;
+		u32 reg;
+
+		/* update NumP */
+		reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+		nump = DWC3_DCFG_NUMP(reg);
+		nump = max(nump, burst);
+		reg &= ~DWC3_DCFG_NUMP_MASK;
+		reg |= nump << DWC3_DCFG_NUMP_SHIFT;
+		dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
-		params.param0 |= DWC3_DEPCFG_BURST_SIZE(burst);
+		params.param0 |= DWC3_DEPCFG_BURST_SIZE(burst - 1);
 	}
 
 	if (ignore)
@@ -567,10 +577,10 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
 		reg |= DWC3_DALEPENA_EP(dep->number);
 		dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
 
-		if (!usb_endpoint_xfer_isoc(desc))
+		if (usb_endpoint_xfer_control(desc))
 			goto out;
 
-		/* Link TRB for ISOC. The HWO bit is never reset */
+		/* Link TRB. The HWO bit is never reset */
 		trb_st_hw = &dep->trb_pool[0];
 
 		trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1];
@@ -608,19 +618,19 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
 	struct dwc3_request		*req;
 
-	if (!list_empty(&dep->req_queued)) {
+	if (!list_empty(&dep->started_list)) {
 		dwc3_stop_active_transfer(dwc, dep->number, true);
 
 		/* - giveback all requests to gadget driver */
-		while (!list_empty(&dep->req_queued)) {
-			req = next_request(&dep->req_queued);
+		while (!list_empty(&dep->started_list)) {
+			req = next_request(&dep->started_list);
 
 			dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
 		}
 	}
 
-	while (!list_empty(&dep->request_list)) {
-		req = next_request(&dep->request_list);
+	while (!list_empty(&dep->pending_list)) {
+		req = next_request(&dep->pending_list);
 
 		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
 	}
@@ -783,20 +793,19 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 			chain ? " chain" : "");
 
 
-	trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+	trb = &dep->trb_pool[dep->trb_enqueue];
 
 	if (!req->trb) {
-		dwc3_gadget_move_request_queued(req);
+		dwc3_gadget_move_started_request(req);
 		req->trb = trb;
 		req->trb_dma = dwc3_trb_dma_offset(dep, trb);
-		req->start_slot = dep->free_slot & DWC3_TRB_MASK;
+		req->first_trb_index = dep->trb_enqueue;
 	}
 
-	dep->free_slot++;
-	/* Skip the LINK-TRB on ISOC */
-	if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
-			usb_endpoint_xfer_isoc(dep->endpoint.desc))
-		dep->free_slot++;
+	dwc3_ep_inc_enq(dep);
+	/* Skip the LINK-TRB */
+	if (dwc3_ep_is_last_trb(dep->trb_enqueue))
+		dwc3_ep_inc_enq(dep);
 
 	trb->size = DWC3_TRB_SIZE_LENGTH(length);
 	trb->bpl = lower_32_bits(dma);
@@ -812,6 +821,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
 		else
 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
+
+		/* always enable Interrupt on Missed ISOC */
+		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
 		break;
 
 	case USB_ENDPOINT_XFER_BULK:
@@ -826,15 +838,14 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 		BUG();
 	}
 
+	/* always enable Continue on Short Packet */
+	trb->ctrl |= DWC3_TRB_CTRL_CSP;
+
 	if (!req->request.no_interrupt && !chain)
-		trb->ctrl |= DWC3_TRB_CTRL_IOC;
+		trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI;
 
-	if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
-		trb->ctrl |= DWC3_TRB_CTRL_CSP;
-	} else if (last) {
+	if (last)
 		trb->ctrl |= DWC3_TRB_CTRL_LST;
-	}
 
 	if (chain)
 		trb->ctrl |= DWC3_TRB_CTRL_CHN;
@@ -860,55 +871,29 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 {
 	struct dwc3_request	*req, *n;
 	u32			trbs_left;
-	u32			max;
 	unsigned int		last_one = 0;
 
 	BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
 
-	/* the first request must not be queued */
-	trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
-
-	/* Can't wrap around on a non-isoc EP since there's no link TRB */
-	if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-		max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK);
-		if (trbs_left > max)
-			trbs_left = max;
-	}
+	trbs_left = dep->trb_dequeue - dep->trb_enqueue;
 
 	/*
-	 * If busy & slot are equal than it is either full or empty. If we are
-	 * starting to process requests then we are empty. Otherwise we are
+	 * If enqueue & dequeue are equal than it is either full or empty. If we
+	 * are starting to process requests then we are empty. Otherwise we are
 	 * full and don't do anything
 	 */
 	if (!trbs_left) {
 		if (!starting)
 			return;
+
 		trbs_left = DWC3_TRB_NUM;
-		/*
-		 * In case we start from scratch, we queue the ISOC requests
-		 * starting from slot 1. This is done because we use ring
-		 * buffer and have no LST bit to stop us. Instead, we place
-		 * IOC bit every TRB_NUM/4. We try to avoid having an interrupt
-		 * after the first request so we start at slot 1 and have
-		 * 7 requests proceed before we hit the first IOC.
-		 * Other transfer types don't use the ring buffer and are
-		 * processed from the first TRB until the last one. Since we
-		 * don't wrap around we have to start at the beginning.
-		 */
-		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-			dep->busy_slot = 1;
-			dep->free_slot = 1;
-		} else {
-			dep->busy_slot = 0;
-			dep->free_slot = 0;
-		}
 	}
 
 	/* The last TRB is a link TRB, not used for xfer */
-	if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc))
+	if (trbs_left <= 1)
 		return;
 
-	list_for_each_entry_safe(req, n, &dep->request_list, list) {
+	list_for_each_entry_safe(req, n, &dep->pending_list, list) {
 		unsigned	length;
 		dma_addr_t	dma;
 		last_one = false;
@@ -927,7 +912,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 
 				if (i == (request->num_mapped_sgs - 1) ||
 						sg_is_last(s)) {
-					if (list_empty(&dep->request_list))
+					if (list_empty(&dep->pending_list))
 						last_one = true;
 					chain = false;
 				}
@@ -957,7 +942,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 				last_one = 1;
 
 			/* Is this the last request? */
-			if (list_is_last(&req->list, &dep->request_list))
+			if (list_is_last(&req->list, &dep->pending_list))
 				last_one = 1;
 
 			dwc3_prepare_one_trb(dep, req, dma, length,
@@ -988,18 +973,18 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
 	 * new requests as we try to set the IOC bit only on the last request.
 	 */
 	if (start_new) {
-		if (list_empty(&dep->req_queued))
+		if (list_empty(&dep->started_list))
 			dwc3_prepare_trbs(dep, start_new);
 
 		/* req points to the first request which will be sent */
-		req = next_request(&dep->req_queued);
+		req = next_request(&dep->started_list);
 	} else {
 		dwc3_prepare_trbs(dep, start_new);
 
 		/*
 		 * req points to the first request where HWO changed from 0 to 1
 		 */
-		req = next_request(&dep->req_queued);
+		req = next_request(&dep->started_list);
 	}
 	if (!req) {
 		dep->flags |= DWC3_EP_PENDING_REQUEST;
@@ -1046,7 +1031,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc,
 {
 	u32 uf;
 
-	if (list_empty(&dep->request_list)) {
+	if (list_empty(&dep->pending_list)) {
 		dwc3_trace(trace_dwc3_gadget,
 				"ISOC ep %s run out for requests",
 				dep->name);
@@ -1114,7 +1099,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 	if (ret)
 		return ret;
 
-	list_add_tail(&req->list, &dep->request_list);
+	list_add_tail(&req->list, &dep->pending_list);
 
 	/*
 	 * If there are no pending requests and the endpoint isn't already
@@ -1149,7 +1134,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 		 * notion of current microframe.
 		 */
 		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-			if (list_empty(&dep->req_queued)) {
+			if (list_empty(&dep->started_list)) {
 				dwc3_stop_active_transfer(dwc, dep->number, true);
 				dep->flags = DWC3_EP_ENABLED;
 			}
@@ -1267,13 +1252,13 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
 
 	spin_lock_irqsave(&dwc->lock, flags);
 
-	list_for_each_entry(r, &dep->request_list, list) {
+	list_for_each_entry(r, &dep->pending_list, list) {
 		if (r == req)
 			break;
 	}
 
 	if (r != req) {
-		list_for_each_entry(r, &dep->req_queued, list) {
+		list_for_each_entry(r, &dep->started_list, list) {
 			if (r == req)
 				break;
 		}
@@ -1313,10 +1298,10 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
 
 	if (value) {
 		if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) ||
-				(!list_empty(&dep->req_queued) ||
-				 !list_empty(&dep->request_list)))) {
+				(!list_empty(&dep->started_list) ||
+				 !list_empty(&dep->pending_list)))) {
 			dwc3_trace(trace_dwc3_gadget,
-					"%s: pending request, cannot halt\n",
+					"%s: pending request, cannot halt",
 					dep->name);
 			return -EAGAIN;
 		}
@@ -1417,22 +1402,16 @@ static int dwc3_gadget_get_frame(struct usb_gadget *g)
 	return DWC3_DSTS_SOFFN(reg);
 }
 
-static int dwc3_gadget_wakeup(struct usb_gadget *g)
+static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
 {
-	struct dwc3		*dwc = gadget_to_dwc(g);
-
 	unsigned long		timeout;
-	unsigned long		flags;
 
+	int			ret;
 	u32			reg;
 
-	int			ret = 0;
-
 	u8			link_state;
 	u8			speed;
 
-	spin_lock_irqsave(&dwc->lock, flags);
-
 	/*
 	 * According to the Databook Remote wakeup request should
 	 * be issued only when the device is in early suspend state.
@@ -1445,8 +1424,7 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
 	if ((speed == DWC3_DSTS_SUPERSPEED) ||
 	    (speed == DWC3_DSTS_SUPERSPEED_PLUS)) {
 		dwc3_trace(trace_dwc3_gadget, "no wakeup on SuperSpeed\n");
-		ret = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
 	link_state = DWC3_DSTS_USBLNKST(reg);
@@ -1459,14 +1437,13 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
 		dwc3_trace(trace_dwc3_gadget,
 				"can't wakeup from '%s'\n",
 				dwc3_gadget_link_string(link_state));
-		ret = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
 	ret = dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RECOV);
 	if (ret < 0) {
 		dev_err(dwc->dev, "failed to put link in Recovery\n");
-		goto out;
+		return ret;
 	}
 
 	/* Recent versions do this automatically */
@@ -1490,10 +1467,20 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
 
 	if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) {
 		dev_err(dwc->dev, "failed to send remote wakeup\n");
-		ret = -EINVAL;
+		return -EINVAL;
 	}
 
-out:
+	return 0;
+}
+
+static int dwc3_gadget_wakeup(struct usb_gadget *g)
+{
+	struct dwc3		*dwc = gadget_to_dwc(g);
+	unsigned long		flags;
+	int			ret;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	ret = __dwc3_gadget_wakeup(dwc);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return ret;
@@ -1620,7 +1607,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 
 	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
 	ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
-			IRQF_SHARED, "dwc3", dwc);
+			IRQF_SHARED, "dwc3", dwc->ev_buf);
 	if (ret) {
 		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
 				irq, ret);
@@ -1682,6 +1669,17 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 	}
 	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
 
+	/*
+	 * We are telling dwc3 that we want to use DCFG.NUMP as ACK TP's NUMP
+	 * field instead of letting dwc3 itself calculate that automatically.
+	 *
+	 * This way, we maximize the chances that we'll be able to get several
+	 * bursts of data without going through any sort of endpoint throttling.
+	 */
+	reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
+	reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL;
+	dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
+
 	/* Start with SuperSpeed Default */
 	dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 
@@ -1720,7 +1718,7 @@ err2:
 err1:
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-	free_irq(irq, dwc);
+	free_irq(irq, dwc->ev_buf);
 
 err0:
 	return ret;
@@ -1743,7 +1741,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-	free_irq(irq, dwc);
+	free_irq(irq, dwc->ev_buf);
 
 	return 0;
 }
@@ -1815,8 +1813,8 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
 		dep->endpoint.caps.dir_in = !!direction;
 		dep->endpoint.caps.dir_out = !direction;
 
-		INIT_LIST_HEAD(&dep->request_list);
-		INIT_LIST_HEAD(&dep->req_queued);
+		INIT_LIST_HEAD(&dep->pending_list);
+		INIT_LIST_HEAD(&dep->started_list);
 	}
 
 	return 0;
@@ -1913,11 +1911,11 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
 				 * If there are still queued request
 				 * then wait, do not issue either END
 				 * or UPDATE TRANSFER, just attach next
-				 * request in request_list during
+				 * request in pending_list during
 				 * giveback.If any future queued request
 				 * is successfully transferred then we
 				 * will issue UPDATE TRANSFER for all
-				 * request in the request_list.
+				 * request in the pending_list.
 				 */
 				dep->flags |= DWC3_EP_MISSED_ISOC;
 			} else {
@@ -1963,15 +1961,14 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
 	int			ret;
 
 	do {
-		req = next_request(&dep->req_queued);
+		req = next_request(&dep->started_list);
 		if (WARN_ON_ONCE(!req))
 			return 1;
 
 		i = 0;
 		do {
-			slot = req->start_slot + i;
-			if ((slot == DWC3_TRB_NUM - 1) &&
-				usb_endpoint_xfer_isoc(dep->endpoint.desc))
+			slot = req->first_trb_index + i;
+			if (slot == DWC3_TRB_NUM - 1)
 				slot++;
 			slot %= DWC3_TRB_NUM;
 			trb = &dep->trb_pool[slot];
@@ -1989,8 +1986,8 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
 	} while (1);
 
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
-			list_empty(&dep->req_queued)) {
-		if (list_empty(&dep->request_list)) {
+			list_empty(&dep->started_list)) {
+		if (list_empty(&dep->pending_list)) {
 			/*
 			 * If there is no entry in request list then do
 			 * not issue END TRANSFER now. Just set PENDING
@@ -2039,7 +2036,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
 			if (!(dep->flags & DWC3_EP_ENABLED))
 				continue;
 
-			if (!list_empty(&dep->req_queued))
+			if (!list_empty(&dep->started_list))
 				return;
 		}
 
@@ -2686,14 +2683,13 @@ static void dwc3_process_event_entry(struct dwc3 *dwc,
 	}
 }
 
-static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
+static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
 {
-	struct dwc3_event_buffer *evt;
+	struct dwc3 *dwc = evt->dwc;
 	irqreturn_t ret = IRQ_NONE;
 	int left;
 	u32 reg;
 
-	evt = dwc->ev_buffs[buf];
 	left = evt->count;
 
 	if (!(evt->flags & DWC3_EVENT_PENDING))
@@ -2718,7 +2714,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
 		evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;
 		left -= 4;
 
-		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);
+		dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 4);
 	}
 
 	evt->count = 0;
@@ -2726,39 +2722,34 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
 	ret = IRQ_HANDLED;
 
 	/* Unmask interrupt */
-	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
+	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
 	reg &= ~DWC3_GEVNTSIZ_INTMASK;
-	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
 
 	return ret;
 }
 
-static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc)
+static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt)
 {
-	struct dwc3 *dwc = _dwc;
+	struct dwc3_event_buffer *evt = _evt;
+	struct dwc3 *dwc = evt->dwc;
 	unsigned long flags;
 	irqreturn_t ret = IRQ_NONE;
-	int i;
 
 	spin_lock_irqsave(&dwc->lock, flags);
-
-	for (i = 0; i < dwc->num_event_buffers; i++)
-		ret |= dwc3_process_event_buf(dwc, i);
-
+	ret = dwc3_process_event_buf(evt);
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return ret;
 }
 
-static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
+static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
 {
-	struct dwc3_event_buffer *evt;
+	struct dwc3 *dwc = evt->dwc;
 	u32 count;
 	u32 reg;
 
-	evt = dwc->ev_buffs[buf];
-
-	count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
+	count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
 	count &= DWC3_GEVNTCOUNT_MASK;
 	if (!count)
 		return IRQ_NONE;
@@ -2767,28 +2758,18 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3 *dwc, u32 buf)
 	evt->flags |= DWC3_EVENT_PENDING;
 
 	/* Mask interrupt */
-	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf));
+	reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(0));
 	reg |= DWC3_GEVNTSIZ_INTMASK;
-	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg);
+	dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), reg);
 
 	return IRQ_WAKE_THREAD;
 }
 
-static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
+static irqreturn_t dwc3_interrupt(int irq, void *_evt)
 {
-	struct dwc3			*dwc = _dwc;
-	int				i;
-	irqreturn_t			ret = IRQ_NONE;
-
-	for (i = 0; i < dwc->num_event_buffers; i++) {
-		irqreturn_t status;
+	struct dwc3_event_buffer	*evt = _evt;
 
-		status = dwc3_check_event_buf(dwc, i);
-		if (status == IRQ_WAKE_THREAD)
-			ret = status;
-	}
-
-	return ret;
+	return dwc3_check_event_buf(evt);
 }
 
 /**
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 18ae3eaa8b6f..f21c0fccbebd 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -68,12 +68,12 @@ static inline struct dwc3_request *next_request(struct list_head *list)
 	return list_first_entry(list, struct dwc3_request, list);
 }
 
-static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
+static inline void dwc3_gadget_move_started_request(struct dwc3_request *req)
 {
 	struct dwc3_ep		*dep = req->dep;
 
-	req->queued = true;
-	list_move_tail(&req->list, &dep->req_queued);
+	req->started = true;
+	list_move_tail(&req->list, &dep->started_list);
 }
 
 void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index 2bb4d3ad0e6b..8826cca5fc6f 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -23,7 +23,6 @@
 struct dwc3_platform_data {
 	enum usb_device_speed maximum_speed;
 	enum usb_dr_mode dr_mode;
-	bool tx_fifo_resize;
 	bool usb3_lpm_capable;
 
 	unsigned is_utmi_l1_suspend:1;
@@ -43,6 +42,7 @@ struct dwc3_platform_data {
 	unsigned dis_u3_susphy_quirk:1;
 	unsigned dis_u2_susphy_quirk:1;
 	unsigned dis_enblslpm_quirk:1;
+	unsigned dis_rxdet_inp3_quirk:1;
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index af5d922a8f5d..2057add439f0 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -15,6 +15,7 @@
 
 menuconfig USB_GADGET
 	tristate "USB Gadget Support"
+	select USB_COMMON
 	select NLS
 	help
 	   USB is a master/slave protocol, organized with one master
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 524e233d48de..d67de0d22a2b 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -66,20 +66,36 @@ function_descriptors(struct usb_function *f,
 {
 	struct usb_descriptor_header **descriptors;
 
+	/*
+	 * NOTE: we try to help gadget drivers which might not be setting
+	 * max_speed appropriately.
+	 */
+
 	switch (speed) {
 	case USB_SPEED_SUPER_PLUS:
 		descriptors = f->ssp_descriptors;
-		break;
+		if (descriptors)
+			break;
+		/* FALLTHROUGH */
 	case USB_SPEED_SUPER:
 		descriptors = f->ss_descriptors;
-		break;
+		if (descriptors)
+			break;
+		/* FALLTHROUGH */
 	case USB_SPEED_HIGH:
 		descriptors = f->hs_descriptors;
-		break;
+		if (descriptors)
+			break;
+		/* FALLTHROUGH */
 	default:
 		descriptors = f->fs_descriptors;
 	}
 
+	/*
+	 * if we can't find any descriptors at all, then this gadget deserves to
+	 * Oops with a NULL pointer dereference
+	 */
+
 	return descriptors;
 }
 
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 15b648cbc75c..73515d54e1cc 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -651,7 +651,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
 	if (io_data->read && ret > 0) {
 		use_mm(io_data->mm);
 		ret = copy_to_iter(io_data->buf, ret, &io_data->data);
-		if (iov_iter_count(&io_data->data))
+		if (ret != io_data->req->actual && iov_iter_count(&io_data->data))
 			ret = -EFAULT;
 		unuse_mm(io_data->mm);
 	}
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index acf210f16328..5c6d4d7ca605 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -2977,25 +2977,6 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
 }
 EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string);
 
-int fsg_common_run_thread(struct fsg_common *common)
-{
-	common->state = FSG_STATE_IDLE;
-	/* Tell the thread to start working */
-	common->thread_task =
-		kthread_create(fsg_main_thread, common, "file-storage");
-	if (IS_ERR(common->thread_task)) {
-		common->state = FSG_STATE_TERMINATED;
-		return PTR_ERR(common->thread_task);
-	}
-
-	DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
-
-	wake_up_process(common->thread_task);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(fsg_common_run_thread);
-
 static void fsg_common_release(struct kref *ref)
 {
 	struct fsg_common *common = container_of(ref, struct fsg_common, ref);
@@ -3005,6 +2986,7 @@ static void fsg_common_release(struct kref *ref)
 	if (common->state != FSG_STATE_TERMINATED) {
 		raise_exception(common, FSG_STATE_EXIT);
 		wait_for_completion(&common->thread_notifier);
+		common->thread_task = NULL;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
@@ -3050,9 +3032,21 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
 		if (ret)
 			return ret;
 		fsg_common_set_inquiry_string(fsg->common, NULL, NULL);
-		ret = fsg_common_run_thread(fsg->common);
-		if (ret)
+	}
+
+	if (!common->thread_task) {
+		common->state = FSG_STATE_IDLE;
+		common->thread_task =
+			kthread_create(fsg_main_thread, common, "file-storage");
+		if (IS_ERR(common->thread_task)) {
+			int ret = PTR_ERR(common->thread_task);
+			common->thread_task = NULL;
+			common->state = FSG_STATE_TERMINATED;
 			return ret;
+		}
+		DBG(common, "I/O thread pid: %d\n",
+		    task_pid_nr(common->thread_task));
+		wake_up_process(common->thread_task);
 	}
 
 	fsg->gadget = gadget;
diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h
index 445df6775609..b6a9918eaefb 100644
--- a/drivers/usb/gadget/function/f_mass_storage.h
+++ b/drivers/usb/gadget/function/f_mass_storage.h
@@ -153,8 +153,6 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
 void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
 				   const char *pn);
 
-int fsg_common_run_thread(struct fsg_common *common);
-
 void fsg_config_from_params(struct fsg_config *cfg,
 			    const struct fsg_module_parameters *params,
 			    unsigned int fsg_num_buffers);
diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c
index c16089efc322..c39de65a448b 100644
--- a/drivers/usb/gadget/legacy/acm_ms.c
+++ b/drivers/usb/gadget/legacy/acm_ms.c
@@ -133,10 +133,6 @@ static int acm_ms_do_config(struct usb_configuration *c)
 	if (status < 0)
 		goto put_msg;
 
-	status = fsg_common_run_thread(opts->common);
-	if (status)
-		goto remove_acm;
-
 	status = usb_add_function(c, f_msg);
 	if (status)
 		goto remove_acm;
diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c
index e61af53c7d2b..125974f32f50 100644
--- a/drivers/usb/gadget/legacy/mass_storage.c
+++ b/drivers/usb/gadget/legacy/mass_storage.c
@@ -132,10 +132,6 @@ static int msg_do_config(struct usb_configuration *c)
 	if (IS_ERR(f_msg))
 		return PTR_ERR(f_msg);
 
-	ret = fsg_common_run_thread(opts->common);
-	if (ret)
-		goto put_func;
-
 	ret = usb_add_function(c, f_msg);
 	if (ret)
 		goto put_func;
diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c
index 229d704a620b..a70a406580ea 100644
--- a/drivers/usb/gadget/legacy/multi.c
+++ b/drivers/usb/gadget/legacy/multi.c
@@ -137,7 +137,6 @@ static struct usb_function *f_msg_rndis;
 
 static int rndis_do_config(struct usb_configuration *c)
 {
-	struct fsg_opts *fsg_opts;
 	int ret;
 
 	if (gadget_is_otg(c->cdev->gadget)) {
@@ -169,11 +168,6 @@ static int rndis_do_config(struct usb_configuration *c)
 		goto err_fsg;
 	}
 
-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
-	ret = fsg_common_run_thread(fsg_opts->common);
-	if (ret)
-		goto err_run;
-
 	ret = usb_add_function(c, f_msg_rndis);
 	if (ret)
 		goto err_run;
@@ -225,7 +219,6 @@ static struct usb_function *f_msg_multi;
 
 static int cdc_do_config(struct usb_configuration *c)
 {
-	struct fsg_opts *fsg_opts;
 	int ret;
 
 	if (gadget_is_otg(c->cdev->gadget)) {
@@ -258,11 +251,6 @@ static int cdc_do_config(struct usb_configuration *c)
 		goto err_fsg;
 	}
 
-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
-	ret = fsg_common_run_thread(fsg_opts->common);
-	if (ret)
-		goto err_run;
-
 	ret = usb_add_function(c, f_msg_multi);
 	if (ret)
 		goto err_run;
diff --git a/drivers/usb/gadget/legacy/nokia.c b/drivers/usb/gadget/legacy/nokia.c
index 09975046c694..b1e535f4022e 100644
--- a/drivers/usb/gadget/legacy/nokia.c
+++ b/drivers/usb/gadget/legacy/nokia.c
@@ -152,7 +152,6 @@ static int nokia_bind_config(struct usb_configuration *c)
 	struct usb_function *f_ecm;
 	struct usb_function *f_obex2 = NULL;
 	struct usb_function *f_msg;
-	struct fsg_opts *fsg_opts;
 	int status = 0;
 	int obex1_stat = -1;
 	int obex2_stat = -1;
@@ -222,12 +221,6 @@ static int nokia_bind_config(struct usb_configuration *c)
 		goto err_ecm;
 	}
 
-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
-
-	status = fsg_common_run_thread(fsg_opts->common);
-	if (status)
-		goto err_msg;
-
 	status = usb_add_function(c, f_msg);
 	if (status)
 		goto err_msg;
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
index d0d18947f58b..8bc78418d40e 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -1726,10 +1726,7 @@ static int at91sam9261_udc_init(struct at91_udc *udc)
 
 	udc->matrix = syscon_regmap_lookup_by_phandle(udc->pdev->dev.of_node,
 						      "atmel,matrix");
-	if (IS_ERR(udc->matrix))
-		return PTR_ERR(udc->matrix);
-
-	return 0;
+	return PTR_ERR_OR_ZERO(udc->matrix);
 }
 
 static void at91sam9261_udc_pullup(struct at91_udc *udc, int is_on)
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c
index 9571ef54b86b..ebc51ec5790a 100644
--- a/drivers/usb/gadget/udc/pch_udc.c
+++ b/drivers/usb/gadget/udc/pch_udc.c
@@ -325,11 +325,8 @@ struct pch_vbus_gpio_data {
  * @pdev:		reference to the PCI device
  * @ep:			array of endpoints
  * @lock:		protects all state
- * @active:		enabled the PCI device
  * @stall:		stall requested
  * @prot_stall:		protcol stall requested
- * @irq_registered:	irq registered with system
- * @mem_region:		device memory mapped
  * @registered:		driver registered with system
  * @suspended:		driver in suspended state
  * @connected:		gadget driver associated
@@ -339,12 +336,8 @@ struct pch_vbus_gpio_data {
  * @data_requests:	DMA pool for data requests
  * @stp_requests:	DMA pool for setup requests
  * @dma_addr:		DMA pool for received
- * @ep0out_buf:		Buffer for DMA
  * @setup_data:		Received setup data
- * @phys_addr:		of device memory
  * @base_addr:		for mapped device memory
- * @bar:		Indicates which PCI BAR for USB regs
- * @irq:		IRQ line for the device
  * @cfg_data:		current cfg, intf, and alt in use
  * @vbus_gpio:		GPIO informaton for detecting VBUS
  */
@@ -354,11 +347,9 @@ struct pch_udc_dev {
 	struct pci_dev			*pdev;
 	struct pch_udc_ep		ep[PCH_UDC_EP_NUM];
 	spinlock_t			lock; /* protects all state */
-	unsigned	active:1,
+	unsigned
 			stall:1,
 			prot_stall:1,
-			irq_registered:1,
-			mem_region:1,
 			suspended:1,
 			connected:1,
 			vbus_session:1,
@@ -367,12 +358,8 @@ struct pch_udc_dev {
 	struct pci_pool		*data_requests;
 	struct pci_pool		*stp_requests;
 	dma_addr_t			dma_addr;
-	void				*ep0out_buf;
 	struct usb_ctrlrequest		setup_data;
-	unsigned long			phys_addr;
 	void __iomem			*base_addr;
-	unsigned			bar;
-	unsigned			irq;
 	struct pch_udc_cfg_data		cfg_data;
 	struct pch_vbus_gpio_data	vbus_gpio;
 };
@@ -380,8 +367,10 @@ struct pch_udc_dev {
 
 #define PCH_UDC_PCI_BAR_QUARK_X1000	0
 #define PCH_UDC_PCI_BAR			1
-#define PCI_DEVICE_ID_INTEL_EG20T_UDC	0x8808
+
 #define PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC	0x0939
+#define PCI_DEVICE_ID_INTEL_EG20T_UDC		0x8808
+
 #define PCI_VENDOR_ID_ROHM		0x10DB
 #define PCI_DEVICE_ID_ML7213_IOH_UDC	0x801D
 #define PCI_DEVICE_ID_ML7831_IOH_UDC	0x8808
@@ -1732,14 +1721,12 @@ static int pch_udc_pcd_ep_enable(struct usb_ep *usbep,
 static int pch_udc_pcd_ep_disable(struct usb_ep *usbep)
 {
 	struct pch_udc_ep	*ep;
-	struct pch_udc_dev	*dev;
 	unsigned long	iflags;
 
 	if (!usbep)
 		return -EINVAL;
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if ((usbep->name == ep0_string) || !ep->ep.desc)
 		return -EINVAL;
 
@@ -1770,12 +1757,10 @@ static struct usb_request *pch_udc_alloc_request(struct usb_ep *usbep,
 	struct pch_udc_request		*req;
 	struct pch_udc_ep		*ep;
 	struct pch_udc_data_dma_desc	*dma_desc;
-	struct pch_udc_dev		*dev;
 
 	if (!usbep)
 		return NULL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	req = kzalloc(sizeof *req, gfp);
 	if (!req)
 		return NULL;
@@ -1948,12 +1933,10 @@ static int pch_udc_pcd_dequeue(struct usb_ep *usbep,
 {
 	struct pch_udc_ep	*ep;
 	struct pch_udc_request	*req;
-	struct pch_udc_dev	*dev;
 	unsigned long		flags;
 	int ret = -EINVAL;
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if (!usbep || !usbreq || (!ep->ep.desc && ep->num))
 		return ret;
 	req = container_of(usbreq, struct pch_udc_request, req);
@@ -1985,14 +1968,12 @@ static int pch_udc_pcd_dequeue(struct usb_ep *usbep,
 static int pch_udc_pcd_set_halt(struct usb_ep *usbep, int halt)
 {
 	struct pch_udc_ep	*ep;
-	struct pch_udc_dev	*dev;
 	unsigned long iflags;
 	int ret;
 
 	if (!usbep)
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if (!ep->ep.desc && !ep->num)
 		return -EINVAL;
 	if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
@@ -2030,14 +2011,12 @@ static int pch_udc_pcd_set_halt(struct usb_ep *usbep, int halt)
 static int pch_udc_pcd_set_wedge(struct usb_ep *usbep)
 {
 	struct pch_udc_ep	*ep;
-	struct pch_udc_dev	*dev;
 	unsigned long iflags;
 	int ret;
 
 	if (!usbep)
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if (!ep->ep.desc && !ep->num)
 		return -EINVAL;
 	if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
@@ -2647,7 +2626,7 @@ static void pch_udc_svc_enum_interrupt(struct pch_udc_dev *dev)
 static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev)
 {
 	u32 reg, dev_stat = 0;
-	int i, ret;
+	int i;
 
 	dev_stat = pch_udc_read_device_status(dev);
 	dev->cfg_data.cur_intf = (dev_stat & UDC_DEVSTS_INTF_MASK) >>
@@ -2676,7 +2655,7 @@ static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev)
 	}
 	dev->stall = 0;
 	spin_lock(&dev->lock);
-	ret = dev->driver->setup(&dev->gadget, &dev->setup_data);
+	dev->driver->setup(&dev->gadget, &dev->setup_data);
 	spin_unlock(&dev->lock);
 }
 
@@ -2687,7 +2666,7 @@ static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev)
  */
 static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev)
 {
-	int i, ret;
+	int i;
 	u32 reg, dev_stat = 0;
 
 	dev_stat = pch_udc_read_device_status(dev);
@@ -2713,7 +2692,7 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev)
 
 	/* call gadget zero with setup data received */
 	spin_lock(&dev->lock);
-	ret = dev->driver->setup(&dev->gadget, &dev->setup_data);
+	dev->driver->setup(&dev->gadget, &dev->setup_data);
 	spin_unlock(&dev->lock);
 }
 
@@ -2856,17 +2835,6 @@ static void pch_udc_setup_ep0(struct pch_udc_dev *dev)
 }
 
 /**
- * gadget_release() - Free the gadget driver private data
- * @pdev	reference to struct pci_dev
- */
-static void gadget_release(struct device *pdev)
-{
-	struct pch_udc_dev *dev = dev_get_drvdata(pdev);
-
-	kfree(dev);
-}
-
-/**
  * pch_udc_pcd_reinit() - This API initializes the endpoint structures
  * @dev:	Reference to the driver structure
  */
@@ -2949,6 +2917,7 @@ static int init_dma_pools(struct pch_udc_dev *dev)
 {
 	struct pch_udc_stp_dma_desc	*td_stp;
 	struct pch_udc_data_dma_desc	*td_data;
+	void				*ep0out_buf;
 
 	/* DMA setup */
 	dev->data_requests = pci_pool_create("data_requests", dev->pdev,
@@ -2991,10 +2960,11 @@ static int init_dma_pools(struct pch_udc_dev *dev)
 	dev->ep[UDC_EP0IN_IDX].td_data = NULL;
 	dev->ep[UDC_EP0IN_IDX].td_data_phys = 0;
 
-	dev->ep0out_buf = kzalloc(UDC_EP0OUT_BUFF_SIZE * 4, GFP_KERNEL);
-	if (!dev->ep0out_buf)
+	ep0out_buf = devm_kzalloc(&dev->pdev->dev, UDC_EP0OUT_BUFF_SIZE * 4,
+				  GFP_KERNEL);
+	if (!ep0out_buf)
 		return -ENOMEM;
-	dev->dma_addr = dma_map_single(&dev->pdev->dev, dev->ep0out_buf,
+	dev->dma_addr = dma_map_single(&dev->pdev->dev, ep0out_buf,
 				       UDC_EP0OUT_BUFF_SIZE * 4,
 				       DMA_FROM_DEVICE);
 	return 0;
@@ -3078,129 +3048,80 @@ static void pch_udc_remove(struct pci_dev *pdev)
 	if (dev->dma_addr)
 		dma_unmap_single(&dev->pdev->dev, dev->dma_addr,
 				 UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE);
-	kfree(dev->ep0out_buf);
 
 	pch_vbus_gpio_free(dev);
 
 	pch_udc_exit(dev);
-
-	if (dev->irq_registered)
-		free_irq(pdev->irq, dev);
-	if (dev->base_addr)
-		iounmap(dev->base_addr);
-	if (dev->mem_region)
-		release_mem_region(dev->phys_addr,
-				   pci_resource_len(pdev, dev->bar));
-	if (dev->active)
-		pci_disable_device(pdev);
-	kfree(dev);
 }
 
-#ifdef CONFIG_PM
-static int pch_udc_suspend(struct pci_dev *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int pch_udc_suspend(struct device *d)
 {
+	struct pci_dev *pdev = to_pci_dev(d);
 	struct pch_udc_dev *dev = pci_get_drvdata(pdev);
 
 	pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK);
 	pch_udc_disable_ep_interrupts(dev, UDC_EPINT_MSK_DISABLE_ALL);
 
-	pci_disable_device(pdev);
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-
-	if (pci_save_state(pdev)) {
-		dev_err(&pdev->dev,
-			"%s: could not save PCI config state\n", __func__);
-		return -ENOMEM;
-	}
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 	return 0;
 }
 
-static int pch_udc_resume(struct pci_dev *pdev)
+static int pch_udc_resume(struct device *d)
 {
-	int ret;
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	ret = pci_enable_device(pdev);
-	if (ret) {
-		dev_err(&pdev->dev, "%s: pci_enable_device failed\n", __func__);
-		return ret;
-	}
-	pci_enable_wake(pdev, PCI_D3hot, 0);
 	return 0;
 }
+
+static SIMPLE_DEV_PM_OPS(pch_udc_pm, pch_udc_suspend, pch_udc_resume);
+#define PCH_UDC_PM_OPS		(&pch_udc_pm)
 #else
-#define pch_udc_suspend	NULL
-#define pch_udc_resume	NULL
-#endif /* CONFIG_PM */
+#define PCH_UDC_PM_OPS		NULL
+#endif /* CONFIG_PM_SLEEP */
 
 static int pch_udc_probe(struct pci_dev *pdev,
 			  const struct pci_device_id *id)
 {
-	unsigned long		resource;
-	unsigned long		len;
+	int			bar;
 	int			retval;
 	struct pch_udc_dev	*dev;
 
 	/* init */
-	dev = kzalloc(sizeof *dev, GFP_KERNEL);
-	if (!dev) {
-		pr_err("%s: no memory for device structure\n", __func__);
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
 		return -ENOMEM;
-	}
+
 	/* pci setup */
-	if (pci_enable_device(pdev) < 0) {
-		kfree(dev);
-		pr_err("%s: pci_enable_device failed\n", __func__);
-		return -ENODEV;
-	}
-	dev->active = 1;
+	retval = pcim_enable_device(pdev);
+	if (retval)
+		return retval;
+
 	pci_set_drvdata(pdev, dev);
 
 	/* Determine BAR based on PCI ID */
 	if (id->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_UDC)
-		dev->bar = PCH_UDC_PCI_BAR_QUARK_X1000;
+		bar = PCH_UDC_PCI_BAR_QUARK_X1000;
 	else
-		dev->bar = PCH_UDC_PCI_BAR;
+		bar = PCH_UDC_PCI_BAR;
 
 	/* PCI resource allocation */
-	resource = pci_resource_start(pdev, dev->bar);
-	len = pci_resource_len(pdev, dev->bar);
+	retval = pcim_iomap_regions(pdev, 1 << bar, pci_name(pdev));
+	if (retval)
+		return retval;
 
-	if (!request_mem_region(resource, len, KBUILD_MODNAME)) {
-		dev_err(&pdev->dev, "%s: pci device used already\n", __func__);
-		retval = -EBUSY;
-		goto finished;
-	}
-	dev->phys_addr = resource;
-	dev->mem_region = 1;
+	dev->base_addr = pcim_iomap_table(pdev)[bar];
 
-	dev->base_addr = ioremap_nocache(resource, len);
-	if (!dev->base_addr) {
-		pr_err("%s: device memory cannot be mapped\n", __func__);
-		retval = -ENOMEM;
-		goto finished;
-	}
-	if (!pdev->irq) {
-		dev_err(&pdev->dev, "%s: irq not set\n", __func__);
-		retval = -ENODEV;
-		goto finished;
-	}
 	/* initialize the hardware */
-	if (pch_udc_pcd_init(dev)) {
-		retval = -ENODEV;
-		goto finished;
-	}
-	if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME,
-			dev)) {
+	if (pch_udc_pcd_init(dev))
+		return -ENODEV;
+
+	pci_enable_msi(pdev);
+
+	retval = devm_request_irq(&pdev->dev, pdev->irq, pch_udc_isr,
+				  IRQF_SHARED, KBUILD_MODNAME, dev);
+	if (retval) {
 		dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__,
 			pdev->irq);
-		retval = -ENODEV;
 		goto finished;
 	}
-	dev->irq = pdev->irq;
-	dev->irq_registered = 1;
 
 	pci_set_master(pdev);
 	pci_try_set_mwi(pdev);
@@ -3219,8 +3140,7 @@ static int pch_udc_probe(struct pci_dev *pdev,
 
 	/* Put the device in disconnected state till a driver is bound */
 	pch_udc_set_disconnect(dev);
-	retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget,
-			gadget_release);
+	retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
 	if (retval)
 		goto finished;
 	return 0;
@@ -3262,9 +3182,10 @@ static struct pci_driver pch_udc_driver = {
 	.id_table =	pch_udc_pcidev_id,
 	.probe =	pch_udc_probe,
 	.remove =	pch_udc_remove,
-	.suspend =	pch_udc_suspend,
-	.resume =	pch_udc_resume,
 	.shutdown =	pch_udc_shutdown,
+	.driver = {
+		.pm = PCH_UDC_PM_OPS,
+	},
 };
 
 module_pci_driver(pch_udc_driver);
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c
index baa0609a429d..8b300e6da7fc 100644
--- a/drivers/usb/gadget/udc/r8a66597-udc.c
+++ b/drivers/usb/gadget/udc/r8a66597-udc.c
@@ -296,7 +296,7 @@ static void r8a66597_change_curpipe(struct r8a66597 *r8a66597, u16 pipenum,
 	} while ((tmp & mask) != loop);
 }
 
-static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum)
+static void pipe_change(struct r8a66597 *r8a66597, u16 pipenum)
 {
 	struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum];
 
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index e4e70e11d0f6..6e8300d6a737 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -61,11 +61,9 @@ static int udc_bind_to_driver(struct usb_udc *udc,
 
 #ifdef	CONFIG_HAS_DMA
 
-int usb_gadget_map_request(struct usb_gadget *gadget,
+int usb_gadget_map_request_by_dev(struct device *dev,
 		struct usb_request *req, int is_in)
 {
-	struct device *dev = gadget->dev.parent;
-
 	if (req->length == 0)
 		return 0;
 
@@ -75,7 +73,7 @@ int usb_gadget_map_request(struct usb_gadget *gadget,
 		mapped = dma_map_sg(dev, req->sg, req->num_sgs,
 				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 		if (mapped == 0) {
-			dev_err(&gadget->dev, "failed to map SGs\n");
+			dev_err(dev, "failed to map SGs\n");
 			return -EFAULT;
 		}
 
@@ -92,24 +90,38 @@ int usb_gadget_map_request(struct usb_gadget *gadget,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(usb_gadget_map_request_by_dev);
+
+int usb_gadget_map_request(struct usb_gadget *gadget,
+		struct usb_request *req, int is_in)
+{
+	return usb_gadget_map_request_by_dev(gadget->dev.parent, req, is_in);
+}
 EXPORT_SYMBOL_GPL(usb_gadget_map_request);
 
-void usb_gadget_unmap_request(struct usb_gadget *gadget,
+void usb_gadget_unmap_request_by_dev(struct device *dev,
 		struct usb_request *req, int is_in)
 {
 	if (req->length == 0)
 		return;
 
 	if (req->num_mapped_sgs) {
-		dma_unmap_sg(gadget->dev.parent, req->sg, req->num_mapped_sgs,
+		dma_unmap_sg(dev, req->sg, req->num_mapped_sgs,
 				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
 		req->num_mapped_sgs = 0;
 	} else {
-		dma_unmap_single(gadget->dev.parent, req->dma, req->length,
+		dma_unmap_single(dev, req->dma, req->length,
 				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 	}
 }
+EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
+
+void usb_gadget_unmap_request(struct usb_gadget *gadget,
+		struct usb_request *req, int is_in)
+{
+	usb_gadget_unmap_request_by_dev(gadget->dev.parent, req, is_in);
+}
 EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
 
 #endif	/* CONFIG_HAS_DMA */
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6acac6201af0..d8f5674809e8 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -35,6 +35,7 @@ config USB_XHCI_PCI
 
 config USB_XHCI_PLATFORM
 	tristate "Generic xHCI driver for a platform device"
+	select USB_XHCI_RCAR if ARCH_RENESAS
 	---help---
 	  Adds an xHCI host driver for a generic platform device, which
 	  provides a memory space and an irq.
@@ -63,7 +64,7 @@ config USB_XHCI_MVEBU
 
 config USB_XHCI_RCAR
 	tristate "xHCI support for Renesas R-Car SoCs"
-	select USB_XHCI_PLATFORM
+	depends on USB_XHCI_PLATFORM
 	depends on ARCH_RENESAS || COMPILE_TEST
 	---help---
 	  Say 'Y' to enable the support for the xHCI host controller
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
index 963e2d0e8f92..172ef17911aa 100644
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -352,10 +352,8 @@ static int bcma_hcd_probe(struct bcma_device *core)
 	usb_dev->core = core;
 
 	if (core->dev.of_node)
-		usb_dev->gpio_desc = devm_get_gpiod_from_child(&core->dev, "vcc",
-							       &core->dev.of_node->fwnode);
-	if (!IS_ERR_OR_NULL(usb_dev->gpio_desc))
-		gpiod_direction_output(usb_dev->gpio_desc, 1);
+		usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc",
+						    GPIOD_OUT_HIGH);
 
 	switch (core->id.id) {
 	case BCMA_CORE_USB20_HOST:
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 79d12b2ba3c4..1a2614aae42c 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -52,13 +52,6 @@ static void dbg_hcs_params(struct ehci_hcd *ehci, char *label)
 		ehci_dbg(ehci, "%s portroute %s\n", label, buf);
 	}
 }
-#else
-
-static inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label) {}
-
-#endif
-
-#ifdef CONFIG_DYNAMIC_DEBUG
 
 /*
  * check the values in the HCCPARAMS register
@@ -92,13 +85,6 @@ static void dbg_hcc_params(struct ehci_hcd *ehci, char *label)
 				" 32 periodic list" : "");
 	}
 }
-#else
-
-static inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label) {}
-
-#endif
-
-#ifdef CONFIG_DYNAMIC_DEBUG
 
 static void __maybe_unused
 dbg_qtd(const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
@@ -281,37 +267,6 @@ dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
 		(status & PORT_CONNECT) ? " CONNECT" : "");
 }
 
-#else
-static inline void __maybe_unused
-dbg_qh(char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
-{}
-
-static inline int __maybe_unused
-dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
-{
-	return 0;
-}
-
-static inline int __maybe_unused
-dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
-{
-	return 0;
-}
-
-static inline int __maybe_unused
-dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
-{
-	return 0;
-}
-
-static inline int __maybe_unused
-dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	return 0;
-}
-
-#endif	/* CONFIG_DYNAMIC_DEBUG */
-
 static inline void
 dbg_status(struct ehci_hcd *ehci, const char *label, u32 status)
 {
@@ -341,13 +296,6 @@ dbg_port(struct ehci_hcd *ehci, const char *label, int port, u32 status)
 
 /*-------------------------------------------------------------------------*/
 
-#ifndef CONFIG_DYNAMIC_DEBUG
-
-static inline void create_debug_files(struct ehci_hcd *bus) { }
-static inline void remove_debug_files(struct ehci_hcd *bus) { }
-
-#else
-
 /* troubleshooting help: expose state in debugfs */
 
 static int debug_async_open(struct inode *, struct file *);
@@ -1120,4 +1068,38 @@ static inline void remove_debug_files(struct ehci_hcd *ehci)
 	debugfs_remove_recursive(ehci->debug_dir);
 }
 
+#else /* CONFIG_DYNAMIC_DEBUG */
+
+static inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label) { }
+static inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label) { }
+
+static inline void __maybe_unused dbg_qh(const char *label,
+		struct ehci_hcd *ehci, struct ehci_qh *qh) { }
+
+static inline int __maybe_unused dbg_status_buf(const char *buf,
+		unsigned int len, const char *label, u32 status)
+{ return 0; }
+
+static inline int __maybe_unused dbg_command_buf(const char *buf,
+		unsigned int len, const char *label, u32 command)
+{ return 0; }
+
+static inline int __maybe_unused dbg_intr_buf(const char *buf,
+		unsigned int len, const char *label, u32 enable)
+{ return 0; }
+
+static inline int __maybe_unused dbg_port_buf(char *buf,
+		unsigned int len, const char *label, int port, u32 status)
+{ return 0; }
+
+static inline void dbg_status(struct ehci_hcd *ehci, const char *label,
+		u32 status) { }
+static inline void dbg_cmd(struct ehci_hcd *ehci, const char *label,
+		u32 command) { }
+static inline void dbg_port(struct ehci_hcd *ehci, const char *label,
+		int port, u32 status) { }
+
+static inline void create_debug_files(struct ehci_hcd *bus) { }
+static inline void remove_debug_files(struct ehci_hcd *bus) { }
+
 #endif /* CONFIG_DYNAMIC_DEBUG */
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index df538fd10aa4..42e5b66353ef 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -321,7 +321,7 @@ static struct platform_driver exynos_ehci_driver = {
 		.of_match_table = of_match_ptr(exynos_ehci_match),
 	}
 };
-static const struct ehci_driver_overrides exynos_overrides __initdata = {
+static const struct ehci_driver_overrides exynos_overrides __initconst = {
 	.extra_priv_size = sizeof(struct exynos_ehci_hcd),
 };
 
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 3e226ef6ca62..d3afc89d00f5 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -229,7 +229,7 @@ static struct platform_driver ehci_msm_driver = {
 	},
 };
 
-static const struct ehci_driver_overrides msm_overrides __initdata = {
+static const struct ehci_driver_overrides msm_overrides __initconst = {
 	.reset = ehci_msm_reset,
 };
 
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index a24720beb39d..94ea9fff13e6 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -86,7 +86,7 @@ static inline u32 ehci_read(void __iomem *base, u32 reg)
 
 static struct hc_driver __read_mostly ehci_omap_hc_driver;
 
-static const struct ehci_driver_overrides ehci_omap_overrides __initdata = {
+static const struct ehci_driver_overrides ehci_omap_overrides __initconst = {
 	.extra_priv_size = sizeof(struct omap_hcd),
 };
 
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index 3c4e5253955c..1f25c7985f5b 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -163,7 +163,7 @@ static struct platform_driver spear_ehci_hcd_driver = {
 	}
 };
 
-static const struct ehci_driver_overrides spear_overrides __initdata = {
+static const struct ehci_driver_overrides spear_overrides __initconst = {
 	.extra_priv_size = sizeof(struct spear_ehci),
 };
 
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c
index a9609a336efe..2f162faabbca 100644
--- a/drivers/usb/host/fhci-sched.c
+++ b/drivers/usb/host/fhci-sched.c
@@ -288,7 +288,7 @@ static int scan_ed_list(struct fhci_usb *usb,
 	list_for_each_entry(ed, list, node) {
 		td = ed->td_head;
 
-		if (!td || (td && td->status == USB_TD_INPROGRESS))
+		if (!td || td->status == USB_TD_INPROGRESS)
 			continue;
 
 		if (ed->state != FHCI_ED_OPER) {
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 360a5e95abca..66efa9a67687 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -4795,14 +4795,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;
 
-	if (i)
-		goto out;
-
-	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
-out:
-	return i;
+	return device_create_file(controller, &dev_attr_uframe_periodic_max);
 }
 
 static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index 43626c44683b..5b3603c360ab 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -257,14 +257,14 @@ static int whc_probe(struct umc_dev *umc)
 
 	ret = whc_init(whc);
 	if (ret)
-		goto error;
+		goto error_whc_init;
 
 	wusbhc->dev = dev;
 	wusbhc->uwb_rc = uwb_rc_get_by_grandpa(umc->dev.parent);
 	if (!wusbhc->uwb_rc) {
 		ret = -ENODEV;
 		dev_err(dev, "cannot get radio controller\n");
-		goto error;
+		goto error_uwb_rc;
 	}
 
 	if (whc->n_devices > USB_MAXCHILDREN) {
@@ -311,8 +311,9 @@ error_usb_add_hcd:
 	wusbhc_destroy(wusbhc);
 error_wusbhc_create:
 	uwb_rc_put(wusbhc->uwb_rc);
-error:
+error_uwb_rc:
 	whc_clean_up(whc);
+error_whc_init:
 	usb_put_hcd(usb_hcd);
 	return ret;
 }
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
index 1a8e960d073b..c0e6812426b3 100644
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -314,7 +314,7 @@ void qset_free_std(struct whc *whc, struct whc_std *std)
 		kfree(std->bounce_buf);
 	}
 	if (std->pl_virt) {
-		if (std->dma_addr)
+		if (!dma_mapping_error(whc->wusbhc.dev, std->dma_addr))
 			dma_unmap_single(whc->wusbhc.dev, std->dma_addr,
 					 std->num_pointers * sizeof(struct whc_page_list_entry),
 					 DMA_TO_DEVICE);
@@ -535,9 +535,11 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
 	list_for_each_entry(std, &qset->stds, list_node) {
 		if (std->ntds_remaining == -1) {
 			pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
-			std->ntds_remaining = ntds--;
 			std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt,
 						       pl_len, DMA_TO_DEVICE);
+			if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr))
+				return -EFAULT;
+			std->ntds_remaining = ntds--;
 		}
 	}
 	return 0;
@@ -618,6 +620,8 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
 
 		std->dma_addr = dma_map_single(&whc->umc->dev, std->bounce_buf, std->len,
 					       is_out ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+		if (dma_mapping_error(&whc->umc->dev, std->dma_addr))
+			return -EFAULT;
 
 		if (qset_fill_page_list(whc, std, mem_flags) < 0)
 			return -ENOMEM;
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index 1eefc988192d..85908a3ecb8f 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -12,6 +12,9 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
 #include "xhci-mvebu.h"
 
 #define USB3_MAX_WINDOWS	4
@@ -41,8 +44,10 @@ static void xhci_mvebu_mbus_config(void __iomem *base,
 	}
 }
 
-int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev)
+int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
 {
+	struct device *dev = hcd->self.controller;
+	struct platform_device *pdev = to_platform_device(dev);
 	struct resource	*res;
 	void __iomem *base;
 	const struct mbus_dram_target_info *dram;
diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h
index 7ede92aa41f6..301fc984cae6 100644
--- a/drivers/usb/host/xhci-mvebu.h
+++ b/drivers/usb/host/xhci-mvebu.h
@@ -10,10 +10,13 @@
 
 #ifndef __LINUX_XHCI_MVEBU_H
 #define __LINUX_XHCI_MVEBU_H
+
+struct usb_hcd;
+
 #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
-int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev);
+int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
 #else
-static inline int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev)
+static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 474b5fa14900..676ea458148b 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -37,27 +37,32 @@ static const struct xhci_driver_overrides xhci_plat_overrides __initconst = {
 	.start = xhci_plat_start,
 };
 
-static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
+static void xhci_priv_plat_start(struct usb_hcd *hcd)
+{
+	struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
+
+	if (priv->plat_start)
+		priv->plat_start(hcd);
+}
+
+static int xhci_priv_init_quirk(struct usb_hcd *hcd)
 {
-	struct usb_hcd *hcd = xhci_to_hcd(xhci);
+	struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
+
+	if (!priv->init_quirk)
+		return 0;
 
+	return priv->init_quirk(hcd);
+}
+
+static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
+{
 	/*
 	 * As of now platform drivers don't provide MSI support so we ensure
 	 * here that the generic code does not try to make a pci_dev from our
 	 * dev struct in order to setup MSI
 	 */
 	xhci->quirks |= XHCI_PLAT;
-
-	/*
-	 * On R-Car Gen2 and Gen3, the AC64 bit (bit 0) of HCCPARAMS1 is set
-	 * to 1. However, these SoCs don't support 64-bit address memory
-	 * pointers. So, this driver clears the AC64 bit of xhci->hcc_params
-	 * to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in
-	 * xhci_gen_setup().
-	 */
-	if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) ||
-	    xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3))
-		xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
 }
 
 /* called during probe() after chip reset completes */
@@ -65,38 +70,35 @@ static int xhci_plat_setup(struct usb_hcd *hcd)
 {
 	int ret;
 
-	if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) ||
-	    xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3)) {
-		ret = xhci_rcar_init_quirk(hcd);
-		if (ret)
-			return ret;
-	}
+
+	ret = xhci_priv_init_quirk(hcd);
+	if (ret)
+		return ret;
 
 	return xhci_gen_setup(hcd, xhci_plat_quirks);
 }
 
 static int xhci_plat_start(struct usb_hcd *hcd)
 {
-	if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2) ||
-	    xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3))
-		xhci_rcar_start(hcd);
-
+	xhci_priv_plat_start(hcd);
 	return xhci_run(hcd);
 }
 
 #ifdef CONFIG_OF
 static const struct xhci_plat_priv xhci_plat_marvell_armada = {
-	.type = XHCI_PLAT_TYPE_MARVELL_ARMADA,
+	.init_quirk = xhci_mvebu_mbus_init_quirk,
 };
 
 static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = {
-	.type = XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2,
 	.firmware_name = XHCI_RCAR_FIRMWARE_NAME_V1,
+	.init_quirk = xhci_rcar_init_quirk,
+	.plat_start = xhci_rcar_start,
 };
 
 static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
-	.type = XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3,
 	.firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2,
+	.init_quirk = xhci_rcar_init_quirk,
+	.plat_start = xhci_rcar_start,
 };
 
 static const struct of_device_id usb_xhci_of_match[] = {
@@ -207,12 +209,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
 			*priv = *priv_match;
 	}
 
-	if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_MARVELL_ARMADA)) {
-		ret = xhci_mvebu_mbus_init_quirk(pdev);
-		if (ret)
-			goto disable_clk;
-	}
-
 	device_wakeup_enable(hcd->self.controller);
 
 	xhci->clk = clk;
diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h
index 529c3c40f901..9af0cb48053f 100644
--- a/drivers/usb/host/xhci-plat.h
+++ b/drivers/usb/host/xhci-plat.h
@@ -13,27 +13,11 @@
 
 #include "xhci.h"	/* for hcd_to_xhci() */
 
-enum xhci_plat_type {
-	XHCI_PLAT_TYPE_MARVELL_ARMADA = 1,
-	XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2,
-	XHCI_PLAT_TYPE_RENESAS_RCAR_GEN3,
-};
-
 struct xhci_plat_priv {
-	enum xhci_plat_type type;
 	const char *firmware_name;
+	void (*plat_start)(struct usb_hcd *);
+	int (*init_quirk)(struct usb_hcd *);
 };
 
 #define hcd_to_xhci_priv(h) ((struct xhci_plat_priv *)hcd_to_xhci(h)->priv)
-
-static inline bool xhci_plat_type_is(struct usb_hcd *hcd,
-				     enum xhci_plat_type type)
-{
-	struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd);
-
-	if (priv && priv->type == type)
-		return true;
-	else
-		return false;
-}
 #endif	/* _XHCI_PLAT_H */
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index 623100e9385e..0e4535e632ec 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -11,6 +11,7 @@
 #include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/usb/phy.h>
 
 #include "xhci.h"
@@ -76,6 +77,24 @@ static void xhci_rcar_start_gen2(struct usb_hcd *hcd)
 	writel(RCAR_USB3_TX_POL_VAL, hcd->regs + RCAR_USB3_TX_POL);
 }
 
+static int xhci_rcar_is_gen2(struct device *dev)
+{
+	struct device_node *node = dev->of_node;
+
+	return of_device_is_compatible(node, "renesas,xhci-r8a7790") ||
+		of_device_is_compatible(node, "renesas,xhci-r8a7791") ||
+		of_device_is_compatible(node, "renesas,xhci-r8a7793") ||
+		of_device_is_compatible(node, "renensas,rcar-gen2-xhci");
+}
+
+static int xhci_rcar_is_gen3(struct device *dev)
+{
+	struct device_node *node = dev->of_node;
+
+	return of_device_is_compatible(node, "renesas,xhci-r8a7795") ||
+		of_device_is_compatible(node, "renesas,rcar-gen3-xhci");
+}
+
 void xhci_rcar_start(struct usb_hcd *hcd)
 {
 	u32 temp;
@@ -85,7 +104,7 @@ void xhci_rcar_start(struct usb_hcd *hcd)
 		temp = readl(hcd->regs + RCAR_USB3_INT_ENA);
 		temp |= RCAR_USB3_INT_ENA_VAL;
 		writel(temp, hcd->regs + RCAR_USB3_INT_ENA);
-		if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_RENESAS_RCAR_GEN2))
+		if (xhci_rcar_is_gen2(hcd->self.controller))
 			xhci_rcar_start_gen2(hcd);
 	}
 }
@@ -156,9 +175,22 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd)
 /* This function needs to initialize a "phy" of usb before */
 int xhci_rcar_init_quirk(struct usb_hcd *hcd)
 {
+	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+
 	/* If hcd->regs is NULL, we don't just call the following function */
 	if (!hcd->regs)
 		return 0;
 
+	/*
+	 * On R-Car Gen2 and Gen3, the AC64 bit (bit 0) of HCCPARAMS1 is set
+	 * to 1. However, these SoCs don't support 64-bit address memory
+	 * pointers. So, this driver clears the AC64 bit of xhci->hcc_params
+	 * to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in
+	 * xhci_gen_setup().
+	 */
+	if (xhci_rcar_is_gen2(hcd->self.controller) ||
+			xhci_rcar_is_gen3(hcd->self.controller))
+		xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
+
 	return xhci_rcar_download_firmware(hcd);
 }
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 99b4ff42f7a0..52deae4b7eac 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -373,7 +373,11 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci,
 	}
 }
 
-static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
+/* Get the right ring for the given slot_id, ep_index and stream_id.
+ * If the endpoint supports streams, boundary check the URB's stream ID.
+ * If the endpoint doesn't support streams, return the singular endpoint ring.
+ */
+struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
 		unsigned int slot_id, unsigned int ep_index,
 		unsigned int stream_id)
 {
@@ -405,17 +409,6 @@ static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
 	return NULL;
 }
 
-/* Get the right ring for the given URB.
- * If the endpoint supports streams, boundary check the URB's stream ID.
- * If the endpoint doesn't support streams, return the singular endpoint ring.
- */
-static struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
-		struct urb *urb)
-{
-	return xhci_triad_to_transfer_ring(xhci, urb->dev->slot_id,
-		xhci_get_endpoint_index(&urb->ep->desc), urb->stream_id);
-}
-
 /*
  * Move the xHC's endpoint ring dequeue pointer past cur_td.
  * Record the new state of the xHC's endpoint ring dequeue segment,
@@ -1768,7 +1761,7 @@ static int xhci_requires_manual_halt_cleanup(struct xhci_hcd *xhci,
 	if (trb_comp_code == COMP_TX_ERR ||
 			trb_comp_code == COMP_BABBLE ||
 			trb_comp_code == COMP_SPLIT_ERR)
-		/* The 0.96 spec says a babbling control endpoint
+		/* The 0.95 spec says a babbling control endpoint
 		 * is not halted. The 0.96 spec says it is.  Some HW
 		 * claims to be 0.95 compliant, but it halts the control
 		 * endpoint anyway.  Check if a babble halted the
@@ -2938,46 +2931,55 @@ static int prepare_transfer(struct xhci_hcd *xhci,
 	return 0;
 }
 
-static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)
+static unsigned int count_trbs(u64 addr, u64 len)
+{
+	unsigned int num_trbs;
+
+	num_trbs = DIV_ROUND_UP(len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
+			TRB_MAX_BUFF_SIZE);
+	if (num_trbs == 0)
+		num_trbs++;
+
+	return num_trbs;
+}
+
+static inline unsigned int count_trbs_needed(struct urb *urb)
+{
+	return count_trbs(urb->transfer_dma, urb->transfer_buffer_length);
+}
+
+static unsigned int count_sg_trbs_needed(struct urb *urb)
 {
-	int num_sgs, num_trbs, running_total, temp, i;
 	struct scatterlist *sg;
+	unsigned int i, len, full_len, num_trbs = 0;
 
-	sg = NULL;
-	num_sgs = urb->num_mapped_sgs;
-	temp = urb->transfer_buffer_length;
+	full_len = urb->transfer_buffer_length;
 
-	num_trbs = 0;
-	for_each_sg(urb->sg, sg, num_sgs, i) {
-		unsigned int len = sg_dma_len(sg);
-
-		/* Scatter gather list entries may cross 64KB boundaries */
-		running_total = TRB_MAX_BUFF_SIZE -
-			(sg_dma_address(sg) & (TRB_MAX_BUFF_SIZE - 1));
-		running_total &= TRB_MAX_BUFF_SIZE - 1;
-		if (running_total != 0)
-			num_trbs++;
-
-		/* How many more 64KB chunks to transfer, how many more TRBs? */
-		while (running_total < sg_dma_len(sg) && running_total < temp) {
-			num_trbs++;
-			running_total += TRB_MAX_BUFF_SIZE;
-		}
-		len = min_t(int, len, temp);
-		temp -= len;
-		if (temp == 0)
+	for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {
+		len = sg_dma_len(sg);
+		num_trbs += count_trbs(sg_dma_address(sg), len);
+		len = min_t(unsigned int, len, full_len);
+		full_len -= len;
+		if (full_len == 0)
 			break;
 	}
+
 	return num_trbs;
 }
 
-static void check_trb_math(struct urb *urb, int num_trbs, int running_total)
+static unsigned int count_isoc_trbs_needed(struct urb *urb, int i)
 {
-	if (num_trbs != 0)
-		dev_err(&urb->dev->dev, "%s - ep %#x - Miscalculated number of "
-				"TRBs, %d left\n", __func__,
-				urb->ep->desc.bEndpointAddress, num_trbs);
-	if (running_total != urb->transfer_buffer_length)
+	u64 addr, len;
+
+	addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
+	len = urb->iso_frame_desc[i].length;
+
+	return count_trbs(addr, len);
+}
+
+static void check_trb_math(struct urb *urb, int running_total)
+{
+	if (unlikely(running_total != urb->transfer_buffer_length))
 		dev_err(&urb->dev->dev, "%s - ep %#x - Miscalculated tx length, "
 				"queued %#x (%d), asked for %#x (%d)\n",
 				__func__,
@@ -3003,26 +3005,20 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
 	xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id);
 }
 
-/*
- * xHCI uses normal TRBs for both bulk and interrupt.  When the interrupt
- * endpoint is to be serviced, the xHC will consume (at most) one TD.  A TD
- * (comprised of sg list entries) can take several service intervals to
- * transmit.
- */
-int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
-		struct urb *urb, int slot_id, unsigned int ep_index)
+static void check_interval(struct xhci_hcd *xhci, struct urb *urb,
+						struct xhci_ep_ctx *ep_ctx)
 {
-	struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci,
-			xhci->devs[slot_id]->out_ctx, ep_index);
 	int xhci_interval;
 	int ep_interval;
 
 	xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx->ep_info));
 	ep_interval = urb->interval;
+
 	/* Convert to microframes */
 	if (urb->dev->speed == USB_SPEED_LOW ||
 			urb->dev->speed == USB_SPEED_FULL)
 		ep_interval *= 8;
+
 	/* FIXME change this to a warning and a suggestion to use the new API
 	 * to set the polling interval (once the API is added).
 	 */
@@ -3037,6 +3033,22 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 				urb->dev->speed == USB_SPEED_FULL)
 			urb->interval /= 8;
 	}
+}
+
+/*
+ * xHCI uses normal TRBs for both bulk and interrupt.  When the interrupt
+ * endpoint is to be serviced, the xHC will consume (at most) one TD.  A TD
+ * (comprised of sg list entries) can take several service intervals to
+ * transmit.
+ */
+int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+		struct urb *urb, int slot_id, unsigned int ep_index)
+{
+	struct xhci_ep_ctx *ep_ctx;
+
+	ep_ctx = xhci_get_ep_ctx(xhci, xhci->devs[slot_id]->out_ctx, ep_index);
+	check_interval(xhci, urb, ep_ctx);
+
 	return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
 
@@ -3086,44 +3098,47 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
 	return (total_packet_count - ((transferred + trb_buff_len) / maxp));
 }
 
-
-static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+/* This is very similar to what ehci-q.c qtd_fill() does */
+int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		struct urb *urb, int slot_id, unsigned int ep_index)
 {
 	struct xhci_ring *ep_ring;
-	unsigned int num_trbs;
 	struct urb_priv *urb_priv;
 	struct xhci_td *td;
-	struct scatterlist *sg;
-	int num_sgs;
-	int trb_buff_len, this_sg_len, running_total, ret;
-	unsigned int total_packet_count;
+	struct xhci_generic_trb *start_trb;
+	struct scatterlist *sg = NULL;
+	bool more_trbs_coming;
 	bool zero_length_needed;
-	bool first_trb;
-	int last_trb_num;
+	unsigned int num_trbs, last_trb_num, i;
+	unsigned int start_cycle, num_sgs = 0;
+	unsigned int running_total, block_len, trb_buff_len;
+	unsigned int full_len;
+	int ret;
+	u32 field, length_field, remainder;
 	u64 addr;
-	bool more_trbs_coming;
-
-	struct xhci_generic_trb *start_trb;
-	int start_cycle;
 
 	ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
 	if (!ep_ring)
 		return -EINVAL;
 
-	num_trbs = count_sg_trbs_needed(xhci, urb);
-	num_sgs = urb->num_mapped_sgs;
-	total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
-			usb_endpoint_maxp(&urb->ep->desc));
+	/* If we have scatter/gather list, we use it. */
+	if (urb->num_sgs) {
+		num_sgs = urb->num_mapped_sgs;
+		sg = urb->sg;
+		num_trbs = count_sg_trbs_needed(urb);
+	} else
+		num_trbs = count_trbs_needed(urb);
 
 	ret = prepare_transfer(xhci, xhci->devs[slot_id],
 			ep_index, urb->stream_id,
 			num_trbs, urb, 0, mem_flags);
-	if (ret < 0)
+	if (unlikely(ret < 0))
 		return ret;
 
 	urb_priv = urb->hcpriv;
 
+	last_trb_num = num_trbs - 1;
+
 	/* Deal with URB_ZERO_PACKET - need one more td/trb */
 	zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET &&
 		urb_priv->length == 2;
@@ -3133,7 +3148,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		ret = prepare_transfer(xhci, xhci->devs[slot_id],
 				ep_index, urb->stream_id,
 				1, urb, 1, mem_flags);
-		if (ret < 0)
+		if (unlikely(ret < 0))
 			return ret;
 	}
 
@@ -3147,228 +3162,58 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	start_trb = &ep_ring->enqueue->generic;
 	start_cycle = ep_ring->cycle_state;
 
+	full_len = urb->transfer_buffer_length;
 	running_total = 0;
-	/*
-	 * How much data is in the first TRB?
-	 *
-	 * There are three forces at work for TRB buffer pointers and lengths:
-	 * 1. We don't want to walk off the end of this sg-list entry buffer.
-	 * 2. The transfer length that the driver requested may be smaller than
-	 *    the amount of memory allocated for this scatter-gather list.
-	 * 3. TRBs buffers can't cross 64KB boundaries.
-	 */
-	sg = urb->sg;
-	addr = (u64) sg_dma_address(sg);
-	this_sg_len = sg_dma_len(sg);
-	trb_buff_len = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1));
-	trb_buff_len = min_t(int, trb_buff_len, this_sg_len);
-	if (trb_buff_len > urb->transfer_buffer_length)
-		trb_buff_len = urb->transfer_buffer_length;
-
-	first_trb = true;
-	last_trb_num = zero_length_needed ? 2 : 1;
-	/* Queue the first TRB, even if it's zero-length */
-	do {
-		u32 field = 0;
-		u32 length_field = 0;
-		u32 remainder = 0;
+	block_len = 0;
 
-		/* Don't change the cycle bit of the first TRB until later */
-		if (first_trb) {
-			first_trb = false;
-			if (start_cycle == 0)
-				field |= 0x1;
-		} else
-			field |= ep_ring->cycle_state;
+	/* Queue the TRBs, even if they are zero-length */
+	for (i = 0; i < num_trbs; i++) {
+		field = TRB_TYPE(TRB_NORMAL);
 
-		/* Chain all the TRBs together; clear the chain bit in the last
-		 * TRB to indicate it's the last TRB in the chain.
-		 */
-		if (num_trbs > last_trb_num) {
-			field |= TRB_CHAIN;
-		} else if (num_trbs == last_trb_num) {
-			td->last_trb = ep_ring->enqueue;
-			field |= TRB_IOC;
-		} else if (zero_length_needed && num_trbs == 1) {
-			trb_buff_len = 0;
-			urb_priv->td[1]->last_trb = ep_ring->enqueue;
-			field |= TRB_IOC;
-		}
-
-		/* Only set interrupt on short packet for IN endpoints */
-		if (usb_urb_dir_in(urb))
-			field |= TRB_ISP;
-
-		if (TRB_MAX_BUFF_SIZE -
-				(addr & (TRB_MAX_BUFF_SIZE - 1)) < trb_buff_len) {
-			xhci_warn(xhci, "WARN: sg dma xfer crosses 64KB boundaries!\n");
-			xhci_dbg(xhci, "Next boundary at %#x, end dma = %#x\n",
-					(unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1),
-					(unsigned int) addr + trb_buff_len);
-		}
-
-		/* Set the TRB length, TD size, and interrupter fields. */
-		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) |
-			TRB_TD_SIZE(remainder) |
-			TRB_INTR_TARGET(0);
-
-		if (num_trbs > 1)
-			more_trbs_coming = true;
-		else
-			more_trbs_coming = false;
-		queue_trb(xhci, ep_ring, more_trbs_coming,
-				lower_32_bits(addr),
-				upper_32_bits(addr),
-				length_field,
-				field | TRB_TYPE(TRB_NORMAL));
-		--num_trbs;
-		running_total += trb_buff_len;
-
-		/* Calculate length for next transfer --
-		 * Are we done queueing all the TRBs for this sg entry?
-		 */
-		this_sg_len -= trb_buff_len;
-		if (this_sg_len == 0) {
-			--num_sgs;
-			if (num_sgs == 0)
-				break;
-			sg = sg_next(sg);
-			addr = (u64) sg_dma_address(sg);
-			this_sg_len = sg_dma_len(sg);
+		if (block_len == 0) {
+			/* A new contiguous block. */
+			if (sg) {
+				addr = (u64) sg_dma_address(sg);
+				block_len = sg_dma_len(sg);
+			} else {
+				addr = (u64) urb->transfer_dma;
+				block_len = full_len;
+			}
+			/* TRB buffer should not cross 64KB boundaries */
+			trb_buff_len = TRB_BUFF_LEN_UP_TO_BOUNDARY(addr);
+			trb_buff_len = min_t(unsigned int,
+								trb_buff_len,
+								block_len);
 		} else {
-			addr += trb_buff_len;
+			/* Further through the contiguous block. */
+			trb_buff_len = block_len;
+			if (trb_buff_len > TRB_MAX_BUFF_SIZE)
+				trb_buff_len = TRB_MAX_BUFF_SIZE;
 		}
 
-		trb_buff_len = TRB_MAX_BUFF_SIZE -
-			(addr & (TRB_MAX_BUFF_SIZE - 1));
-		trb_buff_len = min_t(int, trb_buff_len, this_sg_len);
-		if (running_total + trb_buff_len > urb->transfer_buffer_length)
-			trb_buff_len =
-				urb->transfer_buffer_length - running_total;
-	} while (num_trbs > 0);
-
-	check_trb_math(urb, num_trbs, running_total);
-	giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
-			start_cycle, start_trb);
-	return 0;
-}
-
-/* This is very similar to what ehci-q.c qtd_fill() does */
-int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
-		struct urb *urb, int slot_id, unsigned int ep_index)
-{
-	struct xhci_ring *ep_ring;
-	struct urb_priv *urb_priv;
-	struct xhci_td *td;
-	int num_trbs;
-	struct xhci_generic_trb *start_trb;
-	bool first_trb;
-	int last_trb_num;
-	bool more_trbs_coming;
-	bool zero_length_needed;
-	int start_cycle;
-	u32 field, length_field;
-
-	int running_total, trb_buff_len, ret;
-	unsigned int total_packet_count;
-	u64 addr;
-
-	if (urb->num_sgs)
-		return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);
-
-	ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
-	if (!ep_ring)
-		return -EINVAL;
-
-	num_trbs = 0;
-	/* How much data is (potentially) left before the 64KB boundary? */
-	running_total = TRB_MAX_BUFF_SIZE -
-		(urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1));
-	running_total &= TRB_MAX_BUFF_SIZE - 1;
-
-	/* If there's some data on this 64KB chunk, or we have to send a
-	 * zero-length transfer, we need at least one TRB
-	 */
-	if (running_total != 0 || urb->transfer_buffer_length == 0)
-		num_trbs++;
-	/* How many more 64KB chunks to transfer, how many more TRBs? */
-	while (running_total < urb->transfer_buffer_length) {
-		num_trbs++;
-		running_total += TRB_MAX_BUFF_SIZE;
-	}
-
-	ret = prepare_transfer(xhci, xhci->devs[slot_id],
-			ep_index, urb->stream_id,
-			num_trbs, urb, 0, mem_flags);
-	if (ret < 0)
-		return ret;
-
-	urb_priv = urb->hcpriv;
-
-	/* Deal with URB_ZERO_PACKET - need one more td/trb */
-	zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET &&
-		urb_priv->length == 2;
-	if (zero_length_needed) {
-		num_trbs++;
-		xhci_dbg(xhci, "Creating zero length td.\n");
-		ret = prepare_transfer(xhci, xhci->devs[slot_id],
-				ep_index, urb->stream_id,
-				1, urb, 1, mem_flags);
-		if (ret < 0)
-			return ret;
-	}
-
-	td = urb_priv->td[0];
-
-	/*
-	 * Don't give the first TRB to the hardware (by toggling the cycle bit)
-	 * until we've finished creating all the other TRBs.  The ring's cycle
-	 * state may change as we enqueue the other TRBs, so save it too.
-	 */
-	start_trb = &ep_ring->enqueue->generic;
-	start_cycle = ep_ring->cycle_state;
-
-	running_total = 0;
-	total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
-			usb_endpoint_maxp(&urb->ep->desc));
-	/* How much data is in the first TRB? */
-	addr = (u64) urb->transfer_dma;
-	trb_buff_len = TRB_MAX_BUFF_SIZE -
-		(urb->transfer_dma & (TRB_MAX_BUFF_SIZE - 1));
-	if (trb_buff_len > urb->transfer_buffer_length)
-		trb_buff_len = urb->transfer_buffer_length;
-
-	first_trb = true;
-	last_trb_num = zero_length_needed ? 2 : 1;
-	/* Queue the first TRB, even if it's zero-length */
-	do {
-		u32 remainder = 0;
-		field = 0;
+		if (running_total + trb_buff_len > full_len)
+			trb_buff_len = full_len - running_total;
 
 		/* Don't change the cycle bit of the first TRB until later */
-		if (first_trb) {
-			first_trb = false;
+		if (i == 0) {
 			if (start_cycle == 0)
-				field |= 0x1;
+				field |= TRB_CYCLE;
 		} else
 			field |= ep_ring->cycle_state;
 
 		/* Chain all the TRBs together; clear the chain bit in the last
 		 * TRB to indicate it's the last TRB in the chain.
 		 */
-		if (num_trbs > last_trb_num) {
+		if (i < last_trb_num) {
 			field |= TRB_CHAIN;
-		} else if (num_trbs == last_trb_num) {
-			td->last_trb = ep_ring->enqueue;
-			field |= TRB_IOC;
-		} else if (zero_length_needed && num_trbs == 1) {
-			trb_buff_len = 0;
-			urb_priv->td[1]->last_trb = ep_ring->enqueue;
+		} else {
 			field |= TRB_IOC;
+			if (i == last_trb_num)
+				td->last_trb = ep_ring->enqueue;
+			else if (zero_length_needed) {
+				trb_buff_len = 0;
+				urb_priv->td[1]->last_trb = ep_ring->enqueue;
+			}
 		}
 
 		/* Only set interrupt on short packet for IN endpoints */
@@ -3376,15 +3221,15 @@ 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. */
-		remainder = xhci_td_remainder(xhci, running_total, trb_buff_len,
-					   urb->transfer_buffer_length,
-					   urb, num_trbs - 1);
+		remainder = xhci_td_remainder(xhci, running_total,
+							trb_buff_len, full_len,
+							urb, num_trbs - i - 1);
 
 		length_field = TRB_LEN(trb_buff_len) |
 			TRB_TD_SIZE(remainder) |
 			TRB_INTR_TARGET(0);
 
-		if (num_trbs > 1)
+		if (i < num_trbs - 1)
 			more_trbs_coming = true;
 		else
 			more_trbs_coming = false;
@@ -3392,18 +3237,24 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 				lower_32_bits(addr),
 				upper_32_bits(addr),
 				length_field,
-				field | TRB_TYPE(TRB_NORMAL));
-		--num_trbs;
-		running_total += trb_buff_len;
+				field);
 
-		/* Calculate length for next transfer */
+		running_total += trb_buff_len;
 		addr += trb_buff_len;
-		trb_buff_len = urb->transfer_buffer_length - running_total;
-		if (trb_buff_len > TRB_MAX_BUFF_SIZE)
-			trb_buff_len = TRB_MAX_BUFF_SIZE;
-	} while (num_trbs > 0);
+		block_len -= trb_buff_len;
+
+		if (sg) {
+			if (block_len == 0) {
+				/* New sg entry */
+				--num_sgs;
+				if (num_sgs == 0)
+					break;
+				sg = sg_next(sg);
+			}
+		}
+	}
 
-	check_trb_math(urb, num_trbs, running_total);
+	check_trb_math(urb, running_total);
 	giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
 			start_cycle, start_trb);
 	return 0;
@@ -3532,23 +3383,6 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	return 0;
 }
 
-static int count_isoc_trbs_needed(struct xhci_hcd *xhci,
-		struct urb *urb, int i)
-{
-	int num_trbs = 0;
-	u64 addr, td_len;
-
-	addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
-	td_len = urb->iso_frame_desc[i].length;
-
-	num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
-			TRB_MAX_BUFF_SIZE);
-	if (num_trbs == 0)
-		num_trbs++;
-
-	return num_trbs;
-}
-
 /*
  * The transfer burst count field of the isochronous TRB defines the number of
  * bursts that are required to move all packets in this TD.  Only SuperSpeed
@@ -3746,7 +3580,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		last_burst_pkt_count = xhci_get_last_burst_packet_count(xhci,
 							urb, total_pkt_count);
 
-		trbs_per_td = count_isoc_trbs_needed(xhci, urb, i);
+		trbs_per_td = count_isoc_trbs_needed(urb, i);
 
 		ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index,
 				urb->stream_id, trbs_per_td, urb, i, mem_flags);
@@ -3807,8 +3641,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 					field |= TRB_BEI;
 			}
 			/* Calculate TRB length */
-			trb_buff_len = TRB_MAX_BUFF_SIZE -
-				(addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1));
+			trb_buff_len = TRB_BUFF_LEN_UP_TO_BOUNDARY(addr);
 			if (trb_buff_len > td_remain_len)
 				trb_buff_len = td_remain_len;
 
@@ -3897,8 +3730,6 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
 	struct xhci_ring *ep_ring;
 	struct xhci_ep_ctx *ep_ctx;
 	int start_frame;
-	int xhci_interval;
-	int ep_interval;
 	int num_tds, num_trbs, i;
 	int ret;
 	struct xhci_virt_ep *xep;
@@ -3912,7 +3743,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
 	num_trbs = 0;
 	num_tds = urb->number_of_packets;
 	for (i = 0; i < num_tds; i++)
-		num_trbs += count_isoc_trbs_needed(xhci, urb, i);
+		num_trbs += count_isoc_trbs_needed(urb, i);
 
 	/* Check the ring to guarantee there is enough room for the whole urb.
 	 * Do not insert any td of the urb to the ring if the check failed.
@@ -3926,26 +3757,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
 	 * Check interval value. This should be done before we start to
 	 * calculate the start frame value.
 	 */
-	xhci_interval = EP_INTERVAL_TO_UFRAMES(le32_to_cpu(ep_ctx->ep_info));
-	ep_interval = urb->interval;
-	/* Convert to microframes */
-	if (urb->dev->speed == USB_SPEED_LOW ||
-			urb->dev->speed == USB_SPEED_FULL)
-		ep_interval *= 8;
-	/* FIXME change this to a warning and a suggestion to use the new API
-	 * to set the polling interval (once the API is added).
-	 */
-	if (xhci_interval != ep_interval) {
-		dev_dbg_ratelimited(&urb->dev->dev,
-				"Driver uses different interval (%d microframe%s) than xHCI (%d microframe%s)\n",
-				ep_interval, ep_interval == 1 ? "" : "s",
-				xhci_interval, xhci_interval == 1 ? "" : "s");
-		urb->interval = xhci_interval;
-		/* Convert back to frames for LS/FS devices */
-		if (urb->dev->speed == USB_SPEED_LOW ||
-				urb->dev->speed == USB_SPEED_FULL)
-			urb->interval /= 8;
-	}
+	check_interval(xhci, urb, ep_ctx);
 
 	/* Calculate the start frame and put it in urb->start_frame. */
 	if (HCC_CFC(xhci->hcc_params) && !list_empty(&ep_ring->td_list)) {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9e71c96ad74a..fa7e1ef36cd9 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1459,47 +1459,6 @@ free_priv:
 	return ret;
 }
 
-/* Get the right ring for the given URB.
- * If the endpoint supports streams, boundary check the URB's stream ID.
- * If the endpoint doesn't support streams, return the singular endpoint ring.
- */
-static struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
-		struct urb *urb)
-{
-	unsigned int slot_id;
-	unsigned int ep_index;
-	unsigned int stream_id;
-	struct xhci_virt_ep *ep;
-
-	slot_id = urb->dev->slot_id;
-	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
-	stream_id = urb->stream_id;
-	ep = &xhci->devs[slot_id]->eps[ep_index];
-	/* Common case: no streams */
-	if (!(ep->ep_state & EP_HAS_STREAMS))
-		return ep->ring;
-
-	if (stream_id == 0) {
-		xhci_warn(xhci,
-				"WARN: Slot ID %u, ep index %u has streams, "
-				"but URB has no stream ID.\n",
-				slot_id, ep_index);
-		return NULL;
-	}
-
-	if (stream_id < ep->stream_info->num_streams)
-		return ep->stream_info->stream_rings[stream_id];
-
-	xhci_warn(xhci,
-			"WARN: Slot ID %u, ep index %u has "
-			"stream IDs 1 to %u allocated, "
-			"but stream ID %u is requested.\n",
-			slot_id, ep_index,
-			ep->stream_info->num_streams - 1,
-			stream_id);
-	return NULL;
-}
-
 /*
  * Remove the URB's TD from the endpoint ring.  This may cause the HC to stop
  * USB transfers, potentially stopping in the middle of a TRB buffer.  The HC
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 6c629c97f8ad..b0b8d0f8791a 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1338,6 +1338,9 @@ union xhci_trb {
 /* TRB buffer pointers can't cross 64KB boundaries */
 #define TRB_MAX_BUFF_SHIFT		16
 #define TRB_MAX_BUFF_SIZE	(1 << TRB_MAX_BUFF_SHIFT)
+/* How much data is left before the 64KB boundary? */
+#define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr)	(TRB_MAX_BUFF_SIZE - \
+					(addr & (TRB_MAX_BUFF_SIZE - 1)))
 
 struct xhci_segment {
 	union xhci_trb		*trbs;
@@ -1965,4 +1968,15 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_
 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
 
+struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
+		unsigned int slot_id, unsigned int ep_index,
+		unsigned int stream_id);
+static inline struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
+								struct urb *urb)
+{
+	return xhci_triad_to_transfer_ring(xhci, urb->dev->slot_id,
+					xhci_get_endpoint_index(&urb->ep->desc),
+					urb->stream_id);
+}
+
 #endif /* __LINUX_XHCI_HCD_H */
diff --git a/drivers/usb/isp1760/isp1760-if.c b/drivers/usb/isp1760/isp1760-if.c
index 264be4d21706..9535b2872183 100644
--- a/drivers/usb/isp1760/isp1760-if.c
+++ b/drivers/usb/isp1760/isp1760-if.c
@@ -163,7 +163,7 @@ static void isp1761_pci_shutdown(struct pci_dev *dev)
 	printk(KERN_ERR "ips1761_pci_shutdown\n");
 }
 
-static const struct pci_device_id isp1760_plx [] = {
+static const struct pci_device_id isp1760_plx[] = {
 	{
 		.class          = PCI_CLASS_BRIDGE_OTHER << 8,
 		.class_mask     = ~0,
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index f7a7fc21be8a..e9e5ae521fa6 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -268,3 +268,29 @@ config USB_CHAOSKEY
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called chaoskey.
+
+config UCSI
+	tristate "USB Type-C Connector System Software Interface driver"
+	depends on ACPI
+	help
+	  UCSI driver is meant to be used as a convenience tool for desktop and
+	  server systems that are not equipped to handle USB in device mode. It
+	  will always select USB host role for the USB Type-C ports on systems
+	  that provide UCSI interface.
+
+	  USB Type-C Connector System Software Interface (UCSI) is a
+	  specification for an interface that allows the Operating System to
+	  control the USB Type-C ports on a system. Things the need controlling
+	  include the USB Data Role (host or device), and when USB Power
+	  Delivery is supported, the Power Role (source or sink). With USB
+	  Type-C connectors, when two dual role capable devices are attached
+	  together, the data role is selected randomly. Therefore it is
+	  important to give the OS a way to select the role. Otherwise the user
+	  would have to unplug and replug in order in order to attempt to swap
+	  the data and power roles.
+
+	  The UCSI specification can be downloaded from:
+	  http://www.intel.com/content/www/us/en/io/universal-serial-bus/usb-type-c-ucsi-spec.html
+
+	  To compile the driver as a module, choose M here: the module will be
+	  called ucsi.
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 45fd4ac39d3e..2769cf6351b4 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_USB_SEVSEG)		+= usbsevseg.o
 obj-$(CONFIG_USB_YUREX)			+= yurex.o
 obj-$(CONFIG_USB_HSIC_USB3503)		+= usb3503.o
 obj-$(CONFIG_USB_CHAOSKEY)		+= chaoskey.o
+obj-$(CONFIG_UCSI)			+= ucsi.o
 
 obj-$(CONFIG_USB_SISUSBVGA)		+= sisusbvga/
 obj-$(CONFIG_USB_LINK_LAYER_TEST)	+= lvstest.o
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index a22de52cb083..15666ad7c772 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -2420,7 +2420,7 @@ static int sisusb_open(struct inode *inode, struct file *file)
 
 	if (!sisusb->devinit) {
 		if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH ||
-				sisusb->sisusb_dev->speed == USB_SPEED_SUPER) {
+				sisusb->sisusb_dev->speed >= USB_SPEED_SUPER) {
 			if (sisusb_init_gfxdevice(sisusb, 0)) {
 				mutex_unlock(&sisusb->lock);
 				dev_err(&sisusb->sisusb_dev->dev,
@@ -3127,7 +3127,7 @@ static int sisusb_probe(struct usb_interface *intf,
 
 	sisusb->present = 1;
 
-	if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) {
+	if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) {
 		int initscreen = 1;
 #ifdef INCL_SISUSB_CON
 		if (sisusb_first_vc > 0 && sisusb_last_vc > 0 &&
diff --git a/drivers/usb/misc/ucsi.c b/drivers/usb/misc/ucsi.c
new file mode 100644
index 000000000000..07397bddefa3
--- /dev/null
+++ b/drivers/usb/misc/ucsi.c
@@ -0,0 +1,478 @@
+/*
+ * USB Type-C Connector System Software Interface driver
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/acpi.h>
+
+#include "ucsi.h"
+
+/* Double the time defined by MIN_TIME_TO_RESPOND_WITH_BUSY */
+#define UCSI_TIMEOUT_MS 20
+
+enum ucsi_status {
+	UCSI_IDLE = 0,
+	UCSI_BUSY,
+	UCSI_ERROR,
+};
+
+struct ucsi_connector {
+	int num;
+	struct ucsi *ucsi;
+	struct work_struct work;
+	struct ucsi_connector_capability cap;
+};
+
+struct ucsi {
+	struct device *dev;
+	struct ucsi_data __iomem *data;
+
+	enum ucsi_status status;
+	struct completion complete;
+	struct ucsi_capability cap;
+	struct ucsi_connector *connector;
+
+	/* device lock */
+	spinlock_t dev_lock;
+
+	/* PPM Communication lock */
+	struct mutex ppm_lock;
+
+	/* PPM communication flags */
+	unsigned long flags;
+#define EVENT_PENDING	0
+#define COMMAND_PENDING	1
+};
+
+static int ucsi_acpi_cmd(struct ucsi *ucsi, struct ucsi_control *ctrl)
+{
+	uuid_le uuid = UUID_LE(0x6f8398c2, 0x7ca4, 0x11e4,
+			       0xad, 0x36, 0x63, 0x10, 0x42, 0xb5, 0x00, 0x8f);
+	union acpi_object *obj;
+
+	ucsi->data->ctrl.raw_cmd = ctrl->raw_cmd;
+
+	obj = acpi_evaluate_dsm(ACPI_HANDLE(ucsi->dev), uuid.b, 1, 1, NULL);
+	if (!obj) {
+		dev_err(ucsi->dev, "%s: failed to evaluate _DSM\n", __func__);
+		return -EIO;
+	}
+
+	ACPI_FREE(obj);
+	return 0;
+}
+
+static void ucsi_acpi_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct ucsi *ucsi = data;
+	struct ucsi_cci *cci;
+
+	spin_lock(&ucsi->dev_lock);
+
+	ucsi->status = UCSI_IDLE;
+	cci = &ucsi->data->cci;
+
+	/*
+	 * REVISIT: This is not documented behavior, but all known PPMs ACK
+	 * asynchronous events by sending notification with cleared CCI.
+	 */
+	if (!ucsi->data->raw_cci) {
+		if (test_bit(EVENT_PENDING, &ucsi->flags))
+			complete(&ucsi->complete);
+		else
+			dev_WARN(ucsi->dev, "spurious notification\n");
+		goto out_unlock;
+	}
+
+	if (test_bit(COMMAND_PENDING, &ucsi->flags)) {
+		if (cci->busy) {
+			ucsi->status = UCSI_BUSY;
+			complete(&ucsi->complete);
+
+			goto out_unlock;
+		} else if (cci->ack_complete || cci->cmd_complete) {
+			/* Error Indication is only valid with commands */
+			if (cci->error && cci->cmd_complete)
+				ucsi->status = UCSI_ERROR;
+
+			ucsi->data->ctrl.raw_cmd = 0;
+			complete(&ucsi->complete);
+		}
+	}
+
+	if (cci->connector_change) {
+		struct ucsi_connector *con;
+
+		/*
+		 * This is workaround for buggy PPMs that create asynchronous
+		 * event notifications before OPM has enabled them.
+		 */
+		if (!ucsi->connector)
+			goto out_unlock;
+
+		con = ucsi->connector + (cci->connector_change - 1);
+
+		/*
+		 * PPM will not clear the connector specific bit in Connector
+		 * Change Indication field of CCI until the driver has ACK it,
+		 * and the driver can not ACK it before it has been processed.
+		 * The PPM will not generate new events before the first has
+		 * been acknowledged, even if they are for an other connector.
+		 * So only one event at a time.
+		 */
+		if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags))
+			schedule_work(&con->work);
+	}
+out_unlock:
+	spin_unlock(&ucsi->dev_lock);
+}
+
+static int ucsi_ack(struct ucsi *ucsi, u8 cmd)
+{
+	struct ucsi_control ctrl;
+	int ret;
+
+	ctrl.cmd.cmd = UCSI_ACK_CC_CI;
+	ctrl.cmd.length = 0;
+	ctrl.cmd.data = cmd;
+	ret = ucsi_acpi_cmd(ucsi, &ctrl);
+	if (ret)
+		return ret;
+
+	/* Waiting for ACK also with ACK CMD for now */
+	ret = wait_for_completion_timeout(&ucsi->complete,
+					  msecs_to_jiffies(UCSI_TIMEOUT_MS));
+	if (!ret)
+		return -ETIMEDOUT;
+	return 0;
+}
+
+static int ucsi_run_cmd(struct ucsi *ucsi, struct ucsi_control *ctrl,
+			void *data, size_t size)
+{
+	u16 err_value = 0;
+	int ret;
+
+	set_bit(COMMAND_PENDING, &ucsi->flags);
+
+	ret = ucsi_acpi_cmd(ucsi, ctrl);
+	if (ret)
+		goto err_clear_flag;
+
+	ret = wait_for_completion_timeout(&ucsi->complete,
+					  msecs_to_jiffies(UCSI_TIMEOUT_MS));
+	if (!ret) {
+		ret = -ETIMEDOUT;
+		goto err_clear_flag;
+	}
+
+	switch (ucsi->status) {
+	case UCSI_IDLE:
+		if (data)
+			memcpy(data, ucsi->data->message_in, size);
+
+		ret = ucsi_ack(ucsi, UCSI_ACK_CMD);
+		break;
+	case UCSI_BUSY:
+		/* The caller decides whether to cancel or not */
+		ret = -EBUSY;
+		goto err_clear_flag;
+	case UCSI_ERROR:
+		ret = ucsi_ack(ucsi, UCSI_ACK_CMD);
+		if (ret)
+			goto err_clear_flag;
+
+		ctrl->cmd.cmd = UCSI_GET_ERROR_STATUS;
+		ctrl->cmd.length = 0;
+		ctrl->cmd.data = 0;
+		ret = ucsi_acpi_cmd(ucsi, ctrl);
+		if (ret)
+			goto err_clear_flag;
+
+		ret = wait_for_completion_timeout(&ucsi->complete,
+					msecs_to_jiffies(UCSI_TIMEOUT_MS));
+		if (!ret) {
+			ret = -ETIMEDOUT;
+			goto err_clear_flag;
+		}
+
+		memcpy(&err_value, ucsi->data->message_in, sizeof(err_value));
+
+		/* Something has really gone wrong */
+		if (WARN_ON(ucsi->status == UCSI_ERROR)) {
+			ret = -ENODEV;
+			goto err_clear_flag;
+		}
+
+		ret = ucsi_ack(ucsi, UCSI_ACK_CMD);
+		if (ret)
+			goto err_clear_flag;
+
+		switch (err_value) {
+		case UCSI_ERROR_INCOMPATIBLE_PARTNER:
+			ret = -EOPNOTSUPP;
+			break;
+		case UCSI_ERROR_CC_COMMUNICATION_ERR:
+			ret = -ECOMM;
+			break;
+		case UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL:
+			ret = -EIO;
+			break;
+		case UCSI_ERROR_DEAD_BATTERY:
+			dev_warn(ucsi->dev, "Dead battery condition!\n");
+			ret = -EPERM;
+			break;
+		/* The following mean a bug in this driver */
+		case UCSI_ERROR_INVALID_CON_NUM:
+		case UCSI_ERROR_UNREGONIZED_CMD:
+		case UCSI_ERROR_INVALID_CMD_ARGUMENT:
+		default:
+			dev_warn(ucsi->dev,
+				 "%s: possible UCSI driver bug - error %hu\n",
+				 __func__, err_value);
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	}
+	ctrl->raw_cmd = 0;
+err_clear_flag:
+	clear_bit(COMMAND_PENDING, &ucsi->flags);
+	return ret;
+}
+
+static void ucsi_connector_change(struct work_struct *work)
+{
+	struct ucsi_connector *con = container_of(work, struct ucsi_connector,
+						  work);
+	struct ucsi_connector_status constat;
+	struct ucsi *ucsi = con->ucsi;
+	struct ucsi_control ctrl;
+	int ret;
+
+	mutex_lock(&ucsi->ppm_lock);
+
+	ctrl.cmd.cmd = UCSI_GET_CONNECTOR_STATUS;
+	ctrl.cmd.length = 0;
+	ctrl.cmd.data = con->num;
+	ret = ucsi_run_cmd(con->ucsi, &ctrl, &constat, sizeof(constat));
+	if (ret) {
+		dev_err(ucsi->dev, "%s: failed to read connector status (%d)\n",
+			__func__, ret);
+		goto out_ack_event;
+	}
+
+	/* Ignoring disconnections and Alternate Modes */
+	if (!constat.connected || !(constat.change &
+	    (UCSI_CONSTAT_PARTNER_CHANGE | UCSI_CONSTAT_CONNECT_CHANGE)) ||
+	    constat.partner_flags & UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE)
+		goto out_ack_event;
+
+	/* If the partner got USB Host role, attempting swap */
+	if (constat.partner_type & UCSI_CONSTAT_PARTNER_TYPE_DFP) {
+		ctrl.uor.cmd = UCSI_SET_UOR;
+		ctrl.uor.con_num = con->num;
+		ctrl.uor.role = UCSI_UOR_ROLE_DFP;
+
+		ret = ucsi_run_cmd(con->ucsi, &ctrl, NULL, 0);
+		if (ret)
+			dev_err(ucsi->dev, "%s: failed to swap role (%d)\n",
+				__func__, ret);
+	}
+out_ack_event:
+	ucsi_ack(ucsi, UCSI_ACK_EVENT);
+	clear_bit(EVENT_PENDING, &ucsi->flags);
+	mutex_unlock(&ucsi->ppm_lock);
+}
+
+static int ucsi_reset_ppm(struct ucsi *ucsi)
+{
+	int timeout = UCSI_TIMEOUT_MS;
+	struct ucsi_control ctrl;
+	int ret;
+
+	memset(&ctrl, 0, sizeof(ctrl));
+	ctrl.cmd.cmd = UCSI_PPM_RESET;
+	ret = ucsi_acpi_cmd(ucsi, &ctrl);
+	if (ret)
+		return ret;
+
+	/* There is no quarantee the PPM will ever set the RESET_COMPLETE bit */
+	while (!ucsi->data->cci.reset_complete && timeout--)
+		usleep_range(1000, 2000);
+	return 0;
+}
+
+static int ucsi_init(struct ucsi *ucsi)
+{
+	struct ucsi_connector *con;
+	struct ucsi_control ctrl;
+	int ret;
+	int i;
+
+	init_completion(&ucsi->complete);
+	spin_lock_init(&ucsi->dev_lock);
+	mutex_init(&ucsi->ppm_lock);
+
+	/* Reset the PPM */
+	ret = ucsi_reset_ppm(ucsi);
+	if (ret)
+		return ret;
+
+	/*
+	 * REVISIT: Executing second reset to WA an issue seen on some of the
+	 * Broxton based platforms, where the first reset puts the PPM into a
+	 * state where it's unable to recognise some of the commands.
+	 */
+	ret = ucsi_reset_ppm(ucsi);
+	if (ret)
+		return ret;
+
+	mutex_lock(&ucsi->ppm_lock);
+
+	/* Enable basic notifications */
+	ctrl.cmd.cmd = UCSI_SET_NOTIFICATION_ENABLE;
+	ctrl.cmd.length = 0;
+	ctrl.cmd.data = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR;
+	ret = ucsi_run_cmd(ucsi, &ctrl, NULL, 0);
+	if (ret)
+		goto err_reset;
+
+	/* Get PPM capabilities */
+	ctrl.cmd.cmd = UCSI_GET_CAPABILITY;
+	ret = ucsi_run_cmd(ucsi, &ctrl, &ucsi->cap, sizeof(ucsi->cap));
+	if (ret)
+		goto err_reset;
+
+	if (!ucsi->cap.num_connectors) {
+		ret = -ENODEV;
+		goto err_reset;
+	}
+
+	ucsi->connector = devm_kcalloc(ucsi->dev, ucsi->cap.num_connectors,
+				       sizeof(*ucsi->connector), GFP_KERNEL);
+	if (!ucsi->connector) {
+		ret = -ENOMEM;
+		goto err_reset;
+	}
+
+	for (i = 1, con = ucsi->connector; i < ucsi->cap.num_connectors + 1;
+	     i++, con++) {
+		/* Get connector capability */
+		ctrl.cmd.cmd = UCSI_GET_CONNECTOR_CAPABILITY;
+		ctrl.cmd.data = i;
+		ret = ucsi_run_cmd(ucsi, &ctrl, &con->cap, sizeof(con->cap));
+		if (ret)
+			goto err_reset;
+
+		con->num = i;
+		con->ucsi = ucsi;
+		INIT_WORK(&con->work, ucsi_connector_change);
+	}
+
+	/* Enable all notifications */
+	ctrl.cmd.cmd = UCSI_SET_NOTIFICATION_ENABLE;
+	ctrl.cmd.data = UCSI_ENABLE_NTFY_ALL;
+	ret = ucsi_run_cmd(ucsi, &ctrl, NULL, 0);
+	if (ret < 0)
+		goto err_reset;
+
+	mutex_unlock(&ucsi->ppm_lock);
+	return 0;
+err_reset:
+	ucsi_reset_ppm(ucsi);
+	mutex_unlock(&ucsi->ppm_lock);
+	return ret;
+}
+
+static int ucsi_acpi_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	acpi_status status;
+	struct ucsi *ucsi;
+	int ret;
+
+	ucsi = devm_kzalloc(&pdev->dev, sizeof(*ucsi), GFP_KERNEL);
+	if (!ucsi)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "missing memory resource\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * NOTE: ACPI has claimed the memory region as it's also an Operation
+	 * Region. It's not possible to request it in the driver.
+	 */
+	ucsi->data = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!ucsi->data)
+		return -ENOMEM;
+
+	ucsi->dev = &pdev->dev;
+
+	status = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev),
+					     ACPI_ALL_NOTIFY,
+					     ucsi_acpi_notify, ucsi);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	ret = ucsi_init(ucsi);
+	if (ret) {
+		acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev),
+					   ACPI_ALL_NOTIFY,
+					   ucsi_acpi_notify);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, ucsi);
+	return 0;
+}
+
+static int ucsi_acpi_remove(struct platform_device *pdev)
+{
+	struct ucsi *ucsi = platform_get_drvdata(pdev);
+
+	acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev),
+				   ACPI_ALL_NOTIFY, ucsi_acpi_notify);
+
+	/* Make sure there are no events in the middle of being processed */
+	if (wait_on_bit_timeout(&ucsi->flags, EVENT_PENDING,
+				TASK_UNINTERRUPTIBLE,
+				msecs_to_jiffies(UCSI_TIMEOUT_MS)))
+		dev_WARN(ucsi->dev, "%s: Events still pending\n", __func__);
+
+	ucsi_reset_ppm(ucsi);
+	return 0;
+}
+
+static const struct acpi_device_id ucsi_acpi_match[] = {
+	{ "PNP0CA0", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, ucsi_acpi_match);
+
+static struct platform_driver ucsi_acpi_platform_driver = {
+	.driver = {
+		.name = "ucsi_acpi",
+		.acpi_match_table = ACPI_PTR(ucsi_acpi_match),
+	},
+	.probe = ucsi_acpi_probe,
+	.remove = ucsi_acpi_remove,
+};
+
+module_platform_driver(ucsi_acpi_platform_driver);
+
+MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("USB Type-C System Software Interface (UCSI) driver");
diff --git a/drivers/usb/misc/ucsi.h b/drivers/usb/misc/ucsi.h
new file mode 100644
index 000000000000..6dd11d1fe225
--- /dev/null
+++ b/drivers/usb/misc/ucsi.h
@@ -0,0 +1,215 @@
+
+#include <linux/types.h>
+
+/* -------------------------------------------------------------------------- */
+
+/* Command Status and Connector Change Indication (CCI) data structure */
+struct ucsi_cci {
+	unsigned int RESERVED1:1;
+	unsigned int connector_change:7;
+	u8 data_length;
+	unsigned int RESERVED9:9;
+	unsigned int not_supported:1;
+	unsigned int cancel_complete:1;
+	unsigned int reset_complete:1;
+	unsigned int busy:1;
+	unsigned int ack_complete:1;
+	unsigned int error:1;
+	unsigned int cmd_complete:1;
+} __packed;
+
+/* Default fields in CONTROL data structure */
+struct ucsi_command {
+	u8 cmd;
+	u8 length;
+	u64 data:48;
+} __packed;
+
+/* Set USB Operation Mode Command structure */
+struct ucsi_uor_cmd {
+	u8 cmd;
+	u8 length;
+	u64 con_num:7;
+	u64 role:3;
+#define UCSI_UOR_ROLE_DFP			BIT(0)
+#define UCSI_UOR_ROLE_UFP			BIT(1)
+#define UCSI_UOR_ROLE_DRP			BIT(2)
+	u64 data:38;
+} __packed;
+
+struct ucsi_control {
+	union {
+		u64 raw_cmd;
+		struct ucsi_command cmd;
+		struct ucsi_uor_cmd uor;
+	};
+};
+
+struct ucsi_data {
+	u16 version;
+	u16 RESERVED;
+	union {
+		u32 raw_cci;
+		struct ucsi_cci cci;
+	};
+	struct ucsi_control ctrl;
+	u32 message_in[4];
+	u32 message_out[4];
+} __packed;
+
+/* Commands */
+#define UCSI_PPM_RESET			0x01
+#define UCSI_CANCEL			0x02
+#define UCSI_CONNECTOR_RESET		0x03
+#define UCSI_ACK_CC_CI			0x04
+#define UCSI_SET_NOTIFICATION_ENABLE	0x05
+#define UCSI_GET_CAPABILITY		0x06
+#define UCSI_GET_CONNECTOR_CAPABILITY	0x07
+#define UCSI_SET_UOM			0x08
+#define UCSI_SET_UOR			0x09
+#define UCSI_SET_PDM			0x0A
+#define UCSI_SET_PDR			0x0B
+#define UCSI_GET_ALTERNATE_MODES	0x0C
+#define UCSI_GET_CAM_SUPPORTED		0x0D
+#define UCSI_GET_CURRENT_CAM		0x0E
+#define UCSI_SET_NEW_CAM		0x0F
+#define UCSI_GET_PDOS			0x10
+#define UCSI_GET_CABLE_PROPERTY		0x11
+#define UCSI_GET_CONNECTOR_STATUS	0x12
+#define UCSI_GET_ERROR_STATUS		0x13
+
+/* ACK_CC_CI commands */
+#define UCSI_ACK_EVENT			1
+#define UCSI_ACK_CMD			2
+
+/* Bits for SET_NOTIFICATION_ENABLE command */
+#define UCSI_ENABLE_NTFY_CMD_COMPLETE		BIT(0)
+#define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE	BIT(1)
+#define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE	BIT(2)
+#define UCSI_ENABLE_NTFY_CAP_CHANGE		BIT(5)
+#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE	BIT(6)
+#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE	BIT(7)
+#define UCSI_ENABLE_NTFY_CAM_CHANGE		BIT(8)
+#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE	BIT(9)
+#define UCSI_ENABLE_NTFY_PARTNER_CHANGE		BIT(11)
+#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE		BIT(12)
+#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE	BIT(14)
+#define UCSI_ENABLE_NTFY_ERROR			BIT(15)
+#define UCSI_ENABLE_NTFY_ALL			0xdbe7
+
+/* Error information returned by PPM in response to GET_ERROR_STATUS command. */
+#define UCSI_ERROR_UNREGONIZED_CMD		BIT(0)
+#define UCSI_ERROR_INVALID_CON_NUM		BIT(1)
+#define UCSI_ERROR_INVALID_CMD_ARGUMENT		BIT(2)
+#define UCSI_ERROR_INCOMPATIBLE_PARTNER		BIT(3)
+#define UCSI_ERROR_CC_COMMUNICATION_ERR		BIT(4)
+#define UCSI_ERROR_DEAD_BATTERY			BIT(5)
+#define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL	BIT(6)
+
+/* Data structure filled by PPM in response to GET_CAPABILITY command. */
+struct ucsi_capability {
+	u32 attributes;
+#define UCSI_CAP_ATTR_DISABLE_STATE		BIT(0)
+#define UCSI_CAP_ATTR_BATTERY_CHARGING		BIT(1)
+#define UCSI_CAP_ATTR_USB_PD			BIT(2)
+#define UCSI_CAP_ATTR_TYPEC_CURRENT		BIT(6)
+#define UCSI_CAP_ATTR_POWER_AC_SUPPLY		BIT(8)
+#define UCSI_CAP_ATTR_POWER_OTHER		BIT(10)
+#define UCSI_CAP_ATTR_POWER_VBUS		BIT(14)
+	u8 num_connectors;
+	u32 features:24;
+#define UCSI_CAP_SET_UOM			BIT(0)
+#define UCSI_CAP_SET_PDM			BIT(1)
+#define UCSI_CAP_ALT_MODE_DETAILS		BIT(2)
+#define UCSI_CAP_ALT_MODE_OVERRIDE		BIT(3)
+#define UCSI_CAP_PDO_DETAILS			BIT(4)
+#define UCSI_CAP_CABLE_DETAILS			BIT(5)
+#define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS	BIT(6)
+#define UCSI_CAP_PD_RESET			BIT(7)
+	u8 num_alt_modes;
+	u8 RESERVED;
+	u16 bc_version;
+	u16 pd_version;
+	u16 typec_version;
+} __packed;
+
+/* Data structure filled by PPM in response to GET_CONNECTOR_CAPABILITY cmd. */
+struct ucsi_connector_capability {
+	u8 op_mode;
+#define UCSI_CONCAP_OPMODE_DFP			BIT(0)
+#define UCSI_CONCAP_OPMODE_UFP			BIT(1)
+#define UCSI_CONCAP_OPMODE_DRP			BIT(2)
+#define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY	BIT(3)
+#define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY	BIT(4)
+#define UCSI_CONCAP_OPMODE_USB2			BIT(5)
+#define UCSI_CONCAP_OPMODE_USB3			BIT(6)
+#define UCSI_CONCAP_OPMODE_ALT_MODE		BIT(7)
+	u8 provider:1;
+	u8 consumer:1;
+} __packed;
+
+/* Data structure filled by PPM in response to GET_CABLE_PROPERTY command. */
+struct ucsi_cable_property {
+	u16 speed_supported;
+	u8 current_capability;
+	u8 vbus_in_cable:1;
+	u8 active_cable:1;
+	u8 directionality:1;
+	u8 plug_type:2;
+#define UCSI_CABLE_PROPERTY_PLUG_TYPE_A		0
+#define UCSI_CABLE_PROPERTY_PLUG_TYPE_B		1
+#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C		2
+#define UCSI_CABLE_PROPERTY_PLUG_OTHER		3
+	u8 mode_support:1;
+	u8 RESERVED_2:2;
+	u8 latency:4;
+	u8 RESERVED_4:4;
+} __packed;
+
+/* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */
+struct ucsi_connector_status {
+	u16 change;
+#define UCSI_CONSTAT_EXT_SUPPLY_CHANGE		BIT(1)
+#define UCSI_CONSTAT_POWER_OPMODE_CHANGE	BIT(2)
+#define UCSI_CONSTAT_PDOS_CHANGE		BIT(5)
+#define UCSI_CONSTAT_POWER_LEVEL_CHANGE		BIT(6)
+#define UCSI_CONSTAT_PD_RESET_COMPLETE		BIT(7)
+#define UCSI_CONSTAT_CAM_CHANGE			BIT(8)
+#define UCSI_CONSTAT_BC_CHANGE			BIT(9)
+#define UCSI_CONSTAT_PARTNER_CHANGE		BIT(11)
+#define UCSI_CONSTAT_POWER_DIR_CHANGE		BIT(12)
+#define UCSI_CONSTAT_CONNECT_CHANGE		BIT(14)
+#define UCSI_CONSTAT_ERROR			BIT(15)
+	u16 pwr_op_mode:3;
+#define UCSI_CONSTAT_PWR_OPMODE_NONE		0
+#define UCSI_CONSTAT_PWR_OPMODE_DEFAULT		1
+#define UCSI_CONSTAT_PWR_OPMODE_BC		2
+#define UCSI_CONSTAT_PWR_OPMODE_PD		3
+#define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_3	4
+#define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0	5
+	u16 connected:1;
+	u16 pwr_dir:1;
+	u16 partner_flags:8;
+#define UCSI_CONSTAT_PARTNER_FLAG_USB		BIT(0)
+#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE	BIT(1)
+	u16 partner_type:3;
+#define UCSI_CONSTAT_PARTNER_TYPE_DFP		1
+#define UCSI_CONSTAT_PARTNER_TYPE_UFP		2
+#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_NO_UFP	3 /* Powered Cable */
+#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP	4 /* Powered Cable */
+#define UCSI_CONSTAT_PARTNER_TYPE_DEBUG		5
+#define UCSI_CONSTAT_PARTNER_TYPE_AUDIO		6
+	u32 request_data_obj;
+	u8 bc_status:2;
+#define UCSI_CONSTAT_BC_NOT_CHARGING		0
+#define UCSI_CONSTAT_BC_NOMINAL_CHARGING	1
+#define UCSI_CONSTAT_BC_SLOW_CHARGING		2
+#define UCSI_CONSTAT_BC_TRICKLE_CHARGING	3
+	u8 provider_cap_limit_reason:4;
+#define UCSI_CONSTAT_CAP_PWR_LOWERED		0
+#define UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT	1
+	u8 RESERVED:2;
+} __packed;
+
+/* -------------------------------------------------------------------------- */
+
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 92fdb6e9faff..6b978f04b8d7 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -287,6 +287,9 @@ static struct urb *usbtest_alloc_urb(
 	if (usb_pipein(pipe))
 		urb->transfer_flags |= URB_SHORT_NOT_OK;
 
+	if ((bytes + offset) == 0)
+		return urb;
+
 	if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 		urb->transfer_buffer = usb_alloc_coherent(udev, bytes + offset,
 			GFP_KERNEL, &urb->transfer_dma);
@@ -529,6 +532,7 @@ static struct scatterlist *
 alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
 {
 	struct scatterlist	*sg;
+	unsigned int		n_size = 0;
 	unsigned		i;
 	unsigned		size = max;
 	unsigned		maxpacket =
@@ -561,7 +565,8 @@ alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
 			break;
 		case 1:
 			for (j = 0; j < size; j++)
-				*buf++ = (u8) ((j % maxpacket) % 63);
+				*buf++ = (u8) (((j + n_size) % maxpacket) % 63);
+			n_size += size;
 			break;
 		}
 
diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c
index 3d7af85aecb9..d8593adb3621 100644
--- a/drivers/usb/phy/phy-qcom-8x16-usb.c
+++ b/drivers/usb/phy/phy-qcom-8x16-usb.c
@@ -240,10 +240,7 @@ static int phy_8x16_read_devicetree(struct phy_8x16 *qphy)
 
 	qphy->switch_gpio = devm_gpiod_get_optional(dev, "switch",
 						   GPIOD_OUT_LOW);
-	if (IS_ERR(qphy->switch_gpio))
-		return PTR_ERR(qphy->switch_gpio);
-
-	return 0;
+	return PTR_ERR_OR_ZERO(qphy->switch_gpio);
 }
 
 static int phy_8x16_reboot_notify(struct notifier_block *this,
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 014dbbd72132..24e2b3cf1867 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -155,13 +155,13 @@ static int twl6030_start_srp(struct phy_companion *comparator)
 static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
 {
 	/* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */
-	twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG);
+	twl6030_writeb(twl, TWL6030_MODULE_ID0, 0x1, TWL6030_BACKUP_REG);
 
 	/* Program CFG_LDO_PD2 register and set VUSB bit */
-	twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_CFG_LDO_PD2);
+	twl6030_writeb(twl, TWL6030_MODULE_ID0, 0x1, TWL6030_CFG_LDO_PD2);
 
 	/* Program MISC2 register and set bit VUSB_IN_VBAT */
-	twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2);
+	twl6030_writeb(twl, TWL6030_MODULE_ID0, 0x10, TWL6030_MISC2);
 
 	twl->usb3v3 = regulator_get(twl->dev, twl->regulator);
 	if (IS_ERR(twl->usb3v3))
@@ -301,10 +301,10 @@ static void otg_set_vbus_work(struct work_struct *data)
 	 */
 
 	if (twl->vbus_enable)
-		twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40,
+		twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE, 0x40,
 							CHARGERUSB_CTRL1);
 	else
-		twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00,
+		twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE, 0x00,
 							CHARGERUSB_CTRL1);
 }
 
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 000f9750149f..7be4e7d57ace 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -799,8 +799,10 @@ static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
 	struct usbhs_pipe *pipe = pkt->pipe;
 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
 	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
+	struct usbhs_fifo *fifo = usbhs_pipe_to_fifo(pipe);
+	struct dma_chan *chan = usbhsf_dma_chan_get(fifo, pkt);
 
-	return info->dma_map_ctrl(pkt, map);
+	return info->dma_map_ctrl(chan->device->dev, pkt, map);
 }
 
 static void usbhsf_dma_complete(void *arg);
@@ -881,12 +883,12 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
 	if (!fifo)
 		goto usbhsf_pio_prepare_push;
 
-	if (usbhsf_dma_map(pkt) < 0)
-		goto usbhsf_pio_prepare_push;
-
 	ret = usbhsf_fifo_select(pipe, fifo, 0);
 	if (ret < 0)
-		goto usbhsf_pio_prepare_push_unmap;
+		goto usbhsf_pio_prepare_push;
+
+	if (usbhsf_dma_map(pkt) < 0)
+		goto usbhsf_pio_prepare_push_unselect;
 
 	pkt->trans = len;
 
@@ -896,8 +898,8 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
 
 	return 0;
 
-usbhsf_pio_prepare_push_unmap:
-	usbhsf_dma_unmap(pkt);
+usbhsf_pio_prepare_push_unselect:
+	usbhsf_fifo_unselect(pipe, fifo);
 usbhsf_pio_prepare_push:
 	/*
 	 * change handler to PIO
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 53d104b56ef1..30345c2d01be 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -191,13 +191,12 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep,
 /*
  *		dma map/unmap
  */
-static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
+static int usbhsg_dma_map_ctrl(struct device *dma_dev, struct usbhs_pkt *pkt,
+			       int map)
 {
 	struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
 	struct usb_request *req = &ureq->req;
 	struct usbhs_pipe *pipe = pkt->pipe;
-	struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
-	struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
 	enum dma_data_direction dir;
 	int ret = 0;
 
@@ -207,13 +206,13 @@ static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
 		/* it can not use scatter/gather */
 		WARN_ON(req->num_sgs);
 
-		ret = usb_gadget_map_request(&gpriv->gadget, req, dir);
+		ret = usb_gadget_map_request_by_dev(dma_dev, req, dir);
 		if (ret < 0)
 			return ret;
 
 		pkt->dma = req->dma;
 	} else {
-		usb_gadget_unmap_request(&gpriv->gadget, req, dir);
+		usb_gadget_unmap_request_by_dev(dma_dev, req, dir);
 	}
 
 	return ret;
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 1a8e4c45c4c5..3bf0b72eb359 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -929,7 +929,8 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd,
 /*
  *		dma map functions
  */
-static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map)
+static int usbhsh_dma_map_ctrl(struct device *dma_dev, struct usbhs_pkt *pkt,
+			       int map)
 {
 	if (map) {
 		struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt);
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 78e9dba701c4..c238772b9e9e 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -391,9 +391,8 @@ void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
 /*
  *		pipe setup
  */
-static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
-				int is_host,
-				int dir_in)
+static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host,
+				int dir_in, u16 *pipecfg)
 {
 	u16 type = 0;
 	u16 bfre = 0;
@@ -451,14 +450,14 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
 
 	/* EPNUM */
 	epnum = 0; /* see usbhs_pipe_config_update() */
-
-	return	type	|
-		bfre	|
-		dblb	|
-		cntmd	|
-		dir	|
-		shtnak	|
-		epnum;
+	*pipecfg = type		|
+		   bfre		|
+		   dblb		|
+		   cntmd	|
+		   dir		|
+		   shtnak	|
+		   epnum;
+	return 0;
 }
 
 static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
@@ -655,7 +654,8 @@ static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
 }
 
 void usbhs_pipe_init(struct usbhs_priv *priv,
-		     int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
+		     int (*dma_map_ctrl)(struct device *dma_dev,
+					 struct usbhs_pkt *pkt, int map))
 {
 	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
 	struct usbhs_pipe *pipe;
@@ -702,7 +702,11 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
 		return NULL;
 	}
 
-	pipecfg  = usbhsp_setup_pipecfg(pipe, is_host, dir_in);
+	if (usbhsp_setup_pipecfg(pipe, is_host, dir_in, &pipecfg)) {
+		dev_err(dev, "can't setup pipe\n");
+		return NULL;
+	}
+
 	pipebuf  = usbhsp_setup_pipebuff(pipe);
 
 	usbhsp_pipe_select(pipe);
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 7835747f9803..95185fdb29b1 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -47,7 +47,8 @@ struct usbhs_pipe_info {
 	struct usbhs_pipe *pipe;
 	int size;	/* array size of "pipe" */
 
-	int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map);
+	int (*dma_map_ctrl)(struct device *dma_dev, struct usbhs_pkt *pkt,
+			    int map);
 };
 
 /*
@@ -84,7 +85,8 @@ int usbhs_pipe_is_running(struct usbhs_pipe *pipe);
 void usbhs_pipe_running(struct usbhs_pipe *pipe, int running);
 
 void usbhs_pipe_init(struct usbhs_priv *priv,
-		     int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map));
+		     int (*dma_map_ctrl)(struct device *dma_dev,
+					 struct usbhs_pkt *pkt, int map));
 int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
 void usbhs_pipe_clear(struct usbhs_pipe *pipe);
 int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 7c9f25e9c422..96a70789b4c2 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -331,6 +331,42 @@ struct cp210x_comm_status {
  */
 #define PURGE_ALL		0x000f
 
+/* CP210X_GET_FLOW/CP210X_SET_FLOW read/write these 0x10 bytes */
+struct cp210x_flow_ctl {
+	__le32	ulControlHandshake;
+	__le32	ulFlowReplace;
+	__le32	ulXonLimit;
+	__le32	ulXoffLimit;
+} __packed;
+
+/* cp210x_flow_ctl::ulControlHandshake */
+#define CP210X_SERIAL_DTR_MASK		GENMASK(1, 0)
+#define CP210X_SERIAL_DTR_SHIFT(_mode)	(_mode)
+#define CP210X_SERIAL_CTS_HANDSHAKE	BIT(3)
+#define CP210X_SERIAL_DSR_HANDSHAKE	BIT(4)
+#define CP210X_SERIAL_DCD_HANDSHAKE	BIT(5)
+#define CP210X_SERIAL_DSR_SENSITIVITY	BIT(6)
+
+/* values for cp210x_flow_ctl::ulControlHandshake::CP210X_SERIAL_DTR_MASK */
+#define CP210X_SERIAL_DTR_INACTIVE	0
+#define CP210X_SERIAL_DTR_ACTIVE	1
+#define CP210X_SERIAL_DTR_FLOW_CTL	2
+
+/* cp210x_flow_ctl::ulFlowReplace */
+#define CP210X_SERIAL_AUTO_TRANSMIT	BIT(0)
+#define CP210X_SERIAL_AUTO_RECEIVE	BIT(1)
+#define CP210X_SERIAL_ERROR_CHAR	BIT(2)
+#define CP210X_SERIAL_NULL_STRIPPING	BIT(3)
+#define CP210X_SERIAL_BREAK_CHAR	BIT(4)
+#define CP210X_SERIAL_RTS_MASK		GENMASK(7, 6)
+#define CP210X_SERIAL_RTS_SHIFT(_mode)	(_mode << 6)
+#define CP210X_SERIAL_XOFF_CONTINUE	BIT(31)
+
+/* values for cp210x_flow_ctl::ulFlowReplace::CP210X_SERIAL_RTS_MASK */
+#define CP210X_SERIAL_RTS_INACTIVE	0
+#define CP210X_SERIAL_RTS_ACTIVE	1
+#define CP210X_SERIAL_RTS_FLOW_CTL	2
+
 /*
  * Reads a variable-sized block of CP210X_ registers, identified by req.
  * Returns data into buf in native USB byte order.
@@ -698,9 +734,10 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
 {
 	struct device *dev = &port->dev;
 	unsigned int cflag;
-	u8 modem_ctl[16];
+	struct cp210x_flow_ctl flow_ctl;
 	u32 baud;
 	u16 bits;
+	u32 ctl_hs;
 
 	cp210x_read_u32_reg(port, CP210X_GET_BAUDRATE, &baud);
 
@@ -796,9 +833,10 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
 		break;
 	}
 
-	cp210x_read_reg_block(port, CP210X_GET_FLOW, modem_ctl,
-			sizeof(modem_ctl));
-	if (modem_ctl[0] & 0x08) {
+	cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
+			sizeof(flow_ctl));
+	ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
+	if (ctl_hs & CP210X_SERIAL_CTS_HANDSHAKE) {
 		dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__);
 		cflag |= CRTSCTS;
 	} else {
@@ -867,7 +905,6 @@ static void cp210x_set_termios(struct tty_struct *tty,
 	struct device *dev = &port->dev;
 	unsigned int cflag, old_cflag;
 	u16 bits;
-	u8 modem_ctl[16];
 
 	cflag = tty->termios.c_cflag;
 	old_cflag = old_termios->c_cflag;
@@ -951,35 +988,44 @@ static void cp210x_set_termios(struct tty_struct *tty,
 	}
 
 	if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
-
-		/* Only bytes 0, 4 and 7 out of first 8 have functional bits */
-
-		cp210x_read_reg_block(port, CP210X_GET_FLOW, modem_ctl,
-				sizeof(modem_ctl));
-		dev_dbg(dev, "%s - read modem controls = %02x .. .. .. %02x .. .. %02x\n",
-			__func__, modem_ctl[0], modem_ctl[4], modem_ctl[7]);
-
+		struct cp210x_flow_ctl flow_ctl;
+		u32 ctl_hs;
+		u32 flow_repl;
+
+		cp210x_read_reg_block(port, CP210X_GET_FLOW, &flow_ctl,
+				sizeof(flow_ctl));
+		ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake);
+		flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace);
+		dev_dbg(dev, "%s - read ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n",
+				__func__, ctl_hs, flow_repl);
+
+		ctl_hs &= ~CP210X_SERIAL_DSR_HANDSHAKE;
+		ctl_hs &= ~CP210X_SERIAL_DCD_HANDSHAKE;
+		ctl_hs &= ~CP210X_SERIAL_DSR_SENSITIVITY;
+		ctl_hs &= ~CP210X_SERIAL_DTR_MASK;
+		ctl_hs |= CP210X_SERIAL_DTR_SHIFT(CP210X_SERIAL_DTR_ACTIVE);
 		if (cflag & CRTSCTS) {
-			modem_ctl[0] &= ~0x7B;
-			modem_ctl[0] |= 0x09;
-			modem_ctl[4] = 0x80;
-			/* FIXME - why clear reserved bits just read? */
-			modem_ctl[5] = 0;
-			modem_ctl[6] = 0;
-			modem_ctl[7] = 0;
+			ctl_hs |= CP210X_SERIAL_CTS_HANDSHAKE;
+
+			flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+			flow_repl |= CP210X_SERIAL_RTS_SHIFT(
+					CP210X_SERIAL_RTS_FLOW_CTL);
 			dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__);
 		} else {
-			modem_ctl[0] &= ~0x7B;
-			modem_ctl[0] |= 0x01;
-			/* FIXME - OR here instead of assignment looks wrong */
-			modem_ctl[4] |= 0x40;
+			ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE;
+
+			flow_repl &= ~CP210X_SERIAL_RTS_MASK;
+			flow_repl |= CP210X_SERIAL_RTS_SHIFT(
+					CP210X_SERIAL_RTS_ACTIVE);
 			dev_dbg(dev, "%s - flow control = NONE\n", __func__);
 		}
 
-		dev_dbg(dev, "%s - write modem controls = %02x .. .. .. %02x .. .. %02x\n",
-			__func__, modem_ctl[0], modem_ctl[4], modem_ctl[7]);
-		cp210x_write_reg_block(port, CP210X_SET_FLOW, modem_ctl,
-				sizeof(modem_ctl));
+		dev_dbg(dev, "%s - write ulControlHandshake=0x%08x, ulFlowReplace=0x%08x\n",
+				__func__, ctl_hs, flow_repl);
+		flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs);
+		flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl);
+		cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl,
+				sizeof(flow_ctl));
 	}
 
 }
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 3a814e802dee..00820809139a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -93,27 +93,27 @@ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
 static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
 static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
 
-static struct ftdi_sio_quirk ftdi_jtag_quirk = {
+static const struct ftdi_sio_quirk ftdi_jtag_quirk = {
 	.probe	= ftdi_jtag_probe,
 };
 
-static struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
+static const struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
 	.probe	= ftdi_NDI_device_setup,
 };
 
-static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
+static const struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
 	.port_probe = ftdi_USB_UIRT_setup,
 };
 
-static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
+static const struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
 	.port_probe = ftdi_HE_TIRA1_setup,
 };
 
-static struct ftdi_sio_quirk ftdi_stmclite_quirk = {
+static const struct ftdi_sio_quirk ftdi_stmclite_quirk = {
 	.probe	= ftdi_stmclite_probe,
 };
 
-static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
+static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
 	.probe	= ftdi_8u2232c_probe,
 };
 
@@ -1775,7 +1775,7 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
 static int ftdi_sio_probe(struct usb_serial *serial,
 					const struct usb_device_id *id)
 {
-	struct ftdi_sio_quirk *quirk =
+	const struct ftdi_sio_quirk *quirk =
 				(struct ftdi_sio_quirk *)id->driver_info;
 
 	if (quirk && quirk->probe) {
@@ -1792,7 +1792,7 @@ static int ftdi_sio_probe(struct usb_serial *serial,
 static int ftdi_sio_port_probe(struct usb_serial_port *port)
 {
 	struct ftdi_private *priv;
-	struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
+	const struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
 
 
 	priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL);
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index f3007ecdd1b4..11c05ce2f35f 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2849,14 +2849,16 @@ static int edge_startup(struct usb_serial *serial)
 				/* not set up yet, so do it now */
 				edge_serial->interrupt_read_urb =
 						usb_alloc_urb(0, GFP_KERNEL);
-				if (!edge_serial->interrupt_read_urb)
-					return -ENOMEM;
+				if (!edge_serial->interrupt_read_urb) {
+					response = -ENOMEM;
+					break;
+				}
 
 				edge_serial->interrupt_in_buffer =
 					kmalloc(buffer_size, GFP_KERNEL);
 				if (!edge_serial->interrupt_in_buffer) {
-					usb_free_urb(edge_serial->interrupt_read_urb);
-					return -ENOMEM;
+					response = -ENOMEM;
+					break;
 				}
 				edge_serial->interrupt_in_endpoint =
 						endpoint->bEndpointAddress;
@@ -2884,14 +2886,16 @@ static int edge_startup(struct usb_serial *serial)
 				/* not set up yet, so do it now */
 				edge_serial->read_urb =
 						usb_alloc_urb(0, GFP_KERNEL);
-				if (!edge_serial->read_urb)
-					return -ENOMEM;
+				if (!edge_serial->read_urb) {
+					response = -ENOMEM;
+					break;
+				}
 
 				edge_serial->bulk_in_buffer =
 					kmalloc(buffer_size, GFP_KERNEL);
 				if (!edge_serial->bulk_in_buffer) {
-					usb_free_urb(edge_serial->read_urb);
-					return -ENOMEM;
+					response = -ENOMEM;
+					break;
 				}
 				edge_serial->bulk_in_endpoint =
 						endpoint->bEndpointAddress;
@@ -2917,9 +2921,22 @@ static int edge_startup(struct usb_serial *serial)
 			}
 		}
 
-		if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
-			dev_err(ddev, "Error - the proper endpoints were not found!\n");
-			return -ENODEV;
+		if (response || !interrupt_in_found || !bulk_in_found ||
+							!bulk_out_found) {
+			if (!response) {
+				dev_err(ddev, "expected endpoints not found\n");
+				response = -ENODEV;
+			}
+
+			usb_free_urb(edge_serial->interrupt_read_urb);
+			kfree(edge_serial->interrupt_in_buffer);
+
+			usb_free_urb(edge_serial->read_urb);
+			kfree(edge_serial->bulk_in_buffer);
+
+			kfree(edge_serial);
+
+			return response;
 		}
 
 		/* start interrupt read for this edgeport this interrupt will
@@ -2942,16 +2959,9 @@ static void edge_disconnect(struct usb_serial *serial)
 {
 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
 
-	/* stop reads and writes on all ports */
-	/* free up our endpoint stuff */
 	if (edge_serial->is_epic) {
 		usb_kill_urb(edge_serial->interrupt_read_urb);
-		usb_free_urb(edge_serial->interrupt_read_urb);
-		kfree(edge_serial->interrupt_in_buffer);
-
 		usb_kill_urb(edge_serial->read_urb);
-		usb_free_urb(edge_serial->read_urb);
-		kfree(edge_serial->bulk_in_buffer);
 	}
 }
 
@@ -2964,6 +2974,16 @@ static void edge_release(struct usb_serial *serial)
 {
 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
 
+	if (edge_serial->is_epic) {
+		usb_kill_urb(edge_serial->interrupt_read_urb);
+		usb_free_urb(edge_serial->interrupt_read_urb);
+		kfree(edge_serial->interrupt_in_buffer);
+
+		usb_kill_urb(edge_serial->read_urb);
+		usb_free_urb(edge_serial->read_urb);
+		kfree(edge_serial->bulk_in_buffer);
+	}
+
 	kfree(edge_serial);
 }
 
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index b6bd8e4a6486..1f9414bdd649 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -255,7 +255,7 @@ static int keyspan_write(struct tty_struct *tty,
 			return count;
 		}
 
-		dev_dbg(&port->dev, "%s - endpoint %d flip %d\n",
+		dev_dbg(&port->dev, "%s - endpoint %x flip %d\n",
 			__func__, usb_pipeendpoint(this_urb->pipe), flip);
 
 		if (this_urb->status == -EINPROGRESS) {
@@ -300,7 +300,7 @@ static void	usa26_indat_callback(struct urb *urb)
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
+		dev_dbg(&urb->dev->dev, "%s - nonzero status %d on endpoint %x\n",
 			__func__, status, endpoint);
 		return;
 	}
@@ -393,7 +393,8 @@ static void	usa26_instat_callback(struct urb *urb)
 	serial =  urb->context;
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status: %d\n",
+				__func__, status);
 		return;
 	}
 	if (urb->actual_length != 9) {
@@ -452,7 +453,7 @@ static void usa28_indat_callback(struct urb *urb)
 
 	do {
 		if (status) {
-			dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
+			dev_dbg(&urb->dev->dev, "%s - nonzero status %d on endpoint %x\n",
 				__func__, status, usb_pipeendpoint(urb->pipe));
 			return;
 		}
@@ -511,7 +512,8 @@ static void	usa28_instat_callback(struct urb *urb)
 	serial =  urb->context;
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status: %d\n",
+				__func__, status);
 		return;
 	}
 
@@ -591,7 +593,8 @@ static void	usa49_instat_callback(struct urb *urb)
 	serial =  urb->context;
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status: %d\n",
+				__func__, status);
 		return;
 	}
 
@@ -646,7 +649,7 @@ static void	usa49_indat_callback(struct urb *urb)
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
+		dev_dbg(&urb->dev->dev, "%s - nonzero status %d on endpoint %x\n",
 			__func__, status, endpoint);
 		return;
 	}
@@ -698,7 +701,8 @@ static void usa49wg_indat_callback(struct urb *urb)
 	serial = urb->context;
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status: %d\n",
+				__func__, status);
 		return;
 	}
 
@@ -774,8 +778,8 @@ static void usa90_indat_callback(struct urb *urb)
 	endpoint = usb_pipeendpoint(urb->pipe);
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x on endpoint %d.\n",
-		    __func__, status, endpoint);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status %d on endpoint %x\n",
+			__func__, status, endpoint);
 		return;
 	}
 
@@ -847,7 +851,8 @@ static void	usa90_instat_callback(struct urb *urb)
 	serial =  urb->context;
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status: %d\n",
+				__func__, status);
 		return;
 	}
 	if (urb->actual_length < 14) {
@@ -912,7 +917,8 @@ static void	usa67_instat_callback(struct urb *urb)
 	serial = urb->context;
 
 	if (status) {
-		dev_dbg(&urb->dev->dev, "%s - nonzero status: %x\n", __func__, status);
+		dev_dbg(&urb->dev->dev, "%s - nonzero status: %d\n",
+				__func__, status);
 		return;
 	}
 
@@ -1082,12 +1088,6 @@ static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
 	return 0;
 }
 
-static inline void stop_urb(struct urb *urb)
-{
-	if (urb && urb->status == -EINPROGRESS)
-		usb_kill_urb(urb);
-}
-
 static void keyspan_dtr_rts(struct usb_serial_port *port, int on)
 {
 	struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
@@ -1114,10 +1114,10 @@ static void keyspan_close(struct usb_serial_port *port)
 	p_priv->out_flip = 0;
 	p_priv->in_flip = 0;
 
-	stop_urb(p_priv->inack_urb);
+	usb_kill_urb(p_priv->inack_urb);
 	for (i = 0; i < 2; i++) {
-		stop_urb(p_priv->in_urbs[i]);
-		stop_urb(p_priv->out_urbs[i]);
+		usb_kill_urb(p_priv->in_urbs[i]);
+		usb_kill_urb(p_priv->out_urbs[i]);
 	}
 }
 
@@ -1221,8 +1221,8 @@ static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *se
 		if (ep->bEndpointAddress == endpoint)
 			return ep;
 	}
-	dev_warn(&serial->interface->dev, "found no endpoint descriptor for "
-		 "endpoint %x\n", endpoint);
+	dev_warn(&serial->interface->dev, "found no endpoint descriptor for endpoint %x\n",
+			endpoint);
 	return NULL;
 }
 
@@ -1237,7 +1237,8 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
 	if (endpoint == -1)
 		return NULL;		/* endpoint not needed */
 
-	dev_dbg(&serial->interface->dev, "%s - alloc for endpoint %d.\n", __func__, endpoint);
+	dev_dbg(&serial->interface->dev, "%s - alloc for endpoint %x\n",
+			__func__, endpoint);
 	urb = usb_alloc_urb(0, GFP_KERNEL);		/* No ISO */
 	if (!urb)
 		return NULL;
@@ -1572,7 +1573,8 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
 		return -1;
 	}
 
-	dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
+	dev_dbg(&port->dev, "%s - endpoint %x\n",
+			__func__, usb_pipeendpoint(this_urb->pipe));
 
 	/* Save reset port val for resend.
 	   Don't overwrite resend for open/close condition. */
@@ -1838,7 +1840,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
 		return -1;
 	}
 
-	dev_dbg(&port->dev, "%s - endpoint %d (%d)\n",
+	dev_dbg(&port->dev, "%s - endpoint %x (%d)\n",
 		__func__, usb_pipeendpoint(this_urb->pipe), device_port);
 
 	/* Save reset port val for resend.
@@ -2365,9 +2367,9 @@ static void keyspan_disconnect(struct usb_serial *serial)
 
 	s_priv = usb_get_serial_data(serial);
 
-	stop_urb(s_priv->instat_urb);
-	stop_urb(s_priv->glocont_urb);
-	stop_urb(s_priv->indat_urb);
+	usb_kill_urb(s_priv->instat_urb);
+	usb_kill_urb(s_priv->glocont_urb);
+	usb_kill_urb(s_priv->indat_urb);
 }
 
 static void keyspan_release(struct usb_serial *serial)
@@ -2376,6 +2378,10 @@ static void keyspan_release(struct usb_serial *serial)
 
 	s_priv = usb_get_serial_data(serial);
 
+	/* Make sure to unlink the URBs submitted in attach. */
+	usb_kill_urb(s_priv->instat_urb);
+	usb_kill_urb(s_priv->indat_urb);
+
 	usb_free_urb(s_priv->instat_urb);
 	usb_free_urb(s_priv->indat_urb);
 	usb_free_urb(s_priv->glocont_urb);
@@ -2491,11 +2497,11 @@ static int keyspan_port_remove(struct usb_serial_port *port)
 
 	p_priv = usb_get_serial_port_data(port);
 
-	stop_urb(p_priv->inack_urb);
-	stop_urb(p_priv->outcont_urb);
+	usb_kill_urb(p_priv->inack_urb);
+	usb_kill_urb(p_priv->outcont_urb);
 	for (i = 0; i < 2; i++) {
-		stop_urb(p_priv->in_urbs[i]);
-		stop_urb(p_priv->out_urbs[i]);
+		usb_kill_urb(p_priv->in_urbs[i]);
+		usb_kill_urb(p_priv->out_urbs[i]);
 	}
 
 	usb_free_urb(p_priv->inack_urb);
diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
index 3722d6c1ba77..c88215a0fa3d 100644
--- a/drivers/usb/serial/mxuport.c
+++ b/drivers/usb/serial/mxuport.c
@@ -1259,6 +1259,15 @@ static int mxuport_attach(struct usb_serial *serial)
 	return 0;
 }
 
+static void mxuport_release(struct usb_serial *serial)
+{
+	struct usb_serial_port *port0 = serial->port[0];
+	struct usb_serial_port *port1 = serial->port[1];
+
+	usb_serial_generic_close(port1);
+	usb_serial_generic_close(port0);
+}
+
 static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct mxuport_port *mxport = usb_get_serial_port_data(port);
@@ -1361,6 +1370,7 @@ static struct usb_serial_driver mxuport_device = {
 	.probe			= mxuport_probe,
 	.port_probe		= mxuport_port_probe,
 	.attach			= mxuport_attach,
+	.release		= mxuport_release,
 	.calc_num_ports		= mxuport_calc_num_ports,
 	.open			= mxuport_open,
 	.close			= mxuport_close,
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index c6f497f16526..d96d423d00e6 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -375,18 +375,22 @@ static void option_instat_callback(struct urb *urb);
 #define HAIER_PRODUCT_CE81B			0x10f8
 #define HAIER_PRODUCT_CE100			0x2009
 
-/* Cinterion (formerly Siemens) products */
-#define SIEMENS_VENDOR_ID				0x0681
-#define CINTERION_VENDOR_ID				0x1e2d
+/* Gemalto's Cinterion products (formerly Siemens) */
+#define SIEMENS_VENDOR_ID			0x0681
+#define CINTERION_VENDOR_ID			0x1e2d
+#define CINTERION_PRODUCT_HC25_MDMNET		0x0040
 #define CINTERION_PRODUCT_HC25_MDM		0x0047
-#define CINTERION_PRODUCT_HC25_MDMNET	0x0040
+#define CINTERION_PRODUCT_HC28_MDMNET		0x004A /* same for HC28J */
 #define CINTERION_PRODUCT_HC28_MDM		0x004C
-#define CINTERION_PRODUCT_HC28_MDMNET	0x004A /* same for HC28J */
 #define CINTERION_PRODUCT_EU3_E			0x0051
 #define CINTERION_PRODUCT_EU3_P			0x0052
 #define CINTERION_PRODUCT_PH8			0x0053
 #define CINTERION_PRODUCT_AHXX			0x0055
 #define CINTERION_PRODUCT_PLXX			0x0060
+#define CINTERION_PRODUCT_PH8_2RMNET		0x0082
+#define CINTERION_PRODUCT_PH8_AUDIO		0x0083
+#define CINTERION_PRODUCT_AHXX_2RMNET		0x0084
+#define CINTERION_PRODUCT_AHXX_AUDIO		0x0085
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID			0x0b3c
@@ -633,6 +637,10 @@ static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = {
 	.reserved = BIT(1) | BIT(2) | BIT(3),
 };
 
+static const struct option_blacklist_info cinterion_rmnet2_blacklist = {
+	.reserved = BIT(4) | BIT(5),
+};
+
 static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -1602,7 +1610,79 @@ static const struct usb_device_id option_ids[] = {
 		.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff45, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff46, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff47, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff48, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff49, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff50, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff51, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff52, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff53, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff54, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff55, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff56, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff57, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff58, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff59, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff60, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff61, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff62, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff63, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff64, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff65, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff66, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff67, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff68, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff69, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff70, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff71, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff72, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff73, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff74, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff75, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff76, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff77, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff78, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff79, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7a, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7b, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7c, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7d, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7e, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff80, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff81, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff82, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff83, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff84, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff85, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff86, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff87, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff88, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff89, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8a, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8b, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8c, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8d, 0xff, 0xff, 0xff) },
@@ -1613,6 +1693,61 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff9f, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa6, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa7, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa8, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaa, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffab, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffac, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffae, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaf, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb6, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb7, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb8, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffba, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbb, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbc, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbd, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbe, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbf, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc6, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc7, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc8, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc9, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffca, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcb, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcc, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcd, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffce, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcf, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd0, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd1, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd2, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd3, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd4, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd5, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff6, 0xff, 0xff, 0xff) },
@@ -1712,7 +1847,13 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) },
 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff),
+		.driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff),
+		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) },
+	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
+	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
 	{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
 	{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 2df8ad5ede89..85acb50a7ee2 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -141,6 +141,7 @@ static void qt2_release(struct usb_serial *serial)
 
 	serial_priv = usb_get_serial_data(serial);
 
+	usb_kill_urb(serial_priv->read_urb);
 	usb_free_urb(serial_priv->read_urb);
 	kfree(serial_priv->read_buffer);
 	kfree(serial_priv);
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 2694df2f4559..e7dbbef2af2a 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -80,6 +80,7 @@ struct ti_device {
 	int			td_open_port_count;
 	struct usb_serial	*td_serial;
 	int			td_is_3410;
+	bool			td_rs485_only;
 	int			td_urb_error;
 };
 
@@ -160,6 +161,11 @@ static const struct usb_device_id ti_id_table_3410[] = {
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
 	{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1110_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1130_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) },
 	{ }	/* terminator */
 };
 
@@ -193,6 +199,11 @@ static const struct usb_device_id ti_id_table_combined[] = {
 	{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
 	{ USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1110_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1130_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) },
+	{ USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) },
 	{ }	/* terminator */
 };
 
@@ -277,6 +288,11 @@ MODULE_FIRMWARE("mts_gsm.fw");
 MODULE_FIRMWARE("mts_edge.fw");
 MODULE_FIRMWARE("mts_mt9234mu.fw");
 MODULE_FIRMWARE("mts_mt9234zba.fw");
+MODULE_FIRMWARE("moxa/moxa-1110.fw");
+MODULE_FIRMWARE("moxa/moxa-1130.fw");
+MODULE_FIRMWARE("moxa/moxa-1131.fw");
+MODULE_FIRMWARE("moxa/moxa-1150.fw");
+MODULE_FIRMWARE("moxa/moxa-1151.fw");
 
 module_param(closing_wait, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(closing_wait,
@@ -292,6 +308,9 @@ static int ti_startup(struct usb_serial *serial)
 {
 	struct ti_device *tdev;
 	struct usb_device *dev = serial->dev;
+	struct usb_host_interface *cur_altsetting;
+	int num_endpoints;
+	u16 vid, pid;
 	int status;
 
 	dev_dbg(&dev->dev,
@@ -315,8 +334,22 @@ static int ti_startup(struct usb_serial *serial)
 	dev_dbg(&dev->dev, "%s - device type is %s\n", __func__,
 		tdev->td_is_3410 ? "3410" : "5052");
 
-	/* if we have only 1 configuration, download firmware */
-	if (dev->descriptor.bNumConfigurations == 1) {
+	vid = le16_to_cpu(dev->descriptor.idVendor);
+	pid = le16_to_cpu(dev->descriptor.idProduct);
+	if (vid == MXU1_VENDOR_ID) {
+		switch (pid) {
+		case MXU1_1130_PRODUCT_ID:
+		case MXU1_1131_PRODUCT_ID:
+			tdev->td_rs485_only = true;
+			break;
+		}
+	}
+
+	cur_altsetting = serial->interface->cur_altsetting;
+	num_endpoints = cur_altsetting->desc.bNumEndpoints;
+
+	/* if we have only 1 configuration and 1 endpoint, download firmware */
+	if (dev->descriptor.bNumConfigurations == 1 && num_endpoints == 1) {
 		status = ti_download_firmware(tdev);
 
 		if (status != 0)
@@ -371,7 +404,11 @@ static int ti_port_probe(struct usb_serial_port *port)
 	port->port.closing_wait = msecs_to_jiffies(10 * closing_wait);
 	tport->tp_port = port;
 	tport->tp_tdev = usb_get_serial_data(port->serial);
-	tport->tp_uart_mode = 0;	/* default is RS232 */
+
+	if (tport->tp_tdev->td_rs485_only)
+		tport->tp_uart_mode = TI_UART_485_RECEIVER_DISABLED;
+	else
+		tport->tp_uart_mode = TI_UART_232;
 
 	usb_set_serial_port_data(port, tport);
 
@@ -1450,6 +1487,16 @@ static int ti_download_firmware(struct ti_device *tdev)
 	const struct firmware *fw_p;
 	char buf[32];
 
+	if (le16_to_cpu(dev->descriptor.idVendor) == MXU1_VENDOR_ID) {
+		snprintf(buf,
+			sizeof(buf),
+			"moxa/moxa-%04x.fw",
+			le16_to_cpu(dev->descriptor.idProduct));
+
+		status = request_firmware(&fw_p, buf, &dev->dev);
+		goto check_firmware;
+	}
+
 	/* try ID specific firmware first, then try generic firmware */
 	sprintf(buf, "ti_usb-v%04x-p%04x.fw",
 			le16_to_cpu(dev->descriptor.idVendor),
@@ -1487,6 +1534,8 @@ static int ti_download_firmware(struct ti_device *tdev)
 		}
 		status = request_firmware(&fw_p, buf, &dev->dev);
 	}
+
+check_firmware:
 	if (status) {
 		dev_err(&dev->dev, "%s - firmware not found\n", __func__);
 		return -ENOENT;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 98f35c656c02..bbfd3a184600 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -60,6 +60,14 @@
 #define HONEYWELL_VENDOR_ID		0x10ac
 #define HONEYWELL_HGI80_PRODUCT_ID	0x0102  /* Honeywell HGI80 */
 
+/* Moxa UPORT 11x0 vendor and product IDs */
+#define MXU1_VENDOR_ID				0x110a
+#define MXU1_1110_PRODUCT_ID			0x1110
+#define MXU1_1130_PRODUCT_ID			0x1130
+#define MXU1_1131_PRODUCT_ID			0x1131
+#define MXU1_1150_PRODUCT_ID			0x1150
+#define MXU1_1151_PRODUCT_ID			0x1151
+
 /* Commands */
 #define TI_GET_VERSION			0x01
 #define TI_GET_PORT_STATUS		0x02
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 3f253aec0c16..b1b9bac44016 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -96,7 +96,8 @@ static int allocate_minors(struct usb_serial *serial, int num_ports)
 	mutex_lock(&table_lock);
 	for (i = 0; i < num_ports; ++i) {
 		port = serial->port[i];
-		minor = idr_alloc(&serial_minors, port, 0, 0, GFP_KERNEL);
+		minor = idr_alloc(&serial_minors, port, 0,
+					USB_SERIAL_TTY_MINORS, GFP_KERNEL);
 		if (minor < 0)
 			goto error;
 		port->minor = minor;
@@ -815,7 +816,7 @@ static int usb_serial_probe(struct usb_interface *interface,
 		}
 	}
 
-#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
+#if IS_ENABLED(CONFIG_USB_SERIAL_PL2303)
 	/* BEGIN HORRIBLE HACK FOR PL2303 */
 	/* this is needed due to the looney way its endpoints are set up */
 	if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 171fa7d793bc..1d8b03c81030 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -829,8 +829,10 @@ static int alauda_write_lba(struct us_data *us, u16 lba,
 
 	pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
 	if (pba == 1) {
-		/* Maybe it is impossible to write to PBA 1.
-		   Fake success, but don't do anything. */
+		/*
+		 * Maybe it is impossible to write to PBA 1.
+		 * Fake success, but don't do anything.
+		 */
 		printk(KERN_WARNING
 		       "alauda_write_lba: avoid writing to pba 1\n");
 		return USB_STOR_TRANSPORT_GOOD;
@@ -977,10 +979,12 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
 			usb_stor_dbg(us, "Read %d zero pages (LBA %d) page %d\n",
 				     pages, lba, page);
 
-			/* This is not really an error. It just means
-			   that the block has never been written.
-			   Instead of returning USB_STOR_TRANSPORT_ERROR
-			   it is better to return all zero data. */
+			/*
+			 * This is not really an error. It just means
+			 * that the block has never been written.
+			 * Instead of returning USB_STOR_TRANSPORT_ERROR
+			 * it is better to return all zero data.
+			 */
 
 			memset(buffer, 0, len);
 		} else {
@@ -1222,8 +1226,10 @@ static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
 	}
 
 	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
-		/* sure.  whatever.  not like we can stop the user from popping
-		   the media out of the device (no locking doors, etc) */
+		/*
+		 * sure.  whatever.  not like we can stop the user from popping
+		 * the media out of the device (no locking doors, etc)
+		 */
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c
index c80d3dec9a34..5e4af44d7d9f 100644
--- a/drivers/usb/storage/cypress_atacb.c
+++ b/drivers/usb/storage/cypress_atacb.c
@@ -110,13 +110,17 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 	/* first build the ATACB command */
 	srb->cmd_len = 16;
 
-	srb->cmnd[0] = 0x24; /* bVSCBSignature : vendor-specific command
-	                        this value can change, but most(all ?) manufacturers
-							keep the cypress default : 0x24 */
+	srb->cmnd[0] = 0x24; /*
+			      * bVSCBSignature : vendor-specific command
+			      * this value can change, but most(all ?) manufacturers
+			      * keep the cypress default : 0x24
+			      */
 	srb->cmnd[1] = 0x24; /* bVSCBSubCommand : 0x24 for ATACB */
 
-	srb->cmnd[3] = 0xff - 1; /* features, sector count, lba low, lba med
-								lba high, device, command are valid */
+	srb->cmnd[3] = 0xff - 1; /*
+				  * features, sector count, lba low, lba med
+				  * lba high, device, command are valid
+				  */
 	srb->cmnd[4] = 1; /* TransferBlockCount : 512 */
 
 	if (save_cmnd[0] == ATA_16) {
@@ -155,8 +159,7 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 
 	usb_stor_transparent_scsi_command(srb, us);
 
-	/* if the device doesn't support ATACB
-	 */
+	/* if the device doesn't support ATACB */
 	if (srb->result == SAM_STAT_CHECK_CONDITION &&
 			memcmp(srb->sense_buffer, usb_stor_sense_invalidCDB,
 				sizeof(usb_stor_sense_invalidCDB)) == 0) {
@@ -164,7 +167,8 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 		goto end;
 	}
 
-	/* if ck_cond flags is set, and there wasn't critical error,
+	/*
+	 * if ck_cond flags is set, and there wasn't critical error,
 	 * build the special sense
 	 */
 	if ((srb->result != (DID_ERROR << 16) &&
@@ -176,11 +180,11 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 		unsigned char *desc = sb + 8;
 		int tmp_result;
 
-		/* build the command for
-		 * reading the ATA registers */
+		/* build the command for reading the ATA registers */
 		scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs));
 
-		/* we use the same command as before, but we set
+		/*
+		 * we use the same command as before, but we set
 		 * the read taskfile bit, for not executing atacb command,
 		 * but reading register selected in srb->cmnd[4]
 		 */
@@ -204,10 +208,11 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
 		sb[2] = 0; /* ATA PASS THROUGH INFORMATION AVAILABLE */
 		sb[3] = 0x1D;
 
-		/* XXX we should generate sk, asc, ascq from status and error
+		/*
+		 * XXX we should generate sk, asc, ascq from status and error
 		 * regs
 		 * (see 11.1 Error translation ATA device error to SCSI error
-		 *  map, and ata_to_sense_error from libata.)
+		 * map, and ata_to_sense_error from libata.)
 		 */
 
 		/* Sense data is current and format is descriptor. */
@@ -258,7 +263,8 @@ static int cypress_probe(struct usb_interface *intf,
 	if (result)
 		return result;
 
-	/* Among CY7C68300 chips, the A revision does not support Cypress ATACB
+	/*
+	 * Among CY7C68300 chips, the A revision does not support Cypress ATACB
 	 * Filter out this revision from EEPROM default descriptor values
 	 */
 	device = interface_to_usbdev(intf);
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index aa4f51944a4a..723197af6ec5 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -1,4 +1,5 @@
-/* Driver for Datafab USB Compact Flash reader
+/*
+ * Driver for Datafab USB Compact Flash reader
  *
  * datafab driver v0.1:
  *
@@ -693,18 +694,23 @@ static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us)
 	}
 
 	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
-		// sure.  whatever.  not like we can stop the user from
-		// popping the media out of the device (no locking doors, etc)
-		//
+		/*
+		 * sure.  whatever.  not like we can stop the user from
+		 * popping the media out of the device (no locking doors, etc)
+		 */
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 
 	if (srb->cmnd[0] == START_STOP) {
-		/* this is used by sd.c'check_scsidisk_media_change to detect
-		   media change */
+		/*
+		 * this is used by sd.c'check_scsidisk_media_change to detect
+		 * media change
+		 */
 		usb_stor_dbg(us, "START_STOP\n");
-		/* the first datafab_id_device after a media change returns
-		   an error (determined experimentally) */
+		/*
+		 * the first datafab_id_device after a media change returns
+		 * an error (determined experimentally)
+		 */
 		rc = datafab_id_device(us, info);
 		if (rc == USB_STOR_TRANSPORT_GOOD) {
 			info->sense_key = NO_SENSE;
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
index 5a12c03138f8..8d20804a59e6 100644
--- a/drivers/usb/storage/debug.c
+++ b/drivers/usb/storage/debug.c
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * Debugging Functions Source Code File
  *
  * Current development and maintenance by:
diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h
index 6b365ce4e610..8ab73299b650 100644
--- a/drivers/usb/storage/debug.h
+++ b/drivers/usb/storage/debug.h
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * Debugging Functions Header File
  *
  * Current development and maintenance by:
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index d3a17c65a702..02bdaa912164 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -560,8 +560,10 @@ static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
 	/* check bulk status */
 	residue = le32_to_cpu(bcs->Residue);
 
-	/* try to compute the actual residue, based on how much data
-	 * was really transferred and what the device tells us */
+	/*
+	 * try to compute the actual residue, based on how much data
+	 * was really transferred and what the device tells us
+	 */
 	if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
 		residue = min(residue, transfer_length);
 		if (us->srb != NULL)
@@ -862,9 +864,6 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
 	u8 ExtBuf[4];
 	u32 bn = PhyBlockAddr * 0x20 + PageNum;
 
-	/* printk(KERN_INFO "MS --- MS_ReaderReadPage,
-	PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
-
 	result = ene_load_bincode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -1141,8 +1140,6 @@ static int ms_read_copyblock(struct us_data *us, u16 oldphy, u16 newphy,
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int result;
 
-	/* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x,
-		PageNum = %x\n", PhyBlockAddr, PageNum); */
 	result = ene_load_bincode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -1176,8 +1173,6 @@ static int ms_read_eraseblock(struct us_data *us, u32 PhyBlockAddr)
 	int result;
 	u32 bn = PhyBlockAddr;
 
-	/* printk(KERN_INFO "MS --- ms_read_eraseblock,
-			PhyBlockAddr = %x\n", PhyBlockAddr); */
 	result = ene_load_bincode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -1255,8 +1250,6 @@ static int ms_lib_overwrite_extra(struct us_data *us, u32 PhyBlockAddr,
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int result;
 
-	/* printk("MS --- MS_LibOverwriteExtra,
-		PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
 	result = ene_load_bincode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -1342,7 +1335,6 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
 	int result;
 	u8 ExtBuf[4];
 
-	/* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb->DataTransferLength = 0x4;
@@ -1541,9 +1533,6 @@ static int ms_lib_read_extrablock(struct us_data *us, u32 PhyBlock,
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int     result;
 
-	/* printk("MS_LibReadExtraBlock --- PhyBlock = %x,
-		PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */
-
 	/* Read Extra Data */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -2390,8 +2379,10 @@ static int ene_ub6250_reset_resume(struct usb_interface *iface)
 	/* Report the reset to the SCSI core */
 	usb_stor_reset_resume(iface);
 
-	/* FIXME: Notify the subdrivers that they need to reinitialize
-	 * the device */
+	/*
+	 * FIXME: Notify the subdrivers that they need to reinitialize
+	 * the device
+	 */
 	info->Power_IsResum = true;
 	/*info->SD_Status.Ready = 0; */
 	info->SD_Status = *(struct SD_STATUS *)&tmp;
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
index 3f2b08966b9d..c0a5d954414b 100644
--- a/drivers/usb/storage/freecom.c
+++ b/drivers/usb/storage/freecom.c
@@ -1,4 +1,5 @@
-/* Driver for Freecom USB/IDE adaptor
+/*
+ * Driver for Freecom USB/IDE adaptor
  *
  * Freecom v0.1:
  *
@@ -84,25 +85,33 @@ struct freecom_status {
 	u8    Pad[60];
 };
 
-/* Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide
- * register. */
+/*
+ * Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide
+ * register.
+ */
 #define FCM_INT_STATUS		0x02 /* INDEX_STAT */
 #define FCM_STATUS_BUSY		0x80
 
-/* These are the packet types.  The low bit indicates that this command
- * should wait for an interrupt. */
+/*
+ * These are the packet types.  The low bit indicates that this command
+ * should wait for an interrupt.
+ */
 #define FCM_PACKET_ATAPI	0x21
 #define FCM_PACKET_STATUS	0x20
 
-/* Receive data from the IDE interface.  The ATAPI packet has already
- * waited, so the data should be immediately available. */
+/*
+ * Receive data from the IDE interface.  The ATAPI packet has already
+ * waited, so the data should be immediately available.
+ */
 #define FCM_PACKET_INPUT	0x81
 
 /* Send data to the IDE interface. */
 #define FCM_PACKET_OUTPUT	0x01
 
-/* Write a value to an ide register.  Or the ide register to write after
- * munging the address a bit. */
+/*
+ * Write a value to an ide register.  Or the ide register to write after
+ * munging the address a bit.
+ */
 #define FCM_PACKET_IDE_WRITE	0x40
 #define FCM_PACKET_IDE_READ	0xC0
 
@@ -251,16 +260,20 @@ static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 	result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
 			FCM_PACKET_LENGTH, NULL);
 
-	/* The Freecom device will only fail if there is something wrong in
+	/*
+	 * The Freecom device will only fail if there is something wrong in
 	 * USB land.  It returns the status in its own registers, which
-	 * come back in the bulk pipe. */
+	 * come back in the bulk pipe.
+	 */
 	if (result != USB_STOR_XFER_GOOD) {
 		usb_stor_dbg(us, "freecom transport error\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	/* There are times we can optimize out this status read, but it
-	 * doesn't hurt us to always do it now. */
+	/*
+	 * There are times we can optimize out this status read, but it
+	 * doesn't hurt us to always do it now.
+	 */
 	result = usb_stor_bulk_transfer_buf (us, ipipe, fst,
 			FCM_STATUS_PACKET_LENGTH, &partial);
 	usb_stor_dbg(us, "foo Status result %d %u\n", result, partial);
@@ -269,7 +282,8 @@ static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	US_DEBUG(pdump(us, (void *)fst, partial));
 
-	/* The firmware will time-out commands after 20 seconds. Some commands
+	/*
+	 * The firmware will time-out commands after 20 seconds. Some commands
 	 * can legitimately take longer than this, so we use a different
 	 * command that only waits for the interrupt and then sends status,
 	 * without having to send a new ATAPI command to the device.
@@ -291,7 +305,8 @@ static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 		result = usb_stor_bulk_transfer_buf (us, opipe, fcb,
 				FCM_PACKET_LENGTH, NULL);
 
-		/* The Freecom device will only fail if there is something
+		/*
+		 * The Freecom device will only fail if there is something
 		 * wrong in USB land.  It returns the status in its own
 		 * registers, which come back in the bulk pipe.
 		 */
@@ -318,9 +333,11 @@ static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 
-	/* The device might not have as much data available as we
+	/*
+	 * The device might not have as much data available as we
 	 * requested.  If you ask for more than the device has, this reads
-	 * and such will hang. */
+	 * and such will hang.
+	 */
 	usb_stor_dbg(us, "Device indicates that it has %d bytes available\n",
 		     le16_to_cpu(fst->Count));
 	usb_stor_dbg(us, "SCSI requested %d\n", scsi_bufflen(srb));
@@ -344,16 +361,20 @@ static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 			     length);
 	}
 
-	/* What we do now depends on what direction the data is supposed to
-	 * move in. */
+	/*
+	 * What we do now depends on what direction the data is supposed to
+	 * move in.
+	 */
 
 	switch (us->srb->sc_data_direction) {
 	case DMA_FROM_DEVICE:
 		/* catch bogus "read 0 length" case */
 		if (!length)
 			break;
-		/* Make sure that the status indicates that the device
-		 * wants data as well. */
+		/*
+		 * Make sure that the status indicates that the device
+		 * wants data as well.
+		 */
 		if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
 			usb_stor_dbg(us, "SCSI wants data, drive doesn't have any\n");
 			return USB_STOR_TRANSPORT_FAILED;
@@ -384,8 +405,10 @@ static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us)
 		/* catch bogus "write 0 length" case */
 		if (!length)
 			break;
-		/* Make sure the status indicates that the device wants to
-		 * send us data. */
+		/*
+		 * Make sure the status indicates that the device wants to
+		 * send us data.
+		 */
 		/* !!IMPLEMENT!! */
 		result = freecom_writedata (srb, us, ipipe, opipe, length);
 		if (result != USB_STOR_TRANSPORT_GOOD)
@@ -431,7 +454,8 @@ static int init_freecom(struct us_data *us)
 	int result;
 	char *buffer = us->iobuf;
 
-	/* The DMA-mapped I/O buffer is 64 bytes long, just right for
+	/*
+	 * The DMA-mapped I/O buffer is 64 bytes long, just right for
 	 * all our packets.  No need to allocate any extra buffer space.
 	 */
 
@@ -440,7 +464,8 @@ static int init_freecom(struct us_data *us)
 	buffer[32] = '\0';
 	usb_stor_dbg(us, "String returned from FC init is: %s\n", buffer);
 
-	/* Special thanks to the people at Freecom for providing me with
+	/*
+	 * Special thanks to the people at Freecom for providing me with
 	 * this "magic sequence", which they use in their Windows and MacOS
 	 * drivers to make sure that all the attached perhiperals are
 	 * properly reset.
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
index 31fa2e92065b..d9d8c17e05d1 100644
--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -1,4 +1,5 @@
-/* Special Initializers for certain USB Mass Storage devices
+/*
+ * Special Initializers for certain USB Mass Storage devices
  *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -42,8 +43,10 @@
 #include "debug.h"
 #include "transport.h"
 
-/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
- * mode */
+/*
+ * This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
+ * mode
+ */
 int usb_stor_euscsi_init(struct us_data *us)
 {
 	int result;
@@ -57,8 +60,10 @@ int usb_stor_euscsi_init(struct us_data *us)
 	return 0;
 }
 
-/* This function is required to activate all four slots on the UCR-61S2B
- * flash reader */
+/*
+ * This function is required to activate all four slots on the UCR-61S2B
+ * flash reader
+ */
 int usb_stor_ucr61s2b_init(struct us_data *us)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap*) us->iobuf;
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
index 529327fbb06b..039abf4d1cb7 100644
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -1,4 +1,5 @@
-/* Header file for Special Initializers for certain USB Mass Storage devices
+/*
+ * Header file for Special Initializers for certain USB Mass Storage devices
  *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -38,12 +39,16 @@
 #include "usb.h"
 #include "transport.h"
 
-/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
- * mode */
+/*
+ * This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
+ * mode
+ */
 int usb_stor_euscsi_init(struct us_data *us);
 
-/* This function is required to activate all four slots on the UCR-61S2B
- * flash reader */
+/*
+ * This function is required to activate all four slots on the UCR-61S2B
+ * flash reader
+ */
 int usb_stor_ucr61s2b_init(struct us_data *us);
 
 /* This places the HUAWEI E220 devices in multi-port mode */
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 39afd7045c43..fba4005dd737 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1,4 +1,5 @@
-/* Transport & Protocol Driver for In-System Design, Inc. ISD200 ASIC
+/*
+ * Transport & Protocol Driver for In-System Design, Inc. ISD200 ASIC
  *
  * Current development and maintenance:
  *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
@@ -628,7 +629,8 @@ static void isd200_invoke_transport( struct us_data *us,
 	srb->cmd_len = sizeof(ataCdb->generic);
 	transferStatus = usb_stor_Bulk_transport(srb, us);
 
-	/* if the command gets aborted by the higher layers, we need to
+	/*
+	 * if the command gets aborted by the higher layers, we need to
 	 * short-circuit all other processing
 	 */
 	if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
@@ -695,15 +697,18 @@ static void isd200_invoke_transport( struct us_data *us,
 		}
 	}
 
-	/* Regardless of auto-sense, if we _know_ we have an error
+	/*
+	 * Regardless of auto-sense, if we _know_ we have an error
 	 * condition, show that in the result code
 	 */
 	if (transferStatus == USB_STOR_TRANSPORT_FAILED)
 		srb->result = SAM_STAT_CHECK_CONDITION;
 	return;
 
-	/* abort processing: the bulk-only transport requires a reset
-	 * following an abort */
+	/*
+	 * abort processing: the bulk-only transport requires a reset
+	 * following an abort
+	 */
 	Handle_Abort:
 	srb->result = DID_ABORT << 16;
 
@@ -965,20 +970,22 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave,
 			info->DeviceHead = master_slave;
 			break;
 		} 
-		/* check Cylinder High/Low to
-		   determine if it is an ATAPI device
-		*/
+		/*
+		 * check Cylinder High/Low to
+		 * determine if it is an ATAPI device
+		 */
 		else if (regs[ATA_REG_HCYL_OFFSET] == 0xEB &&
 			 regs[ATA_REG_LCYL_OFFSET] == 0x14) {
-			/* It seems that the RICOH 
-			   MP6200A CD/RW drive will 
-			   report itself okay as a
-			   slave when it is really a
-			   master. So this check again
-			   as a master device just to
-			   make sure it doesn't report
-			   itself okay as a master also
-			*/
+			/*
+			 * It seems that the RICOH
+			 * MP6200A CD/RW drive will
+			 * report itself okay as a
+			 * slave when it is really a
+			 * master. So this check again
+			 * as a master device just to
+			 * make sure it doesn't report
+			 * itself okay as a master also
+			 */
 			if ((master_slave & ATA_ADDRESS_DEVHEAD_SLAVE) &&
 			    !recheckAsMaster) {
 				usb_stor_dbg(us, "   Identified ATAPI device as slave.  Rechecking again as master\n");
@@ -1176,9 +1183,11 @@ static int isd200_get_inquiry_data( struct us_data *us )
 				if (id[ATA_ID_COMMAND_SET_2] & COMMANDSET_MEDIA_STATUS) {
 					usb_stor_dbg(us, "   Device supports Media Status Notification\n");
 
-					/* Indicate that it is enabled, even though it is not
-					 * This allows the lock/unlock of the media to work
-					 * correctly.
+					/*
+					 * Indicate that it is enabled, even
+					 * though it is not.
+					 * This allows the lock/unlock of the
+					 * media to work correctly.
 					 */
 					info->DeviceFlags |= DF_MEDIA_STATUS_ENABLED;
 				}
@@ -1197,7 +1206,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
 			usb_stor_dbg(us, "Protocol changed to: %s\n",
 				     us->protocol_name);
 	    
-			/* Free driver structure */	    
+			/* Free driver structure */
 			us->extra_destructor(info);
 			kfree(info);
 			us->extra = NULL;
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index ee613e258db0..011e5270690a 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -1,4 +1,5 @@
-/* Driver for Lexar "Jumpshot" Compact Flash reader
+/*
+ * Driver for Lexar "Jumpshot" Compact Flash reader
  *
  * jumpshot driver v0.1:
  *
@@ -618,18 +619,23 @@ static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us)
 	}
 
 	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
-		// sure.  whatever.  not like we can stop the user from popping
-		// the media out of the device (no locking doors, etc)
-		//
+		/*
+		 * sure.  whatever.  not like we can stop the user from popping
+		 * the media out of the device (no locking doors, etc)
+		 */
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 
 	if (srb->cmnd[0] == START_STOP) {
-		/* this is used by sd.c'check_scsidisk_media_change to detect
-		   media change */
+		/*
+		 * this is used by sd.c'check_scsidisk_media_change to detect
+		 * media change
+		 */
 		usb_stor_dbg(us, "START_STOP\n");
-		/* the first jumpshot_id_device after a media change returns
-		   an error (determined experimentally) */
+		/*
+		 * the first jumpshot_id_device after a media change returns
+		 * an error (determined experimentally)
+		 */
 		rc = jumpshot_id_device(us, info);
 		if (rc == USB_STOR_TRANSPORT_GOOD) {
 			info->sense_key = NO_SENSE;
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c
index ae201e69475c..f9d407f0b508 100644
--- a/drivers/usb/storage/karma.c
+++ b/drivers/usb/storage/karma.c
@@ -1,4 +1,5 @@
-/* Driver for Rio Karma
+/*
+ * Driver for Rio Karma
  *
  *   (c) 2006 Bob Copeland <me@bobcopeland.com>
  *   (c) 2006 Keith Bennett <keith@mcs.st-and.ac.uk>
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c
index b2b35b1d7de8..57282f12317b 100644
--- a/drivers/usb/storage/option_ms.c
+++ b/drivers/usb/storage/option_ms.c
@@ -65,7 +65,8 @@ static int option_rezero(struct us_data *us)
 		goto out;
 	}
 
-	/* Some of the devices need to be asked for a response, but we don't
+	/*
+	 * Some of the devices need to be asked for a response, but we don't
 	 * care what that response is.
 	 */
 	usb_stor_bulk_transfer_buf(us,
@@ -140,7 +141,8 @@ int option_ms_init(struct us_data *us)
 
 	usb_stor_dbg(us, "Option MS: %s\n", "option_ms_init called");
 
-	/* Additional test for vendor information via INQUIRY,
+	/*
+	 * Additional test for vendor information via INQUIRY,
 	 * because some vendor/product IDs are ambiguous
 	 */
 	result = option_inquiry(us);
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 12e3c2fac642..74c38870a17e 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -75,7 +76,8 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
 
 void usb_stor_ufi_command(struct scsi_cmnd *srb, struct us_data *us)
 {
-	/* fix some commands -- this is a form of mode translation
+	/*
+	 * fix some commands -- this is a form of mode translation
 	 * UFI devices only accept 12 byte long commands
 	 *
 	 * NOTE: This only works because a scsi_cmnd struct field contains
@@ -127,7 +129,8 @@ EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command);
  * Scatter-gather transfer buffer access routines
  ***********************************************************************/
 
-/* Copy a buffer of length buflen to/from the srb's transfer buffer.
+/*
+ * Copy a buffer of length buflen to/from the srb's transfer buffer.
  * Update the **sgptr and *offset variables so that the next copy will
  * pick up from where this one left off.
  */
@@ -175,7 +178,8 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
 }
 EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf);
 
-/* Store the contents of buffer into srb's transfer buffer and set the
+/*
+ * Store the contents of buffer into srb's transfer buffer and set the
  * SCSI residue.
  */
 void usb_stor_set_xfer_buf(unsigned char *buffer,
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
index ffc3e2af0156..a55666880b7b 100644
--- a/drivers/usb/storage/protocol.h
+++ b/drivers/usb/storage/protocol.h
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * Protocol Functions Header File
  *
  * Current development and maintenance by:
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index 20433563a601..4176d1af9bf2 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -1,4 +1,5 @@
-/* Driver for Realtek RTS51xx USB card reader
+/*
+ * Driver for Realtek RTS51xx USB card reader
  *
  * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
  *
@@ -267,8 +268,10 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun,
 	if (bcs->Tag != us->tag)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	/* try to compute the actual residue, based on how much data
-	 * was really transferred and what the device tells us */
+	/*
+	 * try to compute the actual residue, based on how much data
+	 * was really transferred and what the device tells us
+	 */
 	if (residue)
 		residue = residue < buf_len ? residue : buf_len;
 
@@ -286,7 +289,8 @@ static int rts51x_bulk_transport(struct us_data *us, u8 lun,
 		return USB_STOR_TRANSPORT_FAILED;
 
 	case US_BULK_STAT_PHASE:
-		/* phase error -- note that a transport reset will be
+		/*
+		 * phase error -- note that a transport reset will be
 		 * invoked by the invoke_transport() function
 		 */
 		return USB_STOR_TRANSPORT_ERROR;
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index ae85861051eb..33eb923df892 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * SCSI layer glue code
  *
  * Current development and maintenance by:
@@ -58,7 +59,8 @@
 #include "transport.h"
 #include "protocol.h"
 
-/* Vendor IDs for companies that seem to include the READ CAPACITY bug
+/*
+ * Vendor IDs for companies that seem to include the READ CAPACITY bug
  * in all their devices
  */
 #define VENDOR_ID_NOKIA		0x0421
@@ -87,7 +89,8 @@ static int slave_alloc (struct scsi_device *sdev)
 	 */
 	sdev->inquiry_len = 36;
 
-	/* USB has unusual DMA-alignment requirements: Although the
+	/*
+	 * USB has unusual DMA-alignment requirements: Although the
 	 * starting address of each scatter-gather element doesn't matter,
 	 * the length of each element except the last must be divisible
 	 * by the Bulk maxpacket value.  There's currently no way to
@@ -115,7 +118,8 @@ static int slave_configure(struct scsi_device *sdev)
 {
 	struct us_data *us = host_to_us(sdev->host);
 
-	/* Many devices have trouble transferring more than 32KB at a time,
+	/*
+	 * Many devices have trouble transferring more than 32KB at a time,
 	 * while others have trouble with more than 64K. At this time we
 	 * are limiting both to 32K (64 sectores).
 	 */
@@ -128,14 +132,22 @@ static int slave_configure(struct scsi_device *sdev)
 			blk_queue_max_hw_sectors(sdev->request_queue,
 					      max_sectors);
 	} else if (sdev->type == TYPE_TAPE) {
-		/* Tapes need much higher max_sector limits, so just
+		/*
+		 * Tapes need much higher max_sector limits, so just
 		 * raise it to the maximum possible (4 GB / 512) and
 		 * let the queue segment size sort out the real limit.
 		 */
 		blk_queue_max_hw_sectors(sdev->request_queue, 0x7FFFFF);
+	} else if (us->pusb_dev->speed >= USB_SPEED_SUPER) {
+		/*
+		 * USB3 devices will be limited to 2048 sectors. This gives us
+		 * better throughput on most devices.
+		 */
+		blk_queue_max_hw_sectors(sdev->request_queue, 2048);
 	}
 
-	/* Some USB host controllers can't do DMA; they have to use PIO.
+	/*
+	 * Some USB host controllers can't do DMA; they have to use PIO.
 	 * They indicate this by setting their dma_mask to NULL.  For
 	 * such controllers we need to make sure the block layer sets
 	 * up bounce buffers in addressable memory.
@@ -143,17 +155,21 @@ static int slave_configure(struct scsi_device *sdev)
 	if (!us->pusb_dev->bus->controller->dma_mask)
 		blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH);
 
-	/* We can't put these settings in slave_alloc() because that gets
+	/*
+	 * We can't put these settings in slave_alloc() because that gets
 	 * called before the device type is known.  Consequently these
-	 * settings can't be overridden via the scsi devinfo mechanism. */
+	 * settings can't be overridden via the scsi devinfo mechanism.
+	 */
 	if (sdev->type == TYPE_DISK) {
 
-		/* Some vendors seem to put the READ CAPACITY bug into
+		/*
+		 * Some vendors seem to put the READ CAPACITY bug into
 		 * all their devices -- primarily makers of cell phones
 		 * and digital cameras.  Since these devices always use
 		 * flash media and can be expected to have an even number
 		 * of sectors, we will always enable the CAPACITY_HEURISTICS
-		 * flag unless told otherwise. */
+		 * flag unless told otherwise.
+		 */
 		switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) {
 		case VENDOR_ID_NOKIA:
 		case VENDOR_ID_NIKON:
@@ -165,28 +181,36 @@ static int slave_configure(struct scsi_device *sdev)
 			break;
 		}
 
-		/* Disk-type devices use MODE SENSE(6) if the protocol
+		/*
+		 * Disk-type devices use MODE SENSE(6) if the protocol
 		 * (SubClass) is Transparent SCSI, otherwise they use
-		 * MODE SENSE(10). */
+		 * MODE SENSE(10).
+		 */
 		if (us->subclass != USB_SC_SCSI && us->subclass != USB_SC_CYP_ATACB)
 			sdev->use_10_for_ms = 1;
 
-		/* Many disks only accept MODE SENSE transfer lengths of
-		 * 192 bytes (that's what Windows uses). */
+		/*
+		 *Many disks only accept MODE SENSE transfer lengths of
+		 * 192 bytes (that's what Windows uses).
+		 */
 		sdev->use_192_bytes_for_3f = 1;
 
-		/* Some devices don't like MODE SENSE with page=0x3f,
+		/*
+		 * Some devices don't like MODE SENSE with page=0x3f,
 		 * which is the command used for checking if a device
 		 * is write-protected.  Now that we tell the sd driver
 		 * to do a 192-byte transfer with this command the
 		 * majority of devices work fine, but a few still can't
 		 * handle it.  The sd driver will simply assume those
-		 * devices are write-enabled. */
+		 * devices are write-enabled.
+		 */
 		if (us->fflags & US_FL_NO_WP_DETECT)
 			sdev->skip_ms_page_3f = 1;
 
-		/* A number of devices have problems with MODE SENSE for
-		 * page x08, so we will skip it. */
+		/*
+		 * A number of devices have problems with MODE SENSE for
+		 * page x08, so we will skip it.
+		 */
 		sdev->skip_ms_page_8 = 1;
 
 		/* Some devices don't handle VPD pages correctly */
@@ -198,15 +222,19 @@ static int slave_configure(struct scsi_device *sdev)
 		/* Do not attempt to use WRITE SAME */
 		sdev->no_write_same = 1;
 
-		/* Some disks return the total number of blocks in response
+		/*
+		 * Some disks return the total number of blocks in response
 		 * to READ CAPACITY rather than the highest block number.
-		 * If this device makes that mistake, tell the sd driver. */
+		 * If this device makes that mistake, tell the sd driver.
+		 */
 		if (us->fflags & US_FL_FIX_CAPACITY)
 			sdev->fix_capacity = 1;
 
-		/* A few disks have two indistinguishable version, one of
+		/*
+		 * A few disks have two indistinguishable version, one of
 		 * which reports the correct capacity and the other does not.
-		 * The sd driver has to guess which is the case. */
+		 * The sd driver has to guess which is the case.
+		 */
 		if (us->fflags & US_FL_CAPACITY_HEURISTICS)
 			sdev->guess_capacity = 1;
 
@@ -227,26 +255,34 @@ static int slave_configure(struct scsi_device *sdev)
 		if (sdev->scsi_level > SCSI_SPC_2)
 			us->fflags |= US_FL_SANE_SENSE;
 
-		/* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
+		/*
+		 * USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
 		 * Hardware Error) when any low-level error occurs,
 		 * recoverable or not.  Setting this flag tells the SCSI
 		 * midlayer to retry such commands, which frequently will
 		 * succeed and fix the error.  The worst this can lead to
-		 * is an occasional series of retries that will all fail. */
+		 * is an occasional series of retries that will all fail.
+		 */
 		sdev->retry_hwerror = 1;
 
-		/* USB disks should allow restart.  Some drives spin down
-		 * automatically, requiring a START-STOP UNIT command. */
+		/*
+		 * USB disks should allow restart.  Some drives spin down
+		 * automatically, requiring a START-STOP UNIT command.
+		 */
 		sdev->allow_restart = 1;
 
-		/* Some USB cardreaders have trouble reading an sdcard's last
+		/*
+		 * Some USB cardreaders have trouble reading an sdcard's last
 		 * sector in a larger then 1 sector read, since the performance
-		 * impact is negligible we set this flag for all USB disks */
+		 * impact is negligible we set this flag for all USB disks
+		 */
 		sdev->last_sector_bug = 1;
 
-		/* Enable last-sector hacks for single-target devices using
+		/*
+		 * Enable last-sector hacks for single-target devices using
 		 * the Bulk-only transport, unless we already know the
-		 * capacity will be decremented or is correct. */
+		 * capacity will be decremented or is correct.
+		 */
 		if (!(us->fflags & (US_FL_FIX_CAPACITY | US_FL_CAPACITY_OK |
 					US_FL_SCM_MULT_TARG)) &&
 				us->protocol == USB_PR_BULK)
@@ -262,9 +298,11 @@ static int slave_configure(struct scsi_device *sdev)
 
 	} else {
 
-		/* Non-disk-type devices don't need to blacklist any pages
+		/*
+		 * Non-disk-type devices don't need to blacklist any pages
 		 * or to force 192-byte transfer lengths for MODE SENSE.
-		 * But they do need to use MODE SENSE(10). */
+		 * But they do need to use MODE SENSE(10).
+		 */
 		sdev->use_10_for_ms = 1;
 
 		/* Some (fake) usb cdrom devices don't like READ_DISC_INFO */
@@ -272,7 +310,8 @@ static int slave_configure(struct scsi_device *sdev)
 			sdev->no_read_disc_info = 1;
 	}
 
-	/* The CB and CBI transports have no way to pass LUN values
+	/*
+	 * The CB and CBI transports have no way to pass LUN values
 	 * other than the bits in the second byte of a CDB.  But those
 	 * bits don't get set to the LUN value if the device reports
 	 * scsi_level == 0 (UNKNOWN).  Hence such devices must necessarily
@@ -282,13 +321,17 @@ static int slave_configure(struct scsi_device *sdev)
 			sdev->scsi_level == SCSI_UNKNOWN)
 		us->max_lun = 0;
 
-	/* Some devices choke when they receive a PREVENT-ALLOW MEDIUM
-	 * REMOVAL command, so suppress those commands. */
+	/*
+	 * Some devices choke when they receive a PREVENT-ALLOW MEDIUM
+	 * REMOVAL command, so suppress those commands.
+	 */
 	if (us->fflags & US_FL_NOT_LOCKABLE)
 		sdev->lockable = 0;
 
-	/* this is to satisfy the compiler, tho I don't think the 
-	 * return code is ever checked anywhere. */
+	/*
+	 * this is to satisfy the compiler, tho I don't think the 
+	 * return code is ever checked anywhere.
+	 */
 	return 0;
 }
 
@@ -362,8 +405,10 @@ static int command_abort(struct scsi_cmnd *srb)
 
 	usb_stor_dbg(us, "%s called\n", __func__);
 
-	/* us->srb together with the TIMED_OUT, RESETTING, and ABORTING
-	 * bits are protected by the host lock. */
+	/*
+	 * us->srb together with the TIMED_OUT, RESETTING, and ABORTING
+	 * bits are protected by the host lock.
+	 */
 	scsi_lock(us_to_host(us));
 
 	/* Is this command still active? */
@@ -373,11 +418,13 @@ static int command_abort(struct scsi_cmnd *srb)
 		return FAILED;
 	}
 
-	/* Set the TIMED_OUT bit.  Also set the ABORTING bit, but only if
+	/*
+	 * Set the TIMED_OUT bit.  Also set the ABORTING bit, but only if
 	 * a device reset isn't already in progress (to avoid interfering
 	 * with the reset).  Note that we must retain the host lock while
 	 * calling usb_stor_stop_transport(); otherwise it might interfere
-	 * with an auto-reset that begins as soon as we release the lock. */
+	 * with an auto-reset that begins as soon as we release the lock.
+	 */
 	set_bit(US_FLIDX_TIMED_OUT, &us->dflags);
 	if (!test_bit(US_FLIDX_RESETTING, &us->dflags)) {
 		set_bit(US_FLIDX_ABORTING, &us->dflags);
@@ -390,8 +437,10 @@ static int command_abort(struct scsi_cmnd *srb)
 	return SUCCESS;
 }
 
-/* This invokes the transport reset mechanism to reset the state of the
- * device */
+/*
+ * This invokes the transport reset mechanism to reset the state of the
+ * device
+ */
 static int device_reset(struct scsi_cmnd *srb)
 {
 	struct us_data *us = host_to_us(srb->device->host);
@@ -419,9 +468,11 @@ static int bus_reset(struct scsi_cmnd *srb)
 	return result < 0 ? FAILED : SUCCESS;
 }
 
-/* Report a driver-initiated device reset to the SCSI layer.
+/*
+ * Report a driver-initiated device reset to the SCSI layer.
  * Calling this for a SCSI-initiated reset is unnecessary but harmless.
- * The caller must own the SCSI host lock. */
+ * The caller must own the SCSI host lock.
+ */
 void usb_stor_report_device_reset(struct us_data *us)
 {
 	int i;
@@ -434,9 +485,11 @@ void usb_stor_report_device_reset(struct us_data *us)
 	}
 }
 
-/* Report a driver-initiated bus reset to the SCSI layer.
+/*
+ * Report a driver-initiated bus reset to the SCSI layer.
  * Calling this for a SCSI-initiated reset is unnecessary but harmless.
- * The caller must not own the SCSI host lock. */
+ * The caller must not own the SCSI host lock.
+ */
 void usb_stor_report_bus_reset(struct us_data *us)
 {
 	struct Scsi_Host *host = us_to_host(us);
@@ -565,10 +618,28 @@ static const struct scsi_host_template usb_stor_host_template = {
 	/* lots of sg segments can be handled */
 	.sg_tablesize =			SG_MAX_SEGMENTS,
 
-	/* limit the total size of a transfer to 120 KB */
+
+	/*
+	 * Limit the total size of a transfer to 120 KB.
+	 *
+	 * Some devices are known to choke with anything larger. It seems like
+	 * the problem stems from the fact that original IDE controllers had
+	 * only an 8-bit register to hold the number of sectors in one transfer
+	 * and even those couldn't handle a full 256 sectors.
+	 *
+	 * Because we want to make sure we interoperate with as many devices as
+	 * possible, we will maintain a 240 sector transfer size limit for USB
+	 * Mass Storage devices.
+	 *
+	 * Tests show that other operating have similar limits with Microsoft
+	 * Windows 7 limiting transfers to 128 sectors for both USB2 and USB3
+	 * and Apple Mac OS X 10.11 limiting transfers to 256 sectors for USB2
+	 * and 2048 for USB3 devices.
+	 */
 	.max_sectors =                  240,
 
-	/* merge commands... this seems to help performance, but
+	/*
+	 * merge commands... this seems to help performance, but
 	 * periodically someone should test to see which setting is more
 	 * optimal.
 	 */
diff --git a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h
index 5494d87607fb..d0a331dd9bc5 100644
--- a/drivers/usb/storage/scsiglue.h
+++ b/drivers/usb/storage/scsiglue.h
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * SCSI Connecting Glue Header File
  *
  * Current development and maintenance by:
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 79224fcf9b59..c5797fa2125e 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -1,4 +1,5 @@
-/* Driver for SanDisk SDDR-09 SmartMedia reader
+/*
+ * Driver for SanDisk SDDR-09 SmartMedia reader
  *
  *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
  *   (c) 2002 Andries Brouwer (aeb@cwi.nl)
@@ -799,10 +800,12 @@ sddr09_read_data(struct us_data *us,
 			usb_stor_dbg(us, "Read %d zero pages (LBA %d) page %d\n",
 				     pages, lba, page);
 
-			/* This is not really an error. It just means
-			   that the block has never been written.
-			   Instead of returning an error
-			   it is better to return all zero data. */
+			/*
+			 * This is not really an error. It just means
+			 * that the block has never been written.
+			 * Instead of returning an error
+			 * it is better to return all zero data.
+			 */
 
 			memset(buffer, 0, len);
 
@@ -890,8 +893,10 @@ sddr09_write_lba(struct us_data *us, unsigned int lba,
 	}
 
 	if (pba == 1) {
-		/* Maybe it is impossible to write to PBA 1.
-		   Fake success, but don't do anything. */
+		/*
+		 * Maybe it is impossible to write to PBA 1.
+		 * Fake success, but don't do anything.
+		 */
 		printk(KERN_WARNING "sddr09: avoid writing to pba 1\n");
 		return 0;
 	}
@@ -979,18 +984,22 @@ sddr09_write_data(struct us_data *us,
 	struct scatterlist *sg;
 	int result;
 
-	// Figure out the initial LBA and page
+	/* Figure out the initial LBA and page */
 	lba = address >> info->blockshift;
 	page = (address & info->blockmask);
 	maxlba = info->capacity >> (info->pageshift + info->blockshift);
 	if (lba >= maxlba)
 		return -EIO;
 
-	// blockbuffer is used for reading in the old data, overwriting
-	// with the new data, and performing ECC calculations
+	/*
+	 * blockbuffer is used for reading in the old data, overwriting
+	 * with the new data, and performing ECC calculations
+	 */
 
-	/* TODO: instead of doing kmalloc/kfree for each write,
-	   add a bufferpointer to the info structure */
+	/*
+	 * TODO: instead of doing kmalloc/kfree for each write,
+	 * add a bufferpointer to the info structure
+	 */
 
 	pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT);
 	blocklen = (pagelen << info->blockshift);
@@ -1000,9 +1009,11 @@ sddr09_write_data(struct us_data *us,
 		return -ENOMEM;
 	}
 
-	// Since we don't write the user data directly to the device,
-	// we have to create a bounce buffer and move the data a piece
-	// at a time between the bounce buffer and the actual transfer buffer.
+	/*
+	 * Since we don't write the user data directly to the device,
+	 * we have to create a bounce buffer and move the data a piece
+	 * at a time between the bounce buffer and the actual transfer buffer.
+	 */
 
 	len = min(sectors, (unsigned int) info->blocksize) * info->pagesize;
 	buffer = kmalloc(len, GFP_NOIO);
@@ -1018,7 +1029,7 @@ sddr09_write_data(struct us_data *us,
 
 	while (sectors > 0) {
 
-		// Write as many sectors as possible in this block
+		/* Write as many sectors as possible in this block */
 
 		pages = min(sectors, info->blocksize - page);
 		len = (pages << info->pageshift);
@@ -1031,7 +1042,7 @@ sddr09_write_data(struct us_data *us,
 			break;
 		}
 
-		// Get the data from the transfer buffer
+		/* Get the data from the transfer buffer */
 		usb_stor_access_xfer_buf(buffer, len, us->srb,
 				&sg, &offset, FROM_XFER_BUF);
 
@@ -1168,9 +1179,11 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) {
 	/* Byte 1 is the device type */
 	cardinfo = nand_find_id(deviceID[1]);
 	if (cardinfo) {
-		/* MB or MiB? It is neither. A 16 MB card has
-		   17301504 raw bytes, of which 16384000 are
-		   usable for user data. */
+		/*
+		 * MB or MiB? It is neither. A 16 MB card has
+		 * 17301504 raw bytes, of which 16384000 are
+		 * usable for user data.
+		 */
 		sprintf(blurbtxt + strlen(blurbtxt),
 			", %d MB", 1<<(cardinfo->chipshift - 20));
 	} else {
@@ -1211,14 +1224,18 @@ sddr09_read_map(struct us_data *us) {
 	if (!info->capacity)
 		return -1;
 
-	// size of a block is 1 << (blockshift + pageshift) bytes
-	// divide into the total capacity to get the number of blocks
+	/*
+	 * size of a block is 1 << (blockshift + pageshift) bytes
+	 * divide into the total capacity to get the number of blocks
+	 */
 
 	numblocks = info->capacity >> (info->blockshift + info->pageshift);
 
-	// read 64 bytes for every block (actually 1 << CONTROL_SHIFT)
-	// but only use a 64 KB buffer
-	// buffer size used must be a multiple of (1 << CONTROL_SHIFT)
+	/*
+	 * read 64 bytes for every block (actually 1 << CONTROL_SHIFT)
+	 * but only use a 64 KB buffer
+	 * buffer size used must be a multiple of (1 << CONTROL_SHIFT)
+	 */
 #define SDDR09_READ_MAP_BUFSZ 65536
 
 	alloc_blocks = min(numblocks, SDDR09_READ_MAP_BUFSZ >> CONTROL_SHIFT);
@@ -1575,8 +1592,10 @@ static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	havefakesense = 1;
 
-	/* Dummy up a response for INQUIRY since SDDR09 doesn't
-	   respond to INQUIRY commands */
+	/*
+	 * Dummy up a response for INQUIRY since SDDR09 doesn't
+	 * respond to INQUIRY commands
+	 */
 
 	if (srb->cmnd[0] == INQUIRY) {
 		memcpy(ptr, inquiry_response, 8);
@@ -1628,8 +1647,10 @@ static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
 	if (srb->cmnd[0] == MODE_SENSE_10) {
 		int modepage = (srb->cmnd[2] & 0x3F);
 
-		/* They ask for the Read/Write error recovery page,
-		   or for all pages. */
+		/*
+		 * They ask for the Read/Write error recovery page,
+		 * or for all pages.
+		 */
 		/* %% We should check DBD %% */
 		if (modepage == 0x01 || modepage == 0x3F) {
 			usb_stor_dbg(us, "Dummy up request for mode page 0x%x\n",
@@ -1682,7 +1703,8 @@ static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us)
 				USB_STOR_TRANSPORT_ERROR);
 	}
 
-	/* catch-all for all other commands, except
+	/*
+	 * catch-all for all other commands, except
 	 * pass TEST_UNIT_READY and REQUEST_SENSE through
 	 */
 	if (srb->cmnd[0] != TEST_UNIT_READY &&
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index e5e0a25ecd96..147c50b3e00f 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -1,4 +1,5 @@
-/* Driver for SanDisk SDDR-55 SmartMedia reader
+/*
+ * Driver for SanDisk SDDR-55 SmartMedia reader
  *
  * SDDR55 driver v0.1:
  *
@@ -130,7 +131,8 @@ sddr55_bulk_transport(struct us_data *us, int direction,
 	return usb_stor_bulk_transfer_buf(us, pipe, data, len, NULL);
 }
 
-/* check if card inserted, if there is, update read_only status
+/*
+ * check if card inserted, if there is, update read_only status
  * return non zero if no card
  */
 
@@ -714,15 +716,18 @@ static int sddr55_read_map(struct us_data *us) {
 	if (max_lba > 1000)
 		max_lba = 1000;
 
-	// Each block is 64 bytes of control data, so block i is located in
-	// scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11)
+	/*
+	 * Each block is 64 bytes of control data, so block i is located in
+	 * scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11)
+	 */
 
 	for (i=0; i<numblocks; i++) {
 		int zone = i / 1024;
 
 		lba = short_pack(buffer[i * 2], buffer[i * 2 + 1]);
 
-			/* Every 1024 physical blocks ("zone"), the LBA numbers
+			/*
+			 * Every 1024 physical blocks ("zone"), the LBA numbers
 			 * go back to zero, but are within a higher
 			 * block of LBA's. Also, there is a maximum of
 			 * 1000 LBA's per zone. In other words, in PBA
@@ -733,7 +738,8 @@ static int sddr55_read_map(struct us_data *us) {
 			 * are 24 spare blocks to use when blocks do go bad.
 			 */
 
-			/* SDDR55 returns 0xffff for a bad block, and 0x400 for the 
+			/*
+			 * SDDR55 returns 0xffff for a bad block, and 0x400 for the 
 			 * CIS block. (Is this true for cards 8MB or less??)
 			 * Record these in the physical to logical map
 			 */ 
@@ -824,8 +830,10 @@ static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	memset (info->sense_data, 0, sizeof info->sense_data);
 
-	/* Dummy up a response for INQUIRY since SDDR55 doesn't
-	   respond to INQUIRY commands */
+	/*
+	 * Dummy up a response for INQUIRY since SDDR55 doesn't
+	 * respond to INQUIRY commands
+	 */
 
 	if (srb->cmnd[0] == INQUIRY) {
 		memcpy(ptr, inquiry_response, 8);
@@ -833,7 +841,8 @@ static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 
-	/* only check card status if the map isn't allocated, ie no card seen yet
+	/*
+	 * only check card status if the map isn't allocated, ie no card seen yet
 	 * or if it's been over half a second since we last accessed it
 	 */
 	if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {
@@ -849,8 +858,10 @@ static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
 		}
 	}
 
-	/* if we detected a problem with the map when writing,
-	   don't allow any more access */
+	/*
+	 * if we detected a problem with the map when writing,
+	 * don't allow any more access
+	 */
 	if (info->fatal_error) {
 
 		set_sense_info (3, 0x31, 0);
@@ -868,12 +879,16 @@ static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 		info->capacity = capacity;
 
-		/* figure out the maximum logical block number, allowing for
-		 * the fact that only 250 out of every 256 are used */
+		/*
+		 * figure out the maximum logical block number, allowing for
+		 * the fact that only 250 out of every 256 are used
+		 */
 		info->max_log_blks = ((info->capacity >> (info->pageshift + info->blockshift)) / 256) * 250;
 
-		/* Last page in the card, adjust as we only use 250 out of
-		 * every 256 pages */
+		/*
+		 * Last page in the card, adjust as we only use 250 out of
+		 * every 256 pages
+		 */
 		capacity = (capacity / 256) * 250;
 
 		capacity /= PAGESIZE;
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index a3ec86b913a1..3b0294e4df93 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -1,4 +1,5 @@
-/* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
+/*
+ * Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
  *
  * Current development and maintenance by:
  *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
@@ -408,7 +409,8 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes)
 	int result;
 	unsigned char *status = us->iobuf;
 
-	/* Synchronizing cache on a CDR could take a heck of a long time,
+	/*
+	 * Synchronizing cache on a CDR could take a heck of a long time,
 	 * but probably not more than 10 minutes or so. On the other hand,
 	 * doing a full blank on a CDRW at speed 1 will take about 75
 	 * minutes!
@@ -1570,9 +1572,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	len = scsi_bufflen(srb);
 
-	/* Send A0 (ATA PACKET COMMAND).
-	   Note: I guess we're never going to get any of the ATA
-	   commands... just ATA Packet Commands.
+	/*
+	 * Send A0 (ATA PACKET COMMAND).
+	 * Note: I guess we're never going to get any of the ATA
+	 * commands... just ATA Packet Commands.
  	 */
 
 	registers[0] = USBAT_ATA_FEATURES;
@@ -1851,7 +1854,8 @@ static int usbat_probe(struct usb_interface *intf,
 	if (result)
 		return result;
 
-	/* The actual transport will be determined later by the
+	/*
+	 * The actual transport will be determined later by the
 	 * initialization routine; this is just a placeholder.
 	 */
 	us->transport_name = "Shuttle USBAT";
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c
index 2ea657be14c8..9a51019ac7b2 100644
--- a/drivers/usb/storage/sierra_ms.c
+++ b/drivers/usb/storage/sierra_ms.c
@@ -177,7 +177,8 @@ int sierra_ms_init(struct us_data *us)
 
 		debug_swoc(&us->pusb_dev->dev, swocInfo);
 
-		/* If there is not Linux software on the TRU-Install device
+		/*
+		 * If there is not Linux software on the TRU-Install device
 		 * then switch to modem mode
 		 */
 		if (!containsFullLinuxPackage(swocInfo)) {
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 5e67f63b2e46..ffd086733421 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -109,7 +110,8 @@
  * called more than once or from being called during usb_submit_urb().
  */
 
-/* This is the completion handler which will wake us up when an URB
+/*
+ * This is the completion handler which will wake us up when an URB
  * completes.
  */
 static void usb_stor_blocking_completion(struct urb *urb)
@@ -119,7 +121,8 @@ static void usb_stor_blocking_completion(struct urb *urb)
 	complete(urb_done_ptr);
 }
 
-/* This is the common part of the URB message submission code
+/*
+ * This is the common part of the URB message submission code
  *
  * All URBs from the usb-storage driver involved in handling a queued scsi
  * command _must_ pass through this function (or something like it) for the
@@ -142,10 +145,12 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
 	us->current_urb->context = &urb_done;
 	us->current_urb->transfer_flags = 0;
 
-	/* we assume that if transfer_buffer isn't us->iobuf then it
+	/*
+	 * we assume that if transfer_buffer isn't us->iobuf then it
 	 * hasn't been mapped for DMA.  Yes, this is clunky, but it's
 	 * easier than always having the caller tell us whether the
-	 * transfer buffer has already been mapped. */
+	 * transfer buffer has already been mapped.
+	 */
 	if (us->current_urb->transfer_buffer == us->iobuf)
 		us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	us->current_urb->transfer_dma = us->iobuf_dma;
@@ -157,8 +162,10 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
 		return status;
 	}
 
-	/* since the URB has been submitted successfully, it's now okay
-	 * to cancel it */
+	/*
+	 * since the URB has been submitted successfully, it's now okay
+	 * to cancel it
+	 */
 	set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
 
 	/* did an abort occur during the submission? */
@@ -220,7 +227,8 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
 }
 EXPORT_SYMBOL_GPL(usb_stor_control_msg);
 
-/* This is a version of usb_clear_halt() that allows early termination and
+/*
+ * This is a version of usb_clear_halt() that allows early termination and
  * doesn't read the status from the device -- this is because some devices
  * crash their internal firmware when the status is requested after a halt.
  *
@@ -280,8 +288,10 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
 
 	/* stalled */
 	case -EPIPE:
-		/* for control endpoints, (used by CB[I]) a stall indicates
-		 * a failed command */
+		/*
+		 * for control endpoints, (used by CB[I]) a stall indicates
+		 * a failed command
+		 */
 		if (usb_pipecontrol(pipe)) {
 			usb_stor_dbg(us, "-- stall on control pipe\n");
 			return USB_STOR_XFER_STALLED;
@@ -433,8 +443,10 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 		return USB_STOR_XFER_ERROR;
 	}
 
-	/* since the block has been initialized successfully, it's now
-	 * okay to cancel it */
+	/*
+	 * since the block has been initialized successfully, it's now
+	 * okay to cancel it
+	 */
 	set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
 
 	/* did an abort occur during the submission? */
@@ -515,7 +527,8 @@ EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_sg);
  * Transport routines
  ***********************************************************************/
 
-/* There are so many devices that report the capacity incorrectly,
+/*
+ * There are so many devices that report the capacity incorrectly,
  * this routine was written to counteract some of the resulting
  * problems.
  */
@@ -533,7 +546,8 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
 		[12]	= 0x14			/* Record Not Found */
 	};
 
-	/* If last-sector problems can't occur, whether because the
+	/*
+	 * If last-sector problems can't occur, whether because the
 	 * capacity was already decremented or because the device is
 	 * known to report the correct capacity, then we don't need
 	 * to do anything.
@@ -559,13 +573,15 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
 
 	if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) {
 
-		/* The command succeeded.  We know this device doesn't
+		/*
+		 * The command succeeded.  We know this device doesn't
 		 * have the last-sector bug, so stop checking it.
 		 */
 		us->use_last_sector_hacks = 0;
 
 	} else {
-		/* The command failed.  Allow up to 3 retries in case this
+		/*
+		 * The command failed.  Allow up to 3 retries in case this
 		 * is some normal sort of failure.  After that, assume the
 		 * capacity is wrong and we're trying to access the sector
 		 * beyond the end.  Replace the result code and sense data
@@ -581,7 +597,8 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
 	}
 
  done:
-	/* Don't reset the retry counter for TEST UNIT READY commands,
+	/*
+	 * Don't reset the retry counter for TEST UNIT READY commands,
 	 * because they get issued after device resets which might be
 	 * caused by a failed last-sector access.
 	 */
@@ -589,7 +606,8 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
 		us->last_sector_retries = 0;
 }
 
-/* Invoke the transport and basic error-handling/recovery methods
+/*
+ * Invoke the transport and basic error-handling/recovery methods
  *
  * This is used by the protocol layers to actually send the message to
  * the device and receive the response.
@@ -603,7 +621,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 	scsi_set_resid(srb, 0);
 	result = us->transport(srb, us);
 
-	/* if the command gets aborted by the higher layers, we need to
+	/*
+	 * if the command gets aborted by the higher layers, we need to
 	 * short-circuit all other processing
 	 */
 	if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
@@ -628,7 +647,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	srb->result = SAM_STAT_GOOD;
 
-	/* Determine if we need to auto-sense
+	/*
+	 * Determine if we need to auto-sense
 	 *
 	 * I normally don't use a flag like this, but it's almost impossible
 	 * to understand what's going on here if I don't.
@@ -728,7 +748,8 @@ Retry_Sense:
 			goto Handle_Errors;
 		}
 
-		/* Some devices claim to support larger sense but fail when
+		/*
+		 * Some devices claim to support larger sense but fail when
 		 * trying to request it. When a transport failure happens
 		 * using US_FS_SANE_SENSE, we always retry with a standard
 		 * (small) sense request. This fixes some USB GSM modems
@@ -746,7 +767,8 @@ Retry_Sense:
 		if (temp_result != USB_STOR_TRANSPORT_GOOD) {
 			usb_stor_dbg(us, "-- auto-sense failure\n");
 
-			/* we skip the reset if this happens to be a
+			/*
+			 * we skip the reset if this happens to be a
 			 * multi-target device, since failure of an
 			 * auto-sense is perfectly valid
 			 */
@@ -756,7 +778,8 @@ Retry_Sense:
 			return;
 		}
 
-		/* If the sense data returned is larger than 18-bytes then we
+		/*
+		 * If the sense data returned is larger than 18-bytes then we
 		 * assume this device supports requesting more in the future.
 		 * The response code must be 70h through 73h inclusive.
 		 */
@@ -767,7 +790,8 @@ Retry_Sense:
 			usb_stor_dbg(us, "-- SANE_SENSE support enabled\n");
 			us->fflags |= US_FL_SANE_SENSE;
 
-			/* Indicate to the user that we truncated their sense
+			/*
+			 * Indicate to the user that we truncated their sense
 			 * because we didn't know it supported larger sense.
 			 */
 			usb_stor_dbg(us, "-- Sense data truncated to %i from %i\n",
@@ -795,13 +819,15 @@ Retry_Sense:
 					    SCSI_SENSE_BUFFERSIZE, 4);
 		fm_ili = (scdd ? scdd[3] : srb->sense_buffer[2]) & 0xA0;
 
-		/* We often get empty sense data.  This could indicate that
+		/*
+		 * We often get empty sense data.  This could indicate that
 		 * everything worked or that there was an unspecified
 		 * problem.  We have to decide which.
 		 */
 		if (sshdr.sense_key == 0 && sshdr.asc == 0 && sshdr.ascq == 0 &&
 		    fm_ili == 0) {
-			/* If things are really okay, then let's show that.
+			/*
+			 * If things are really okay, then let's show that.
 			 * Zero out the sense buffer so the higher layers
 			 * won't realize we did an unsolicited auto-sense.
 			 */
@@ -809,7 +835,8 @@ Retry_Sense:
 				srb->result = SAM_STAT_GOOD;
 				srb->sense_buffer[0] = 0x0;
 
-			/* If there was a problem, report an unspecified
+			/*
+			 * If there was a problem, report an unspecified
 			 * hardware error to prevent the higher layers from
 			 * entering an infinite retry loop.
 			 */
@@ -860,20 +887,26 @@ Retry_Sense:
 	last_sector_hacks(us, srb);
 	return;
 
-	/* Error and abort processing: try to resynchronize with the device
+	/*
+	 * Error and abort processing: try to resynchronize with the device
 	 * by issuing a port reset.  If that fails, try a class-specific
-	 * device reset. */
+	 * device reset.
+	 */
   Handle_Errors:
 
-	/* Set the RESETTING bit, and clear the ABORTING bit so that
-	 * the reset may proceed. */
+	/*
+	 * Set the RESETTING bit, and clear the ABORTING bit so that
+	 * the reset may proceed.
+	 */
 	scsi_lock(us_to_host(us));
 	set_bit(US_FLIDX_RESETTING, &us->dflags);
 	clear_bit(US_FLIDX_ABORTING, &us->dflags);
 	scsi_unlock(us_to_host(us));
 
-	/* We must release the device lock because the pre_reset routine
-	 * will want to acquire it. */
+	/*
+	 * We must release the device lock because the pre_reset routine
+	 * will want to acquire it.
+	 */
 	mutex_unlock(&us->dev_mutex);
 	result = usb_stor_port_reset(us);
 	mutex_lock(&us->dev_mutex);
@@ -891,10 +924,12 @@ Retry_Sense:
 /* Stop the current URB transfer */
 void usb_stor_stop_transport(struct us_data *us)
 {
-	/* If the state machine is blocked waiting for an URB,
+	/*
+	 * If the state machine is blocked waiting for an URB,
 	 * let's wake it up.  The test_and_clear_bit() call
 	 * guarantees that if a URB has just been submitted,
-	 * it won't be cancelled more than once. */
+	 * it won't be cancelled more than once.
+	 */
 	if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
 		usb_stor_dbg(us, "-- cancelling URB\n");
 		usb_unlink_urb(us->current_urb);
@@ -955,7 +990,8 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
 
 	/* STATUS STAGE */
 
-	/* NOTE: CB does not have a status stage.  Silly, I know.  So
+	/*
+	 * NOTE: CB does not have a status stage.  Silly, I know.  So
 	 * we have to catch this at a higher level.
 	 */
 	if (us->protocol != USB_PR_CBI)
@@ -967,7 +1003,8 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	/* UFI gives us ASC and ASCQ, like a request sense
+	/*
+	 * UFI gives us ASC and ASCQ, like a request sense
 	 *
 	 * REQUEST_SENSE and INQUIRY don't affect the sense data on UFI
 	 * devices, so we ignore the information for those commands.  Note
@@ -983,7 +1020,8 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
 		return USB_STOR_TRANSPORT_GOOD;
 	}
 
-	/* If not UFI, we interpret the data as a result code 
+	/*
+	 * If not UFI, we interpret the data as a result code 
 	 * The first byte should always be a 0x0.
 	 *
 	 * Some bogus devices don't follow that rule.  They stuff the ASC
@@ -1005,7 +1043,8 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
 	}
 	return USB_STOR_TRANSPORT_ERROR;
 
-	/* the CBI spec requires that the bulk pipe must be cleared
+	/*
+	 * the CBI spec requires that the bulk pipe must be cleared
 	 * following any data-in/out command failure (section 2.4.3.1.3)
 	 */
   Failed:
@@ -1107,9 +1146,11 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 	/* DATA STAGE */
 	/* send/receive data payload, if there is any */
 
-	/* Some USB-IDE converter chips need a 100us delay between the
+	/*
+	 * Some USB-IDE converter chips need a 100us delay between the
 	 * command phase and the data phase.  Some devices need a little
-	 * more than that, probably because of clock rate inaccuracies. */
+	 * more than that, probably because of clock rate inaccuracies.
+	 */
 	if (unlikely(us->fflags & US_FL_GO_SLOW))
 		usleep_range(125, 150);
 
@@ -1121,7 +1162,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 		if (result == USB_STOR_XFER_ERROR)
 			return USB_STOR_TRANSPORT_ERROR;
 
-		/* If the device tried to send back more data than the
+		/*
+		 * If the device tried to send back more data than the
 		 * amount requested, the spec requires us to transfer
 		 * the CSW anyway.  Since there's no point retrying the
 		 * the command, we'll return fake sense data indicating
@@ -1156,7 +1198,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 		}
 	}
 
-	/* See flow chart on pg 15 of the Bulk Only Transport spec for
+	/*
+	 * See flow chart on pg 15 of the Bulk Only Transport spec for
 	 * an explanation of how this code works.
 	 */
 
@@ -1165,7 +1208,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 				bcs, US_BULK_CS_WRAP_LEN, &cswlen);
 
-	/* Some broken devices add unnecessary zero-length packets to the
+	/*
+	 * Some broken devices add unnecessary zero-length packets to the
 	 * end of their data transfers.  Such packets show up as 0-length
 	 * CSWs.  If we encounter such a thing, try to read the CSW again.
 	 */
@@ -1201,7 +1245,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	/* Some broken devices report odd signatures, so we do not check them
+	/*
+	 * Some broken devices report odd signatures, so we do not check them
 	 * for validity against the spec. We store the first one we see,
 	 * and check subsequent transfers for validity against this signature.
 	 */
@@ -1217,11 +1262,14 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	/* try to compute the actual residue, based on how much data
-	 * was really transferred and what the device tells us */
+	/*
+	 * try to compute the actual residue, based on how much data
+	 * was really transferred and what the device tells us
+	 */
 	if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
 
-		/* Heuristically detect devices that generate bogus residues
+		/*
+		 * Heuristically detect devices that generate bogus residues
 		 * by seeing what happens with INQUIRY and READ CAPACITY
 		 * commands.
 		 */
@@ -1259,7 +1307,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 			return USB_STOR_TRANSPORT_FAILED;
 
 		case US_BULK_STAT_PHASE:
-			/* phase error -- note that a transport reset will be
+			/*
+			 * phase error -- note that a transport reset will be
 			 * invoked by the invoke_transport() function
 			 */
 			return USB_STOR_TRANSPORT_ERROR;
@@ -1274,7 +1323,8 @@ EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport);
  * Reset routines
  ***********************************************************************/
 
-/* This is the common part of the device reset code.
+/*
+ * This is the common part of the device reset code.
  *
  * It's handy that every transport mechanism uses the control endpoint for
  * resets.
@@ -1302,8 +1352,10 @@ static int usb_stor_reset_common(struct us_data *us,
 		return result;
 	}
 
-	/* Give the device some time to recover from the reset,
-	 * but don't delay disconnect processing. */
+	/*
+	 * Give the device some time to recover from the reset,
+	 * but don't delay disconnect processing.
+	 */
 	wait_event_interruptible_timeout(us->delay_wait,
 			test_bit(US_FLIDX_DISCONNECTING, &us->dflags),
 			HZ*6);
@@ -1328,8 +1380,7 @@ static int usb_stor_reset_common(struct us_data *us,
 	return result;
 }
 
-/* This issues a CB[I] Reset to the device in question
- */
+/* This issues a CB[I] Reset to the device in question */
 #define CB_RESET_CMD_SIZE	12
 
 int usb_stor_CB_reset(struct us_data *us)
@@ -1343,7 +1394,8 @@ int usb_stor_CB_reset(struct us_data *us)
 }
 EXPORT_SYMBOL_GPL(usb_stor_CB_reset);
 
-/* This issues a Bulk-only Reset to the device in question, including
+/*
+ * This issues a Bulk-only Reset to the device in question, including
  * clearing the subsequent endpoint halts that may occur.
  */
 int usb_stor_Bulk_reset(struct us_data *us)
@@ -1354,7 +1406,8 @@ int usb_stor_Bulk_reset(struct us_data *us)
 }
 EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset);
 
-/* Issue a USB port reset to the device.  The caller must not hold
+/*
+ * Issue a USB port reset to the device.  The caller must not hold
  * us->dev_mutex.
  */
 int usb_stor_port_reset(struct us_data *us)
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
index 9369d752d419..dae3ecd2e6cf 100644
--- a/drivers/usb/storage/transport.h
+++ b/drivers/usb/storage/transport.h
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * Transport Functions Header File
  *
  * Current development and maintenance by:
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 16bc679dc2fc..4d49fce406e1 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -799,7 +799,8 @@ static int uas_slave_alloc(struct scsi_device *sdev)
 
 	sdev->hostdata = devinfo;
 
-	/* USB has unusual DMA-alignment requirements: Although the
+	/*
+	 * USB has unusual DMA-alignment requirements: Although the
 	 * starting address of each scatter-gather element doesn't matter,
 	 * the length of each element except the last must be divisible
 	 * by the Bulk maxpacket value.  There's currently no way to
diff --git a/drivers/usb/storage/unusual_alauda.h b/drivers/usb/storage/unusual_alauda.h
index fa3e9edaa2cf..763bc03032a1 100644
--- a/drivers/usb/storage/unusual_alauda.h
+++ b/drivers/usb/storage/unusual_alauda.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for the Alauda-based card readers
+/*
+ * Unusual Devices File for the Alauda-based card readers
  *
  * 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
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h
index 82e8ed0324e3..e9a2eb88869a 100644
--- a/drivers/usb/storage/unusual_cypress.h
+++ b/drivers/usb/storage/unusual_cypress.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for devices based on the Cypress USB/ATA bridge
+/*
+ * Unusual Devices File for devices based on the Cypress USB/ATA bridge
  *	with support for ATACB
  *
  * This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/usb/storage/unusual_datafab.h b/drivers/usb/storage/unusual_datafab.h
index 582a603c78be..5049b6bbe5d5 100644
--- a/drivers/usb/storage/unusual_datafab.h
+++ b/drivers/usb/storage/unusual_datafab.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for the Datafab USB Compact Flash reader
+/*
+ * Unusual Devices File for the Datafab USB Compact Flash reader
  *
  * 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
@@ -79,7 +80,8 @@ UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
 		USB_SC_SCSI, USB_PR_DATAFAB, NULL,
 		0),
 
-/* Reported by Felix Moeller <felix@derklecks.de>
+/*
+ * Reported by Felix Moeller <felix@derklecks.de>
  * in Germany this is sold by Hama with the productnumber 46952
  * as "DualSlot CompactFlash(TM) & MStick Drive USB"
  */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 7ffe4209067b..aa3539238848 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * Unusual Devices File
  *
  * Current development and maintenance by:
@@ -25,13 +26,15 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* IMPORTANT NOTE: This file must be included in another file which does
+/*
+ * IMPORTANT NOTE: This file must be included in another file which does
  * the following thing for it to work:
  * The UNUSUAL_DEV, COMPLIANT_DEV, and USUAL_DEV macros must be defined
  * before this file is included.
  */
 
-/* If you edit this file, please try to keep it sorted first by VendorID,
+/*
+ * If you edit this file, please try to keep it sorted first by VendorID,
  * then by ProductID.
  *
  * If you want to add an entry for this file, be sure to include the
@@ -47,13 +50,15 @@
  * <usb-storage@lists.one-eyed-alien.net>
  */
 
-/* Note: If you add an entry only in order to set the CAPACITY_OK flag,
+/*
+ * Note: If you add an entry only in order to set the CAPACITY_OK flag,
  * use the COMPLIANT_DEV macro instead of UNUSUAL_DEV.  This is
  * because such entries mark devices which actually work correctly,
  * as opposed to devices that do something strangely or wrongly.
  */
 
-/* In-kernel mode switching is deprecated.  Do not add new devices to
+/*
+ * In-kernel mode switching is deprecated.  Do not add new devices to
  * this list for the sole purpose of switching them to a different
  * mode.  Existing userspace solutions are superior.
  *
@@ -66,8 +71,7 @@
 #define NO_SDDR09
 #endif
 
-/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr>
- */
+/* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> */
 UNUSUAL_DEV(  0x03eb, 0x2002, 0x0100, 0x0100,
 		"ATMEL",
 		"SND1 Storage",
@@ -93,7 +97,8 @@ UNUSUAL_DEV(  0x03f0, 0x070c, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_SANE_SENSE ),
 
-/* Reported by Grant Grundler <grundler@parisc-linux.org>
+/*
+ * Reported by Grant Grundler <grundler@parisc-linux.org>
  * HP r707 camera in "Disk" mode with 2.00.23 or 2.00.24 firmware.
  */
 UNUSUAL_DEV(  0x03f0, 0x4002, 0x0001, 0x0001,
@@ -107,7 +112,8 @@ UNUSUAL_DEV(  0x03f3, 0x0001, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init,
 		US_FL_SCM_MULT_TARG ),
 
-/* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
+/*
+ * Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
  * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
  * for USB floppies that need the SINGLE_LUN enforcement.
  */
@@ -124,7 +130,8 @@ UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Deduced by Jonathan Woithe <jwoithe@just42.net>
+/*
+ * Deduced by Jonathan Woithe <jwoithe@just42.net>
  * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
  * always fails and confuses drive.
  */
@@ -167,8 +174,10 @@ UNUSUAL_DEV(  0x0420, 0x0001, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Andrew Nayenko <relan@bk.ru>
- * Updated for new firmware by Phillip Potter <phillipinda@hotmail.com> */
+/*
+ * Reported by Andrew Nayenko <relan@bk.ru>
+ * Updated for new firmware by Phillip Potter <phillipinda@hotmail.com>
+ */
 UNUSUAL_DEV(  0x0421, 0x0019, 0x0592, 0x0610,
 		"Nokia",
 		"Nokia 6288",
@@ -196,16 +205,20 @@ UNUSUAL_DEV(  0x0421, 0x0434, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
- * Einar Th. Einarsson <einarthered@gmail.com> */
+/*
+ * Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
+ * Einar Th. Einarsson <einarthered@gmail.com>
+ */
 UNUSUAL_DEV(  0x0421, 0x0444, 0x0100, 0x0100,
 		"Nokia",
 		"N91",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
 
-/* Reported by Jiri Slaby <jirislaby@gmail.com> and
- * Rene C. Castberg <Rene@Castberg.org> */
+/*
+ * Reported by Jiri Slaby <jirislaby@gmail.com> and
+ * Rene C. Castberg <Rene@Castberg.org>
+ */
 UNUSUAL_DEV(  0x0421, 0x0446, 0x0100, 0x0100,
 		"Nokia",
 		"N80",
@@ -269,8 +282,10 @@ UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
 		US_FL_SINGLE_LUN ),
 #endif
 
-/* Patch submitted by Daniel Drake <dsd@gentoo.org>
- * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */
+/*
+ * Patch submitted by Daniel Drake <dsd@gentoo.org>
+ * Device reports nonsense bInterfaceProtocol 6 when connected over USB2
+ */
 UNUSUAL_DEV(  0x0451, 0x5416, 0x0100, 0x0100,
 		"Neuros Audio",
 		"USB 2.0 HD 2.5",
@@ -288,17 +303,18 @@ UNUSUAL_DEV(  0x0457, 0x0150, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
 
 /*
-* Bohdan Linda <bohdan.linda@gmail.com>
-* 1GB USB sticks MyFlash High Speed. I have restricted
-* the revision to my model only
-*/
+ * Bohdan Linda <bohdan.linda@gmail.com>
+ * 1GB USB sticks MyFlash High Speed. I have restricted
+ * the revision to my model only
+ */
 UNUSUAL_DEV(  0x0457, 0x0151, 0x0100, 0x0100,
 		"USB 2.0",
 		"Flash Disk",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NOT_LOCKABLE ),
 
-/* Reported by Tamas Kerecsen <kerecsen@bigfoot.com>
+/*
+ * Reported by Tamas Kerecsen <kerecsen@bigfoot.com>
  * Obviously the PROM has not been customized by the VAR;
  * the Vendor and Product string descriptors are:
  *	Generic Mass Storage (PROTOTYPE--Remember to change idVendor)
@@ -347,24 +363,30 @@ UNUSUAL_DEV(  0x0482, 0x0107, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE),
 
-/* Reported by Paul Stewart <stewart@wetlogic.net>
- * This entry is needed because the device reports Sub=ff */
+/*
+ * Reported by Paul Stewart <stewart@wetlogic.net>
+ * This entry is needed because the device reports Sub=ff
+ */
 UNUSUAL_DEV(  0x04a4, 0x0004, 0x0001, 0x0001,
 		"Hitachi",
 		"DVD-CAM DZ-MV100A Camcorder",
 		USB_SC_SCSI, USB_PR_CB, NULL, US_FL_SINGLE_LUN),
 
-/* BENQ DC5330
+/*
+ * BENQ DC5330
  * Reported by Manuel Fombuena <mfombuena@ya.com> and
- * Frank Copeland <fjc@thingy.apana.org.au> */
+ * Frank Copeland <fjc@thingy.apana.org.au>
+ */
 UNUSUAL_DEV(  0x04a5, 0x3010, 0x0100, 0x0100,
 		"Tekom Technologies, Inc",
 		"300_CAMERA",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Patch for Nikon coolpix 2000
- * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/
+/*
+ * Patch for Nikon coolpix 2000
+ * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>
+ */
 UNUSUAL_DEV(  0x04b0, 0x0301, 0x0010, 0x0010,
 		"NIKON",
 		"NIKON DSC E2000",
@@ -378,21 +400,26 @@ UNUSUAL_DEV(  0x04b3, 0x4001, 0x0110, 0x0110,
 		USB_SC_DEVICE, USB_PR_CB, NULL,
 		US_FL_MAX_SECTORS_MIN),
 
-/* Reported by Simon Levitt <simon@whattf.com>
- * This entry needs Sub and Proto fields */
+/*
+ * Reported by Simon Levitt <simon@whattf.com>
+ * This entry needs Sub and Proto fields
+ */
 UNUSUAL_DEV(  0x04b8, 0x0601, 0x0100, 0x0100,
 		"Epson",
 		"875DC Storage",
 		USB_SC_SCSI, USB_PR_CB, NULL, US_FL_FIX_INQUIRY),
 
-/* Reported by Khalid Aziz <khalid@gonehiking.org>
- * This entry is needed because the device reports Sub=ff */
+/*
+ * Reported by Khalid Aziz <khalid@gonehiking.org>
+ * This entry is needed because the device reports Sub=ff
+ */
 UNUSUAL_DEV(  0x04b8, 0x0602, 0x0110, 0x0110,
 		"Epson",
 		"785EPX Storage",
 		USB_SC_SCSI, USB_PR_BULK, NULL, US_FL_SINGLE_LUN),
 
-/* Not sure who reported this originally but
+/*
+ * Not sure who reported this originally but
  * Pavel Machek <pavel@ucw.cz> reported that the extra US_FL_SINGLE_LUN
  * flag be added */
 UNUSUAL_DEV(  0x04cb, 0x0100, 0x0000, 0x2210,
@@ -400,7 +427,8 @@ UNUSUAL_DEV(  0x04cb, 0x0100, 0x0000, 0x2210,
 		"FinePix 1400Zoom",
 		USB_SC_UFI, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN),
 
-/* Reported by Ondrej Zary <linux@rainbow-software.org>
+/*
+ * Reported by Ondrej Zary <linux@rainbow-software.org>
  * The device reports one sector more and breaks when that sector is accessed
  */
 UNUSUAL_DEV(  0x04ce, 0x0002, 0x026c, 0x026c,
@@ -409,7 +437,8 @@ UNUSUAL_DEV(  0x04ce, 0x0002, 0x026c, 0x026c,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
-/* Reported by Kriston Fincher <kriston@airmail.net>
+/*
+ * Reported by Kriston Fincher <kriston@airmail.net>
  * Patch submitted by Sean Millichamp <sean@bruenor.org>
  * This is to support the Panasonic PalmCam PV-SD4090
  * This entry is needed because the device reports Sub=ff 
@@ -419,8 +448,10 @@ UNUSUAL_DEV(  0x04da, 0x0901, 0x0100, 0x0200,
 		"LS-120 Camera",
 		USB_SC_UFI, USB_PR_DEVICE, NULL, 0),
 
-/* From Yukihiro Nakai, via zaitcev@yahoo.com.
- * This is needed for CB instead of CBI */
+/*
+ * From Yukihiro Nakai, via zaitcev@yahoo.com.
+ * This is needed for CB instead of CBI
+ */
 UNUSUAL_DEV(  0x04da, 0x0d05, 0x0000, 0x0000,
 		"Sharp CE-CW05",
 		"CD-R/RW Drive",
@@ -440,7 +471,8 @@ UNUSUAL_DEV(  0x04da, 0x2373, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ),
 
-/* Most of the following entries were developed with the help of
+/*
+ * Most of the following entries were developed with the help of
  * Shuttle/SCM directly.
  */
 UNUSUAL_DEV(  0x04e6, 0x0001, 0x0200, 0x0200,
@@ -536,7 +568,8 @@ UNUSUAL_DEV(  0x04e8, 0x5136, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_MAX_SECTORS_64),
 
-/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+/*
+ * Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
  * Device uses standards-violating 32-byte Bulk Command Block Wrappers and
  * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011.
  */
@@ -553,7 +586,8 @@ UNUSUAL_DEV(  0x050d, 0x0115, 0x0133, 0x0133,
 		USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init,
 		US_FL_SCM_MULT_TARG ),
 
-/* Iomega Clik! Drive 
+/*
+ * Iomega Clik! Drive 
  * Reported by David Chatenay <dchatenay@hotmail.com>
  * The reason this is needed is not fully known.
  */
@@ -570,7 +604,8 @@ COMPLIANT_DEV(0x0525, 0xa4a5, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_CAPACITY_OK ),
 
-/* Yakumo Mega Image 37
+/*
+ * Yakumo Mega Image 37
  * Submitted by Stephan Fuhrmann <atomenergie@t-online.de> */
 UNUSUAL_DEV(  0x052b, 0x1801, 0x0100, 0x0100,
 		"Tekom Technologies, Inc",
@@ -578,8 +613,10 @@ UNUSUAL_DEV(  0x052b, 0x1801, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Another Yakumo camera.
- * Reported by Michele Alzetta <michele.alzetta@aliceposta.it> */
+/*
+ * Another Yakumo camera.
+ * Reported by Michele Alzetta <michele.alzetta@aliceposta.it>
+ */
 UNUSUAL_DEV(  0x052b, 0x1804, 0x0100, 0x0100,
 		"Tekom Technologies, Inc",
 		"300_CAMERA",
@@ -593,16 +630,20 @@ UNUSUAL_DEV(  0x052b, 0x1807, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Yakumo Mega Image 47
- * Reported by Bjoern Paetzel <kolrabi@kolrabi.de> */
+/*
+ * Yakumo Mega Image 47
+ * Reported by Bjoern Paetzel <kolrabi@kolrabi.de>
+ */
 UNUSUAL_DEV(  0x052b, 0x1905, 0x0100, 0x0100,
 		"Tekom Technologies, Inc",
 		"400_CAMERA",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Paul Ortyl <ortylp@3miasto.net>
- * Note that it's similar to the device above, only different prodID */
+/*
+ * Reported by Paul Ortyl <ortylp@3miasto.net>
+ * Note that it's similar to the device above, only different prodID
+ */
 UNUSUAL_DEV(  0x052b, 0x1911, 0x0100, 0x0100,
 		"Tekom Technologies, Inc",
 		"400_CAMERA",
@@ -615,8 +656,10 @@ UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0450,
 		USB_SC_SCSI, USB_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
 
-/* Submitted by Lars Jacob <jacob.lars@googlemail.com>
- * This entry is needed because the device reports Sub=ff */
+/*
+ * Submitted by Lars Jacob <jacob.lars@googlemail.com>
+ * This entry is needed because the device reports Sub=ff
+ */
 UNUSUAL_DEV(  0x054c, 0x0010, 0x0500, 0x0610,
 		"Sony",
 		"DSC-T1/T5/H5",
@@ -719,7 +762,8 @@ UNUSUAL_DEV(  0x057b, 0x0000, 0x0000, 0x0299,
 		USB_SC_DEVICE,  USB_PR_CB, NULL,
 		US_FL_SINGLE_LUN),
 
-/* Reported by Johann Cardon <johann.cardon@free.fr>
+/*
+ * Reported by Johann Cardon <johann.cardon@free.fr>
  * This entry is needed only because the device reports
  * bInterfaceClass = 0xff (vendor-specific)
  */
@@ -741,7 +785,8 @@ UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
 		"Digital Camera EX-20 DSC",
 		USB_SC_8070, USB_PR_DEVICE, NULL, 0 ),
 
-/* Reported by Andre Welter <a.r.welter@gmx.de>
+/*
+ * Reported by Andre Welter <a.r.welter@gmx.de>
  * This antique device predates the release of the Bulk-only Transport
  * spec, and if it gets a Get-Max-LUN then it requires the host to do a
  * Clear-Halt on the bulk endpoints.  The SINGLE_LUN flag will prevent
@@ -773,7 +818,8 @@ UNUSUAL_DEV(  0x059f, 0x0651, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NO_WP_DETECT ),
 
-/* Submitted by Joel Bourquard <numlock@freesurf.ch>
+/*
+ * Submitted by Joel Bourquard <numlock@freesurf.ch>
  * Some versions of this device need the SubClass and Protocol overrides
  * while others don't.
  */
@@ -783,7 +829,8 @@ UNUSUAL_DEV(  0x05ab, 0x0060, 0x1104, 0x1110,
 		USB_SC_SCSI, USB_PR_BULK, NULL,
 		US_FL_NEED_OVERRIDE ),
 
-/* Submitted by Sven Anderson <sven-linux@anderson.de>
+/*
+ * Submitted by Sven Anderson <sven-linux@anderson.de>
  * There are at least four ProductIDs used for iPods, so I added 0x1202 and
  * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears
  * to change with firmware updates, I changed the range to maximum for all
@@ -824,7 +871,8 @@ UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
-/* Reported by Dan Williams <dcbw@redhat.com>
+/*
+ * Reported by Dan Williams <dcbw@redhat.com>
  * Option N.V. mobile broadband modems
  * Ignore driver CD mode and force into modem mode by default.
  */
@@ -843,7 +891,8 @@ UNUSUAL_DEV(  0x05dc, 0xb002, 0x0000, 0x0113,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
-/* The following two entries are for a Genesys USB to IDE
+/*
+ * The following two entries are for a Genesys USB to IDE
  * converter chip, but it changes its ProductId depending
  * on whether or not a disk or an optical device is enclosed
  * They were originally reported by Alexander Oltu
@@ -873,8 +922,10 @@ UNUSUAL_DEV(  0x05e3, 0x0723, 0x9451, 0x9451,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_SANE_SENSE ),
 
-/* Reported by Hanno Boeck <hanno@gmx.de>
- * Taken from the Lycoris Kernel */
+/*
+ * Reported by Hanno Boeck <hanno@gmx.de>
+ * Taken from the Lycoris Kernel
+ */
 UNUSUAL_DEV(  0x0636, 0x0003, 0x0000, 0x9999,
 		"Vivitar",
 		"Vivicam 35Xx",
@@ -908,8 +959,10 @@ UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
 		US_FL_NOT_LOCKABLE ),
 
 /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */
-/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by
- * Thomas Bartosik <tbartdev@gmx-topmail.de> */
+/*
+ * Change to bcdDeviceMin (0x0100 to 0x0001) reported by
+ * Thomas Bartosik <tbartdev@gmx-topmail.de>
+ */
 UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100,
 		"Prolific Technology Inc.",
 		"Mass Storage Device",
@@ -961,7 +1014,8 @@ UNUSUAL_DEV(  0x071b, 0x3203, 0x0000, 0x0000,
 		US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64 |
 		US_FL_NO_READ_CAPACITY_16),
 
-/* Reported by Jean-Baptiste Onofre <jb@nanthrax.net>
+/*
+ * Reported by Jean-Baptiste Onofre <jb@nanthrax.net>
  * Support the following product :
  *    "Dane-Elec MediaTouch"
  */
@@ -971,7 +1025,8 @@ UNUSUAL_DEV(  0x071b, 0x32bb, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
 
-/* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
+/*
+ * Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
  * This USB MP3/AVI player device fails and disconnects if more than 128
  * sectors (64kB) are read/written in a single command, and may be present
  * at least in the following products:
@@ -1040,7 +1095,8 @@ UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
 		US_FL_SINGLE_LUN ),
 #endif
 
-/* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
+/*
+ * Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
  * Only revision 1.13 tested (same for all of the above devices,
  * based on the Datafab DF-UG-07 chip).  Needed for US_FL_FIX_INQUIRY.
  * Submitted by Marek Michalkiewicz <marekm@amelek.gda.pl>.
@@ -1052,7 +1108,8 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0xffff,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ),
 
-/* Reported by Rauch Wolke <rauchwolke@gmx.net>
+/*
+ * Reported by Rauch Wolke <rauchwolke@gmx.net>
  * and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882)
  */
 UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
@@ -1061,7 +1118,8 @@ UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ),
 
-/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
+/*
+ * Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
  * to the USB storage specification in two ways:
  * - They tell us they are using transport protocol CBI. In reality they
  *   are using transport protocol CB.
@@ -1119,7 +1177,8 @@ UNUSUAL_DEV(  0x084b, 0xa001, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init,
 		US_FL_SCM_MULT_TARG ),
 
-/* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
+/*
+ * Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>.
  * Flag will support Bulk devices which use a standards-violating 32-byte
  * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
  * Grandtech GT892x chip, which request "Proprietary SCSI Bulk" support.
@@ -1131,7 +1190,8 @@ UNUSUAL_DEV(  0x084d, 0x0011, 0x0110, 0x0110,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_BULK32),
 
-/* Reported by <ttkspam@free.fr>
+/*
+ * Reported by <ttkspam@free.fr>
  * The device reports a vendor-specific device class, requiring an
  * explicit vendor/product match.
  */
@@ -1140,11 +1200,12 @@ UNUSUAL_DEV(  0x0851, 0x1542, 0x0002, 0x0002,
 		"FW_Omega2",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0),
 
-/* Andrew Lunn <andrew@lunn.ch>
+/*
+ * Andrew Lunn <andrew@lunn.ch>
  * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL
  * on LUN 4.
  * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera"
-*/
+ */
 UNUSUAL_DEV(  0x0851, 0x1543, 0x0200, 0x0200,
 		"PanDigital",
 		"Photo Frame",
@@ -1170,7 +1231,8 @@ UNUSUAL_DEV(  0x08bd, 0x1100, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN),
 
-/* Submitted by Dylan Taft <d13f00l@gmail.com>
+/*
+ * Submitted by Dylan Taft <d13f00l@gmail.com>
  * US_FL_IGNORE_RESIDUE Needed
  */
 UNUSUAL_DEV(  0x08ca, 0x3103, 0x0100, 0x0100,
@@ -1179,7 +1241,8 @@ UNUSUAL_DEV(  0x08ca, 0x3103, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE),
 
-/* Entry needed for flags. Moreover, all devices with this ID use
+/*
+ * Entry needed for flags. Moreover, all devices with this ID use
  * bulk-only transport, but _some_ falsely report Control/Bulk instead.
  * One example is "Trumpion Digital Research MYMP3".
  * Submitted by Bjoern Brill <brill(at)fs.math.uni-frankfurt.de>
@@ -1190,7 +1253,8 @@ UNUSUAL_DEV(  0x090a, 0x1001, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_BULK, NULL,
 		US_FL_NEED_OVERRIDE ),
 
-/* Reported by Filippo Bardelli <filibard@libero.it>
+/*
+ * Reported by Filippo Bardelli <filibard@libero.it>
  * The device reports a subclass of RBC, which is wrong.
  */
 UNUSUAL_DEV(  0x090a, 0x1050, 0x0100, 0x0100,
@@ -1213,7 +1277,8 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
-/* Reported by Paul Hartman <paul.hartman+linux@gmail.com>
+/*
+ * Reported by Paul Hartman <paul.hartman+linux@gmail.com>
  * This card reader returns "Illegal Request, Logical Block Address
  * Out of Range" for the first READ(10) after a new card is inserted.
  */
@@ -1223,7 +1288,8 @@ UNUSUAL_DEV(  0x090c, 0x6000, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_INITIAL_READ10 ),
 
-/* This Pentax still camera is not conformant
+/*
+ * This Pentax still camera is not conformant
  * to the USB storage specification: -
  * - It does not like the INQUIRY command. So we must handle this command
  *   of the SCSI layer ourselves.
@@ -1236,8 +1302,10 @@ UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
-/* These are virtual windows driver CDs, which the zd1211rw driver
- * automatically converts into WLAN devices. */
+/*
+ * These are virtual windows driver CDs, which the zd1211rw driver
+ * automatically converts into WLAN devices.
+ */
 UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
 		"ZyXEL",
 		"G-220F USB-WLAN Install",
@@ -1250,7 +1318,8 @@ UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_DEVICE ),
 
-/* Reported by Dan Williams <dcbw@redhat.com>
+/*
+ * Reported by Dan Williams <dcbw@redhat.com>
  * Option N.V. mobile broadband modems
  * Ignore driver CD mode and force into modem mode by default.
  */
@@ -1262,20 +1331,24 @@ UNUSUAL_DEV(  0x0af0, 0x6971, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init,
 		0),
 
-/* Reported by F. Aben <f.aben@option.com>
+/*
+ * Reported by F. Aben <f.aben@option.com>
  * This device (wrongly) has a vendor-specific device descriptor.
  * The entry is needed so usb-storage can bind to it's mass-storage
- * interface as an interface driver */
+ * interface as an interface driver
+ */
 UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000,
 		"Option",
 		"GI 0401 SD-Card",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		0 ),
 
-/* Reported by Jan Dumon <j.dumon@option.com>
+/*
+ * Reported by Jan Dumon <j.dumon@option.com>
  * These devices (wrongly) have a vendor-specific device descriptor.
  * These entries are needed so usb-storage can bind to their mass-storage
- * interface as an interface driver */
+ * interface as an interface driver
+ */
 UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000,
 		"Option",
 		"GI 0431 SD-Card",
@@ -1419,7 +1492,8 @@ UNUSUAL_DEV(  0x0dc4, 0x0073, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
-/* Reported by Lubomir Blaha <tritol@trilogic.cz>
+/*
+ * Reported by Lubomir Blaha <tritol@trilogic.cz>
  * I _REALLY_ don't know what 3rd, 4th number and all defines mean, but this
  * works for me. Can anybody correct these values? (I able to test corrected
  * version.)
@@ -1430,8 +1504,10 @@ UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
-/* Reported by Edward Chapman (taken from linux-usb mailing list)
-   Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */
+/*
+ * Reported by Edward Chapman (taken from linux-usb mailing list)
+ * Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive
+ */
 UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999,
 		"Netac",
 		"USB Flash Disk",
@@ -1439,8 +1515,10 @@ UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999,
 		US_FL_IGNORE_RESIDUE ),
 
 
-/* Patch by Stephan Walter <stephan.walter@epfl.ch>
- * I don't know why, but it works... */
+/*
+ * Patch by Stephan Walter <stephan.walter@epfl.ch>
+ * I don't know why, but it works...
+ */
 UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012,
 		"WINWARD",
 		"Music Disk",
@@ -1468,8 +1546,10 @@ UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
-/* Submitted by Daniel Drake <dsd@gentoo.org>
- * Reported by dayul on the Gentoo Forums */
+/*
+ * Submitted by Daniel Drake <dsd@gentoo.org>
+ * Reported by dayul on the Gentoo Forums
+ */
 UNUSUAL_DEV(  0x0ea0, 0x2168, 0x0110, 0x0110,
 		"Ours Technology",
 		"Flash Disk",
@@ -1483,15 +1563,18 @@ UNUSUAL_DEV(  0x0ea0, 0x6828, 0x0110, 0x0110,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Benjamin Schiller <sbenni@gmx.de>
- * It is also sold by Easylite as DJ 20 */
+/*
+ * Reported by Benjamin Schiller <sbenni@gmx.de>
+ * It is also sold by Easylite as DJ 20
+ */
 UNUSUAL_DEV(  0x0ed1, 0x7636, 0x0103, 0x0103,
 		"Typhoon",
 		"My DJ 1820",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
 
-/* Patch by Leonid Petrov mail at lpetrov.net
+/*
+ * Patch by Leonid Petrov mail at lpetrov.net
  * Reported by Robert Spitzenpfeil <robert@spitzenpfeil.org>
  * http://www.qbik.ch/usb/devices/showdev.php?id=1705
  * Updated to 103 device by MJ Ray mjr at phonecoop.coop
@@ -1502,7 +1585,8 @@ UNUSUAL_DEV(  0x0f19, 0x0103, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* David Kuehling <dvdkhlng@gmx.de>:
+/*
+ * David Kuehling <dvdkhlng@gmx.de>:
  * for MP3-Player AVOX WSX-300ER (bought in Japan).  Reports lots of SCSI
  * errors when trying to write.
  */
@@ -1540,8 +1624,10 @@ UNUSUAL_DEV(  0x0fce, 0xd0e1, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_DEVICE),
 
-/* Reported by Jan Mate <mate@fiit.stuba.sk>
- * and by Soeren Sonnenburg <kernel@nn7.de> */
+/*
+ * Reported by Jan Mate <mate@fiit.stuba.sk>
+ * and by Soeren Sonnenburg <kernel@nn7.de>
+ */
 UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
 		"Sony Ericsson",
 		"P990i",
@@ -1562,7 +1648,8 @@ UNUSUAL_DEV(  0x0fce, 0xe092, 0x0000, 0x0000,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
+/*
+ * Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
  * Tested on hardware version 1.10.
  * Entry is needed only for the initializer function override.
  * Devices with bcd > 110 seem to not need it while those
@@ -1586,7 +1673,8 @@ UNUSUAL_DEV(0x1058, 0x070a, 0x0000, 0x9999,
 		"My Passport HDD",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_WRITE_CACHE),
 
-/* Reported by Fabio Venturi <f.venturi@tdnet.it>
+/*
+ * Reported by Fabio Venturi <f.venturi@tdnet.it>
  * The device reports a vendor-specific bDeviceClass.
  */
 UNUSUAL_DEV(  0x10d6, 0x2200, 0x0100, 0x0100,
@@ -1595,7 +1683,8 @@ UNUSUAL_DEV(  0x10d6, 0x2200, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		0),
 
-/* Reported by Pascal Terjan <pterjan@mandriva.com>
+/*
+ * Reported by Pascal Terjan <pterjan@mandriva.com>
  * Ignore driver CD mode and force into modem mode by default.
  */
 UNUSUAL_DEV(  0x1186, 0x3e04, 0x0000, 0x0000,
@@ -1603,7 +1692,8 @@ UNUSUAL_DEV(  0x1186, 0x3e04, 0x0000, 0x0000,
            "USB Mass Storage",
            USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init, US_FL_IGNORE_DEVICE),
 
-/* Reported by Kevin Lloyd <linux@sierrawireless.com>
+/*
+ * Reported by Kevin Lloyd <linux@sierrawireless.com>
  * Entry is needed for the initializer function override,
  * which instructs the device to load as a modem
  * device.
@@ -1614,7 +1704,8 @@ UNUSUAL_DEV(  0x1199, 0x0fff, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, sierra_ms_init,
 		0),
 
-/* Reported by Jaco Kroon <jaco@kroon.co.za>
+/*
+ * Reported by Jaco Kroon <jaco@kroon.co.za>
  * The usb-storage module found on the Digitech GNX4 (and supposedly other
  * devices) misbehaves and causes a bunch of invalid I/O errors.
  */
@@ -1624,7 +1715,8 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Reported by fangxiaozhi <huananhu@huawei.com>
+/*
+ * Reported by fangxiaozhi <huananhu@huawei.com>
  * This brings the HUAWEI data card devices into multi-port mode
  */
 UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000,
@@ -1993,7 +2085,8 @@ UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_BROKEN_FUA ),
 
-/* Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+/*
+ * Reported by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
  * JMicron responds to USN and several other SCSI ioctls with a
  * residue that causes subsequent I/O requests to fail.  */
 UNUSUAL_DEV(  0x152d, 0x2329, 0x0100, 0x0100,
@@ -2009,7 +2102,8 @@ UNUSUAL_DEV(  0x152d, 0x2566, 0x0114, 0x0114,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_BROKEN_FUA ),
 
-/* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI)
+/*
+ * Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI)
  * and Mac USB Dock USB-SCSI */
 UNUSUAL_DEV(  0x1645, 0x0007, 0x0100, 0x0133,
 		"Entrega Technologies",
@@ -2017,8 +2111,10 @@ UNUSUAL_DEV(  0x1645, 0x0007, 0x0100, 0x0133,
 		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init,
 		US_FL_SCM_MULT_TARG ),
 
-/* Reported by Robert Schedel <r.schedel@yahoo.de>
- * Note: this is a 'super top' device like the above 14cd/6600 device */
+/*
+ * Reported by Robert Schedel <r.schedel@yahoo.de>
+ * Note: this is a 'super top' device like the above 14cd/6600 device
+ */
 UNUSUAL_DEV(  0x1652, 0x6600, 0x0201, 0x0201,
 		"Teac",
 		"HD-35PUK-B",
@@ -2045,10 +2141,12 @@ UNUSUAL_DEV(  0x1822, 0x0001, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init,
 		US_FL_SCM_MULT_TARG ),
 
-/* Reported by Hans de Goede <hdegoede@redhat.com>
+/*
+ * Reported by Hans de Goede <hdegoede@redhat.com>
  * These Appotech controllers are found in Picture Frames, they provide a
  * (buggy) emulation of a cdrom drive which contains the windows software
- * Uploading of pictures happens over the corresponding /dev/sg device. */
+ * Uploading of pictures happens over the corresponding /dev/sg device.
+ */
 UNUSUAL_DEV( 0x1908, 0x1315, 0x0000, 0x0000,
 		"BUILDWIN",
 		"Photo Frame",
@@ -2065,19 +2163,22 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NO_READ_DISC_INFO ),
 
-/* Reported by Oliver Neukum <oneukum@suse.com>
+/*
+ * Reported by Oliver Neukum <oneukum@suse.com>
  * This device morphes spontaneously into another device if the access
  * pattern of Windows isn't followed. Thus writable media would be dirty
  * if the initial instance is used. So the device is limited to its
  * virtual CD.
- * And yes, the concept that BCD goes up to 9 is not heeded */
+ * And yes, the concept that BCD goes up to 9 is not heeded
+ */
 UNUSUAL_DEV( 0x19d2, 0x1225, 0x0000, 0xffff,
 		"ZTE,Incorporated",
 		"ZTE WCDMA Technologies MSM",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN ),
 
-/* Reported by Sven Geggus <sven-usbst@geggus.net>
+/*
+ * Reported by Sven Geggus <sven-usbst@geggus.net>
  * This encrypted pen drive returns bogus data for the initial READ(10).
  */
 UNUSUAL_DEV(  0x1b1c, 0x1ab5, 0x0200, 0x0200,
@@ -2086,7 +2187,8 @@ UNUSUAL_DEV(  0x1b1c, 0x1ab5, 0x0200, 0x0200,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_INITIAL_READ10 ),
 
-/* Reported by Hans de Goede <hdegoede@redhat.com>
+/*
+ * Reported by Hans de Goede <hdegoede@redhat.com>
  * These are mini projectors using USB for both power and video data transport
  * The usb-storage interface is a virtual windows driver CD, which the gm12u320
  * driver automatically converts into framebuffer & kms dri device nodes.
@@ -2097,9 +2199,11 @@ UNUSUAL_DEV( 0x1de1, 0xc102, 0x0000, 0xffff,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_IGNORE_DEVICE ),
 
-/* Patch by Richard Schütz <r.schtz@t-online.de>
+/*
+ * Patch by Richard Schütz <r.schtz@t-online.de>
  * This external hard drive enclosure uses a JMicron chip which
- * needs the US_FL_IGNORE_RESIDUE flag to work properly. */
+ * needs the US_FL_IGNORE_RESIDUE flag to work properly.
+ */
 UNUSUAL_DEV(  0x1e68, 0x001b, 0x0000, 0x0000,
 		"TrekStor GmbH & Co. KG",
 		"DataStation maxi g.u",
@@ -2126,7 +2230,8 @@ UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
-/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
+/*
+ * patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
 UNUSUAL_DEV(  0x22b8, 0x3010, 0x0001, 0x0001,
@@ -2153,7 +2258,8 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_GO_SLOW ),
 
-/* Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
+/*
+ * Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
  * Mio Moov 330
  */
 UNUSUAL_DEV(  0x3340, 0xffff, 0x0000, 0x0000,
diff --git a/drivers/usb/storage/unusual_freecom.h b/drivers/usb/storage/unusual_freecom.h
index 59a261155b98..1f5aab42ece2 100644
--- a/drivers/usb/storage/unusual_freecom.h
+++ b/drivers/usb/storage/unusual_freecom.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for the Freecom USB/IDE adaptor
+/*
+ * Unusual Devices File for the Freecom USB/IDE adaptor
  *
  * 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
diff --git a/drivers/usb/storage/unusual_isd200.h b/drivers/usb/storage/unusual_isd200.h
index 14cca0c48302..9b6862ec3d4f 100644
--- a/drivers/usb/storage/unusual_isd200.h
+++ b/drivers/usb/storage/unusual_isd200.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for In-System Design, Inc. ISD200 ASIC
+/*
+ * Unusual Devices File for In-System Design, Inc. ISD200 ASIC
  *
  * 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
diff --git a/drivers/usb/storage/unusual_jumpshot.h b/drivers/usb/storage/unusual_jumpshot.h
index 54be78b5d643..413e64fa6b95 100644
--- a/drivers/usb/storage/unusual_jumpshot.h
+++ b/drivers/usb/storage/unusual_jumpshot.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader
+/*
+ * Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader
  *
  * 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
diff --git a/drivers/usb/storage/unusual_karma.h b/drivers/usb/storage/unusual_karma.h
index 6df03972a22c..e6fad3aeae20 100644
--- a/drivers/usb/storage/unusual_karma.h
+++ b/drivers/usb/storage/unusual_karma.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for the Rio Karma
+/*
+ * Unusual Devices File for the Rio Karma
  *
  * 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
diff --git a/drivers/usb/storage/unusual_onetouch.h b/drivers/usb/storage/unusual_onetouch.h
index 0abb819c7405..425dc22f345a 100644
--- a/drivers/usb/storage/unusual_onetouch.h
+++ b/drivers/usb/storage/unusual_onetouch.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for the Maxtor OneTouch USB hard drive's button
+/*
+ * Unusual Devices File for the Maxtor OneTouch USB hard drive's button
  *
  * 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
@@ -18,7 +19,8 @@
 #if defined(CONFIG_USB_STORAGE_ONETOUCH) || \
 		defined(CONFIG_USB_STORAGE_ONETOUCH_MODULE)
 
-/* Submitted by: Nick Sillik <n.sillik@temple.edu>
+/*
+ * Submitted by: Nick Sillik <n.sillik@temple.edu>
  * Needed for OneTouch extension to usb-storage
  */
 UNUSUAL_DEV(  0x0d49, 0x7000, 0x0000, 0x9999,
diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h
index e41f50c95ed4..8fe624ad302a 100644
--- a/drivers/usb/storage/unusual_realtek.h
+++ b/drivers/usb/storage/unusual_realtek.h
@@ -1,4 +1,5 @@
-/* Driver for Realtek RTS51xx USB card reader
+/*
+ * Driver for Realtek RTS51xx USB card reader
  *
  * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
  *
diff --git a/drivers/usb/storage/unusual_sddr09.h b/drivers/usb/storage/unusual_sddr09.h
index 59a7e37b6c11..d9d38ac4abf9 100644
--- a/drivers/usb/storage/unusual_sddr09.h
+++ b/drivers/usb/storage/unusual_sddr09.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for SanDisk SDDR-09 SmartMedia reader
+/*
+ * Unusual Devices File for SanDisk SDDR-09 SmartMedia reader
  *
  * 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
diff --git a/drivers/usb/storage/unusual_sddr55.h b/drivers/usb/storage/unusual_sddr55.h
index fcb7e12c598f..ebb1d1c6c467 100644
--- a/drivers/usb/storage/unusual_sddr55.h
+++ b/drivers/usb/storage/unusual_sddr55.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for SanDisk SDDR-55 SmartMedia reader
+/*
+ * Unusual Devices File for SanDisk SDDR-55 SmartMedia reader
  *
  * 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
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
index 53341a77d89f..cbea9f329e71 100644
--- a/drivers/usb/storage/unusual_uas.h
+++ b/drivers/usb/storage/unusual_uas.h
@@ -1,4 +1,5 @@
-/* Driver for USB Attached SCSI devices - Unusual Devices File
+/*
+ * Driver for USB Attached SCSI devices - Unusual Devices File
  *
  *   (c) 2013 Hans de Goede <hdegoede@redhat.com>
  *
diff --git a/drivers/usb/storage/unusual_usbat.h b/drivers/usb/storage/unusual_usbat.h
index 38e79c4e6d6a..2044ad5ef5e4 100644
--- a/drivers/usb/storage/unusual_usbat.h
+++ b/drivers/usb/storage/unusual_usbat.h
@@ -1,4 +1,5 @@
-/* Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
+/*
+ * Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
  *
  * 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
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 9de988a0f856..ef2d8cde6ef7 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  *
  * Current development and maintenance by:
  *   (c) 1999-2003 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -97,7 +98,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
  * with the entries in usb_storage_usb_ids[], defined in usual-tables.c.
  */
 
-/* The vendor name should be kept at eight characters or less, and
+/*
+ *The vendor name should be kept at eight characters or less, and
  * the product name should be kept at 16 characters or less. If a device
  * has the US_FL_FIX_INQUIRY flag, then the vendor and product names
  * normally generated by a device through the INQUIRY response will be
@@ -191,8 +193,10 @@ int usb_stor_suspend(struct usb_interface *iface, pm_message_t message)
 	if (us->suspend_resume_hook)
 		(us->suspend_resume_hook)(us, US_SUSPEND);
 
-	/* When runtime PM is working, we'll set a flag to indicate
-	 * whether we should autoresume when a SCSI request arrives. */
+	/*
+	 * When runtime PM is working, we'll set a flag to indicate
+	 * whether we should autoresume when a SCSI request arrives.
+	 */
 
 	mutex_unlock(&us->dev_mutex);
 	return 0;
@@ -220,8 +224,10 @@ int usb_stor_reset_resume(struct usb_interface *iface)
 	/* Report the reset to the SCSI core */
 	usb_stor_report_bus_reset(us);
 
-	/* FIXME: Notify the subdrivers that they need to reinitialize
-	 * the device */
+	/*
+	 * FIXME: Notify the subdrivers that they need to reinitialize
+	 * the device
+	 */
 	return 0;
 }
 EXPORT_SYMBOL_GPL(usb_stor_reset_resume);
@@ -250,8 +256,10 @@ int usb_stor_post_reset(struct usb_interface *iface)
 	/* Report the reset to the SCSI core */
 	usb_stor_report_bus_reset(us);
 
-	/* FIXME: Notify the subdrivers that they need to reinitialize
-	 * the device */
+	/*
+	 * FIXME: Notify the subdrivers that they need to reinitialize
+	 * the device
+	 */
 
 	mutex_unlock(&us->dev_mutex);
 	return 0;
@@ -274,15 +282,17 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
 		return;
 
 	memset(data+8, ' ', 28);
-	if (data[0]&0x20) { /* USB device currently not connected. Return
-			      peripheral qualifier 001b ("...however, the
-			      physical device is not currently connected
-			      to this logical unit") and leave vendor and
-			      product identification empty. ("If the target
-			      does store some of the INQUIRY data on the
-			      device, it may return zeros or ASCII spaces
-			      (20h) in those fields until the data is
-			      available from the device."). */
+	if (data[0]&0x20) { /*
+			     * USB device currently not connected. Return
+			     * peripheral qualifier 001b ("...however, the
+			     * physical device is not currently connected
+			     * to this logical unit") and leave vendor and
+			     * product identification empty. ("If the target
+			     * does store some of the INQUIRY data on the
+			     * device, it may return zeros or ASCII spaces
+			     * (20h) in those fields until the data is
+			     * available from the device.").
+			     */
 	} else {
 		u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
 		int n;
@@ -336,7 +346,8 @@ static int usb_stor_control_thread(void * __us)
 
 		scsi_unlock(host);
 
-		/* reject the command if the direction indicator
+		/*
+		 * reject the command if the direction indicator
 		 * is UNKNOWN
 		 */
 		if (us->srb->sc_data_direction == DMA_BIDIRECTIONAL) {
@@ -344,7 +355,8 @@ static int usb_stor_control_thread(void * __us)
 			us->srb->result = DID_ERROR << 16;
 		}
 
-		/* reject if target != 0 or if LUN is higher than
+		/*
+		 * reject if target != 0 or if LUN is higher than
 		 * the maximum known LUN
 		 */
 		else if (us->srb->device->id &&
@@ -362,8 +374,10 @@ static int usb_stor_control_thread(void * __us)
 			us->srb->result = DID_BAD_TARGET << 16;
 		}
 
-		/* Handle those devices which need us to fake
-		 * their inquiry data */
+		/*
+		 * Handle those devices which need us to fake
+		 * their inquiry data
+		 */
 		else if ((us->srb->cmnd[0] == INQUIRY) &&
 			    (us->fflags & US_FL_FIX_INQUIRY)) {
 			unsigned char data_ptr[36] = {
@@ -395,11 +409,13 @@ SkipForAbort:
 			usb_stor_dbg(us, "scsi command aborted\n");
 		}
 
-		/* If an abort request was received we need to signal that
+		/*
+		 * If an abort request was received we need to signal that
 		 * the abort has finished.  The proper test for this is
 		 * the TIMED_OUT flag, not srb->result == DID_ABORT, because
 		 * the timeout might have occurred after the command had
-		 * already completed with a different result code. */
+		 * already completed with a different result code.
+		 */
 		if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
 			complete(&(us->notify));
 
@@ -610,7 +626,8 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id,
 				le16_to_cpu(dev->descriptor.idProduct),
 				us->fflags);
 
-	/* Log a message if a non-generic unusual_dev entry contains an
+	/*
+	 * Log a message if a non-generic unusual_dev entry contains an
 	 * unnecessary subclass or protocol override.  This may stimulate
 	 * reports from users that will help us remove unneeded entries
 	 * from the unusual_devs.h table.
@@ -782,8 +799,10 @@ static int usb_stor_acquire_resources(struct us_data *us)
 		return -ENOMEM;
 	}
 
-	/* Just before we start our control thread, initialize
-	 * the device if it needs initialization */
+	/*
+	 * Just before we start our control thread, initialize
+	 * the device if it needs initialization
+	 */
 	if (us->unusual_dev->initFunction) {
 		p = us->unusual_dev->initFunction(us);
 		if (p)
@@ -805,7 +824,8 @@ static int usb_stor_acquire_resources(struct us_data *us)
 /* Release all our dynamic resources */
 static void usb_stor_release_resources(struct us_data *us)
 {
-	/* Tell the control thread to exit.  The SCSI host must
+	/*
+	 * Tell the control thread to exit.  The SCSI host must
 	 * already have been removed and the DISCONNECTING flag set
 	 * so that we won't accept any more commands.
 	 */
@@ -836,7 +856,8 @@ static void dissociate_dev(struct us_data *us)
 	usb_set_intfdata(us->pusb_intf, NULL);
 }
 
-/* First stage of disconnect processing: stop SCSI scanning,
+/*
+ * First stage of disconnect processing: stop SCSI scanning,
  * remove the host, and stop accepting new commands
  */
 static void quiesce_and_remove_host(struct us_data *us)
@@ -849,7 +870,8 @@ static void quiesce_and_remove_host(struct us_data *us)
 		wake_up(&us->delay_wait);
 	}
 
-	/* Prevent SCSI scanning (if it hasn't started yet)
+	/*
+	 * Prevent SCSI scanning (if it hasn't started yet)
 	 * or wait for the SCSI-scanning routine to stop.
 	 */
 	cancel_delayed_work_sync(&us->scan_dwork);
@@ -858,12 +880,14 @@ static void quiesce_and_remove_host(struct us_data *us)
 	if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags))
 		usb_autopm_put_interface_no_suspend(us->pusb_intf);
 
-	/* Removing the host will perform an orderly shutdown: caches
+	/*
+	 * Removing the host will perform an orderly shutdown: caches
 	 * synchronized, disks spun down, etc.
 	 */
 	scsi_remove_host(host);
 
-	/* Prevent any new commands from being accepted and cut short
+	/*
+	 * Prevent any new commands from being accepted and cut short
 	 * reset delays.
 	 */
 	scsi_lock(host);
@@ -878,8 +902,10 @@ static void release_everything(struct us_data *us)
 	usb_stor_release_resources(us);
 	dissociate_dev(us);
 
-	/* Drop our reference to the host; the SCSI core will free it
-	 * (and "us" along with it) when the refcount becomes 0. */
+	/*
+	 * Drop our reference to the host; the SCSI core will free it
+	 * (and "us" along with it) when the refcount becomes 0.
+	 */
 	scsi_host_put(us_to_host(us));
 }
 
@@ -900,7 +926,8 @@ static void usb_stor_scan_dwork(struct work_struct *work)
 		us->max_lun = usb_stor_Bulk_max_lun(us);
 		/*
 		 * Allow proper scanning of devices that present more than 8 LUNs
-		 * While not affecting other devices that may need the previous behavior
+		 * While not affecting other devices that may need the previous
+		 * behavior
 		 */
 		if (us->max_lun >= 8)
 			us_to_host(us)->max_lun = us->max_lun+1;
@@ -975,7 +1002,8 @@ int usb_stor_probe1(struct us_data **pus,
 	get_transport(us);
 	get_protocol(us);
 
-	/* Give the caller a chance to fill in specialized transport
+	/*
+	 * Give the caller a chance to fill in specialized transport
 	 * or protocol settings.
 	 */
 	return 0;
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index da0ad3241728..8fae28b40bb4 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage compliant devices
+/*
+ * Driver for USB Mass Storage compliant devices
  * Main Header File
  *
  * Current development and maintenance by:
@@ -100,7 +101,8 @@ typedef void (*pm_hook)(struct us_data *, int);	/* power management hook */
 
 /* we allocate one of these for every device that we remember */
 struct us_data {
-	/* The device we're working with
+	/*
+	 * The device we're working with
 	 * It's important to note:
 	 *    (o) you must hold dev_mutex to change pusb_dev
 	 */
@@ -125,7 +127,7 @@ struct us_data {
 	u8			max_lun;
 
 	u8			ifnum;		 /* interface number   */
-	u8			ep_bInterval;	 /* interrupt interval */ 
+	u8			ep_bInterval;	 /* interrupt interval */
 
 	/* function pointers for this device */
 	trans_cmnd		transport;	 /* transport function	   */
@@ -175,8 +177,10 @@ static inline struct us_data *host_to_us(struct Scsi_Host *host) {
 extern void fill_inquiry_response(struct us_data *us,
 	unsigned char *data, unsigned int data_len);
 
-/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the
- * single queue element srb for write access */
+/*
+ * The scsi_lock() and scsi_unlock() macros protect the sm_state and the
+ * single queue element srb for write access
+ */
 #define scsi_unlock(host)	spin_unlock_irq(host->host_lock)
 #define scsi_lock(host)		spin_lock_irq(host->host_lock)
 
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c
index 5ef8ce74aae4..499669bcf700 100644
--- a/drivers/usb/storage/usual-tables.c
+++ b/drivers/usb/storage/usual-tables.c
@@ -1,4 +1,5 @@
-/* Driver for USB Mass Storage devices
+/*
+ * Driver for USB Mass Storage devices
  * Usual Tables File for usb-storage and libusual
  *
  * Copyright (C) 2009 Alan Stern (stern@rowland.harvard.edu)
diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig
index bd99e9e47e50..17646b25343f 100644
--- a/drivers/usb/usbip/Kconfig
+++ b/drivers/usb/usbip/Kconfig
@@ -1,6 +1,6 @@
 config USBIP_CORE
 	tristate "USB/IP support"
-	depends on USB && NET
+	depends on USB_COMMON && NET
 	---help---
 	  This enables pushing USB packets over IP to allow remote
 	  machines direct access to USB devices. It provides the
@@ -16,7 +16,7 @@ config USBIP_CORE
 
 config USBIP_VHCI_HCD
 	tristate "VHCI hcd"
-	depends on USBIP_CORE
+	depends on USBIP_CORE && USB
 	---help---
 	  This enables the USB/IP virtual host controller driver,
 	  which is run on the remote machine.
@@ -26,7 +26,7 @@ config USBIP_VHCI_HCD
 
 config USBIP_HOST
 	tristate "Host driver"
-	depends on USBIP_CORE
+	depends on USBIP_CORE && USB
 	---help---
 	  This enables the USB/IP host driver, which is run on the
 	  machine that is sharing the USB devices.
@@ -34,6 +34,17 @@ config USBIP_HOST
 	  To compile this driver as a module, choose M here: the
 	  module will be called usbip-host.
 
+config USBIP_VUDC
+	tristate "VUDC driver"
+	depends on USBIP_CORE && USB_GADGET
+	---help---
+	  This enables the USB/IP virtual USB device controller
+	  driver, which is run on the host machine, allowing the
+	  machine itself to act as a device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called usbip-vudc.
+
 config USBIP_DEBUG
 	bool "Debug messages for USB/IP"
 	depends on USBIP_CORE
diff --git a/drivers/usb/usbip/Makefile b/drivers/usb/usbip/Makefile
index 9ecd61545be1..d843a9e68852 100644
--- a/drivers/usb/usbip/Makefile
+++ b/drivers/usb/usbip/Makefile
@@ -8,3 +8,6 @@ vhci-hcd-y := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
 
 obj-$(CONFIG_USBIP_HOST) += usbip-host.o
 usbip-host-y := stub_dev.o stub_main.o stub_rx.o stub_tx.o
+
+obj-$(CONFIG_USBIP_VUDC) += usbip-vudc.o
+usbip-vudc-y := vudc_dev.o vudc_sysfs.o vudc_tx.o vudc_rx.o vudc_transfer.o vudc_main.o
diff --git a/drivers/usb/usbip/stub.h b/drivers/usb/usbip/stub.h
index 266e2b0ce9a8..910f027773aa 100644
--- a/drivers/usb/usbip/stub.h
+++ b/drivers/usb/usbip/stub.h
@@ -33,7 +33,6 @@
 #define STUB_BUSID_ALLOC 3
 
 struct stub_device {
-	struct usb_interface *interface;
 	struct usb_device *udev;
 
 	struct usbip_device ud;
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c
index a3ec49bdc1e6..c653ce533430 100644
--- a/drivers/usb/usbip/stub_dev.c
+++ b/drivers/usb/usbip/stub_dev.c
@@ -219,7 +219,7 @@ static void stub_device_reset(struct usbip_device *ud)
 
 	dev_dbg(&udev->dev, "device reset");
 
-	ret = usb_lock_device_for_reset(udev, sdev->interface);
+	ret = usb_lock_device_for_reset(udev, NULL);
 	if (ret < 0) {
 		dev_err(&udev->dev, "lock for reset\n");
 		spin_lock_irq(&ud->lock);
@@ -252,7 +252,7 @@ static void stub_device_unusable(struct usbip_device *ud)
 
 /**
  * stub_device_alloc - allocate a new stub_device struct
- * @interface: usb_interface of a new device
+ * @udev: usb_device of a new device
  *
  * Allocates and initializes a new stub_device struct.
  */
@@ -388,7 +388,6 @@ err_files:
 err_port:
 	dev_set_drvdata(&udev->dev, NULL);
 	usb_put_dev(udev);
-	kthread_stop_put(sdev->ud.eh);
 
 	busid_priv->sdev = NULL;
 	stub_device_free(sdev);
@@ -449,7 +448,7 @@ static void stub_disconnect(struct usb_device *udev)
 	}
 
 	/* If usb reset is called from event handler */
-	if (busid_priv->sdev->ud.eh == current)
+	if (usbip_in_eh(current))
 		return;
 
 	/* shutdown the current connection */
diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c
index 00e475c51a12..2df63e305722 100644
--- a/drivers/usb/usbip/stub_rx.c
+++ b/drivers/usb/usbip/stub_rx.c
@@ -165,12 +165,7 @@ static int tweak_reset_device_cmd(struct urb *urb)
 
 	dev_info(&urb->dev->dev, "usb_queue_reset_device\n");
 
-	/*
-	 * With the implementation of pre_reset and post_reset the driver no
-	 * longer unbinds. This allows the use of synchronous reset.
-	 */
-
-	if (usb_lock_device_for_reset(sdev->udev, sdev->interface) < 0) {
+	if (usb_lock_device_for_reset(sdev->udev, NULL) < 0) {
 		dev_err(&urb->dev->dev, "could not obtain lock to reset device\n");
 		return 0;
 	}
@@ -321,7 +316,7 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
 
 	priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC);
 	if (!priv) {
-		dev_err(&sdev->interface->dev, "alloc stub_priv\n");
+		dev_err(&sdev->udev->dev, "alloc stub_priv\n");
 		spin_unlock_irqrestore(&sdev->priv_lock, flags);
 		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
 		return NULL;
@@ -352,7 +347,7 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir)
 	else
 		ep = udev->ep_out[epnum & 0x7f];
 	if (!ep) {
-		dev_err(&sdev->interface->dev, "no such endpoint?, %d\n",
+		dev_err(&sdev->udev->dev, "no such endpoint?, %d\n",
 			epnum);
 		BUG();
 	}
@@ -387,7 +382,7 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir)
 	}
 
 	/* NOT REACHED */
-	dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum);
+	dev_err(&sdev->udev->dev, "get pipe, epnum %d\n", epnum);
 	return 0;
 }
 
@@ -466,7 +461,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 		priv->urb = usb_alloc_urb(0, GFP_KERNEL);
 
 	if (!priv->urb) {
-		dev_err(&sdev->interface->dev, "malloc urb\n");
+		dev_err(&udev->dev, "malloc urb\n");
 		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
 		return;
 	}
@@ -486,7 +481,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 	priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8,
 					  GFP_KERNEL);
 	if (!priv->urb->setup_packet) {
-		dev_err(&sdev->interface->dev, "allocate setup_packet\n");
+		dev_err(&udev->dev, "allocate setup_packet\n");
 		usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
 		return;
 	}
@@ -517,7 +512,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 		usbip_dbg_stub_rx("submit urb ok, seqnum %u\n",
 				  pdu->base.seqnum);
 	else {
-		dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret);
+		dev_err(&udev->dev, "submit_urb error, %d\n", ret);
 		usbip_dump_header(pdu);
 		usbip_dump_urb(priv->urb);
 
diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c
index dbcabc9dbe0d..6b1e8c3f0e4b 100644
--- a/drivers/usb/usbip/stub_tx.c
+++ b/drivers/usb/usbip/stub_tx.c
@@ -97,7 +97,10 @@ void stub_complete(struct urb *urb)
 
 	/* link a urb to the queue of tx. */
 	spin_lock_irqsave(&sdev->priv_lock, flags);
-	if (priv->unlinking) {
+	if (sdev->ud.tcp_socket == NULL) {
+		usbip_dbg_stub_tx("ignore urb for closed connection %p", urb);
+		/* It will be freed in stub_device_cleanup_urbs(). */
+	} else if (priv->unlinking) {
 		stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
 		stub_free_priv_and_urb(priv);
 	} else {
@@ -229,7 +232,7 @@ static int stub_send_ret_submit(struct stub_device *sdev)
 			}
 
 			if (txsize != sizeof(pdu_header) + urb->actual_length) {
-				dev_err(&sdev->interface->dev,
+				dev_err(&sdev->udev->dev,
 					"actual length of urb %d does not match iso packet sizes %zu\n",
 					urb->actual_length,
 					txsize-sizeof(pdu_header));
@@ -261,7 +264,7 @@ static int stub_send_ret_submit(struct stub_device *sdev)
 		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg,
 						iov,  iovnum, txsize);
 		if (ret != txsize) {
-			dev_err(&sdev->interface->dev,
+			dev_err(&sdev->udev->dev,
 				"sendmsg failed!, retval %d for %zd\n",
 				ret, txsize);
 			kfree(iov);
@@ -336,7 +339,7 @@ static int stub_send_ret_unlink(struct stub_device *sdev)
 		ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
 				     1, txsize);
 		if (ret != txsize) {
-			dev_err(&sdev->interface->dev,
+			dev_err(&sdev->udev->dev,
 				"sendmsg failed!, retval %d for %zd\n",
 				ret, txsize);
 			usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
index e40da7759a0e..8b232290be6b 100644
--- a/drivers/usb/usbip/usbip_common.c
+++ b/drivers/usb/usbip/usbip_common.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -643,7 +645,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
 			ret);
 		kfree(buff);
 
-		if (ud->side == USBIP_STUB)
+		if (ud->side == USBIP_STUB || ud->side == USBIP_VUDC)
 			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
 		else
 			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
@@ -665,7 +667,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
 			"total length of iso packets %d not equal to actual length of buffer %d\n",
 			total_length, urb->actual_length);
 
-		if (ud->side == USBIP_STUB)
+		if (ud->side == USBIP_STUB || ud->side == USBIP_VUDC)
 			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
 		else
 			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
@@ -723,7 +725,7 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
 	int ret;
 	int size;
 
-	if (ud->side == USBIP_STUB) {
+	if (ud->side == USBIP_STUB || ud->side == USBIP_VUDC) {
 		/* the direction of urb must be OUT. */
 		if (usb_pipein(urb->pipe))
 			return 0;
@@ -755,7 +757,7 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
 	ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size);
 	if (ret != size) {
 		dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
-		if (ud->side == USBIP_STUB) {
+		if (ud->side == USBIP_STUB || ud->side == USBIP_VUDC) {
 			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
 		} else {
 			usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
@@ -769,12 +771,19 @@ EXPORT_SYMBOL_GPL(usbip_recv_xbuff);
 
 static int __init usbip_core_init(void)
 {
+	int ret;
+
 	pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
+	ret = usbip_init_eh();
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
 static void __exit usbip_core_exit(void)
 {
+	usbip_finish_eh();
 	return;
 }
 
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index 86b08475c254..c7508cbce3ce 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -1,5 +1,7 @@
 /*
  * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -234,6 +236,7 @@ struct usbip_iso_packet_descriptor {
 enum usbip_side {
 	USBIP_VHCI,
 	USBIP_STUB,
+	USBIP_VUDC,
 };
 
 /* event handler */
@@ -248,6 +251,13 @@ enum usbip_side {
 #define	SDEV_EVENT_ERROR_SUBMIT	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	SDEV_EVENT_ERROR_MALLOC	(USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 
+#define VUDC_EVENT_REMOVED   (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
+#define	VUDC_EVENT_DOWN		(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+#define	VUDC_EVENT_ERROR_TCP	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+/* catastrophic emulated usb error */
+#define	VUDC_EVENT_ERROR_USB	(USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
+#define	VUDC_EVENT_ERROR_MALLOC	(USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
+
 #define	VDEV_EVENT_REMOVED	(USBIP_EH_SHUTDOWN | USBIP_EH_BYE)
 #define	VDEV_EVENT_DOWN		(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	VDEV_EVENT_ERROR_TCP	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
@@ -267,7 +277,6 @@ struct usbip_device {
 	struct task_struct *tcp_tx;
 
 	unsigned long event;
-	struct task_struct *eh;
 	wait_queue_head_t eh_waitq;
 
 	struct eh_ops {
@@ -313,10 +322,13 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
 int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
 
 /* usbip_event.c */
+int usbip_init_eh(void);
+void usbip_finish_eh(void);
 int usbip_start_eh(struct usbip_device *ud);
 void usbip_stop_eh(struct usbip_device *ud);
 void usbip_event_add(struct usbip_device *ud, unsigned long event);
 int usbip_event_happened(struct usbip_device *ud);
+int usbip_in_eh(struct task_struct *task);
 
 static inline int interface_to_busnum(struct usb_interface *interface)
 {
diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c
index 2580a32bcdff..f1635662c299 100644
--- a/drivers/usb/usbip/usbip_event.c
+++ b/drivers/usb/usbip/usbip_event.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ * Copyright (C) 2015 Nobuo Iwata
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,17 +20,68 @@
 
 #include <linux/kthread.h>
 #include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
 
 #include "usbip_common.h"
 
-static int event_handler(struct usbip_device *ud)
+struct usbip_event {
+	struct list_head node;
+	struct usbip_device *ud;
+};
+
+static DEFINE_SPINLOCK(event_lock);
+static LIST_HEAD(event_list);
+
+static void set_event(struct usbip_device *ud, unsigned long event)
 {
-	usbip_dbg_eh("enter\n");
+	unsigned long flags;
 
-	/*
-	 * Events are handled by only this thread.
-	 */
-	while (usbip_event_happened(ud)) {
+	spin_lock_irqsave(&ud->lock, flags);
+	ud->event |= event;
+	spin_unlock_irqrestore(&ud->lock, flags);
+}
+
+static void unset_event(struct usbip_device *ud, unsigned long event)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ud->lock, flags);
+	ud->event &= ~event;
+	spin_unlock_irqrestore(&ud->lock, flags);
+}
+
+static struct usbip_device *get_event(void)
+{
+	struct usbip_event *ue = NULL;
+	struct usbip_device *ud = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&event_lock, flags);
+	if (!list_empty(&event_list)) {
+		ue = list_first_entry(&event_list, struct usbip_event, node);
+		list_del(&ue->node);
+	}
+	spin_unlock_irqrestore(&event_lock, flags);
+
+	if (ue) {
+		ud = ue->ud;
+		kfree(ue);
+	}
+	return ud;
+}
+
+static struct task_struct *worker_context;
+
+static void event_handler(struct work_struct *work)
+{
+	struct usbip_device *ud;
+
+	if (worker_context == NULL) {
+		worker_context = current;
+	}
+
+	while ((ud = get_event()) != NULL) {
 		usbip_dbg_eh("pending event %lx\n", ud->event);
 
 		/*
@@ -38,79 +90,102 @@ static int event_handler(struct usbip_device *ud)
 		 */
 		if (ud->event & USBIP_EH_SHUTDOWN) {
 			ud->eh_ops.shutdown(ud);
-			ud->event &= ~USBIP_EH_SHUTDOWN;
+			unset_event(ud, USBIP_EH_SHUTDOWN);
 		}
 
 		/* Reset the device. */
 		if (ud->event & USBIP_EH_RESET) {
 			ud->eh_ops.reset(ud);
-			ud->event &= ~USBIP_EH_RESET;
+			unset_event(ud, USBIP_EH_RESET);
 		}
 
 		/* Mark the device as unusable. */
 		if (ud->event & USBIP_EH_UNUSABLE) {
 			ud->eh_ops.unusable(ud);
-			ud->event &= ~USBIP_EH_UNUSABLE;
+			unset_event(ud, USBIP_EH_UNUSABLE);
 		}
 
 		/* Stop the error handler. */
 		if (ud->event & USBIP_EH_BYE)
-			return -1;
+			usbip_dbg_eh("removed %p\n", ud);
+
+		wake_up(&ud->eh_waitq);
 	}
+}
 
+int usbip_start_eh(struct usbip_device *ud)
+{
+	init_waitqueue_head(&ud->eh_waitq);
+	ud->event = 0;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(usbip_start_eh);
 
-static int event_handler_loop(void *data)
+void usbip_stop_eh(struct usbip_device *ud)
 {
-	struct usbip_device *ud = data;
+	unsigned long pending = ud->event & ~USBIP_EH_BYE;
 
-	while (!kthread_should_stop()) {
-		wait_event_interruptible(ud->eh_waitq,
-					 usbip_event_happened(ud) ||
-					 kthread_should_stop());
-		usbip_dbg_eh("wakeup\n");
+	if (!(ud->event & USBIP_EH_BYE))
+		usbip_dbg_eh("usbip_eh stopping but not removed\n");
 
-		if (event_handler(ud) < 0)
-			break;
-	}
+	if (pending)
+		usbip_dbg_eh("usbip_eh waiting completion %lx\n", pending);
 
-	return 0;
+	wait_event_interruptible(ud->eh_waitq, !(ud->event & ~USBIP_EH_BYE));
+	usbip_dbg_eh("usbip_eh has stopped\n");
 }
+EXPORT_SYMBOL_GPL(usbip_stop_eh);
 
-int usbip_start_eh(struct usbip_device *ud)
-{
-	init_waitqueue_head(&ud->eh_waitq);
-	ud->event = 0;
+#define WORK_QUEUE_NAME "usbip_event"
 
-	ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh");
-	if (IS_ERR(ud->eh)) {
-		pr_warn("Unable to start control thread\n");
-		return PTR_ERR(ud->eh);
-	}
+static struct workqueue_struct *usbip_queue;
+static DECLARE_WORK(usbip_work, event_handler);
 
+int usbip_init_eh(void)
+{
+	usbip_queue = create_singlethread_workqueue(WORK_QUEUE_NAME);
+	if (usbip_queue == NULL) {
+		pr_err("failed to create usbip_event\n");
+		return -ENOMEM;
+	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(usbip_start_eh);
 
-void usbip_stop_eh(struct usbip_device *ud)
+void usbip_finish_eh(void)
 {
-	if (ud->eh == current)
-		return; /* do not wait for myself */
-
-	kthread_stop(ud->eh);
-	usbip_dbg_eh("usbip_eh has finished\n");
+	flush_workqueue(usbip_queue);
+	destroy_workqueue(usbip_queue);
+	usbip_queue = NULL;
 }
-EXPORT_SYMBOL_GPL(usbip_stop_eh);
 
 void usbip_event_add(struct usbip_device *ud, unsigned long event)
 {
+	struct usbip_event *ue;
 	unsigned long flags;
 
-	spin_lock_irqsave(&ud->lock, flags);
-	ud->event |= event;
-	wake_up(&ud->eh_waitq);
-	spin_unlock_irqrestore(&ud->lock, flags);
+	if (ud->event & USBIP_EH_BYE)
+		return;
+
+	set_event(ud, event);
+
+	spin_lock_irqsave(&event_lock, flags);
+
+	list_for_each_entry_reverse(ue, &event_list, node) {
+		if (ue->ud == ud)
+			goto out;
+	}
+
+	ue = kmalloc(sizeof(struct usbip_event), GFP_ATOMIC);
+	if (ue == NULL)
+		goto out;
+
+	ue->ud = ud;
+
+	list_add_tail(&ue->node, &event_list);
+	queue_work(usbip_queue, &usbip_work);
+
+out:
+	spin_unlock_irqrestore(&event_lock, flags);
 }
 EXPORT_SYMBOL_GPL(usbip_event_add);
 
@@ -127,3 +202,12 @@ int usbip_event_happened(struct usbip_device *ud)
 	return happened;
 }
 EXPORT_SYMBOL_GPL(usbip_event_happened);
+
+int usbip_in_eh(struct task_struct *task)
+{
+	if (task == worker_context)
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(usbip_in_eh);
diff --git a/drivers/usb/usbip/vudc.h b/drivers/usb/usbip/vudc.h
new file mode 100644
index 000000000000..25e01b09c4c3
--- /dev/null
+++ b/drivers/usb/usbip/vudc.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __USBIP_VUDC_H
+#define __USBIP_VUDC_H
+
+#include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/ch9.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/time.h>
+#include <linux/sysfs.h>
+
+#include "usbip_common.h"
+
+#define GADGET_NAME "usbip-vudc"
+
+struct vep {
+	struct usb_ep ep;
+	unsigned type:2; /* type, as USB_ENDPOINT_XFER_* */
+	char name[8];	/* space for ep name */
+
+	const struct usb_endpoint_descriptor *desc;
+	struct usb_gadget *gadget;
+	struct list_head req_queue; /* Request queue */
+	unsigned halted:1;
+	unsigned wedged:1;
+	unsigned already_seen:1;
+	unsigned setup_stage:1;
+};
+
+struct vrequest {
+	struct usb_request req;
+	struct vudc *udc;
+	struct list_head req_entry; /* Request queue */
+};
+
+struct urbp {
+	struct urb *urb;
+	struct vep *ep;
+	struct list_head urb_entry; /* urb queue */
+	unsigned long seqnum;
+	unsigned type:2; /* for tx, since ep type can change after */
+	unsigned new:1;
+};
+
+struct v_unlink {
+	unsigned long seqnum;
+	__u32 status;
+};
+
+enum tx_type {
+	TX_UNLINK,
+	TX_SUBMIT,
+};
+
+struct tx_item {
+	struct list_head tx_entry;
+	enum tx_type type;
+	union {
+		struct urbp *s;
+		struct v_unlink *u;
+	};
+};
+
+enum tr_state {
+	VUDC_TR_RUNNING,
+	VUDC_TR_IDLE,
+	VUDC_TR_STOPPED,
+};
+
+struct transfer_timer {
+	struct timer_list timer;
+	enum tr_state state;
+	unsigned long frame_start;
+	int frame_limit;
+};
+
+struct vudc {
+	struct usb_gadget gadget;
+	struct usb_gadget_driver *driver;
+	struct platform_device *pdev;
+
+	struct usb_device_descriptor dev_desc;
+
+	struct usbip_device ud;
+	struct transfer_timer tr_timer;
+	struct timeval start_time;
+
+	struct list_head urb_queue;
+
+	spinlock_t lock_tx;
+	struct list_head tx_queue;
+	wait_queue_head_t tx_waitq;
+
+	spinlock_t lock;
+	struct vep *ep;
+	int address;
+	u16 devstatus;
+
+	unsigned pullup:1;
+	unsigned connected:1;
+	unsigned desc_cached:1;
+};
+
+struct vudc_device {
+	struct platform_device *pdev;
+	struct list_head dev_entry;
+};
+
+extern const struct attribute_group vudc_attr_group;
+
+/* visible everywhere */
+
+static inline struct vep *to_vep(struct usb_ep *_ep)
+{
+	return container_of(_ep, struct vep, ep);
+}
+
+static inline struct vrequest *to_vrequest(
+	struct usb_request *_req)
+{
+	return container_of(_req, struct vrequest, req);
+}
+
+static inline struct vudc *usb_gadget_to_vudc(
+	struct usb_gadget *_gadget)
+{
+	return container_of(_gadget, struct vudc, gadget);
+}
+
+static inline struct vudc *ep_to_vudc(struct vep *ep)
+{
+	return container_of(ep->gadget, struct vudc, gadget);
+}
+
+/* vudc_sysfs.c */
+
+int get_gadget_descs(struct vudc *udc);
+
+/* vudc_tx.c */
+
+int v_tx_loop(void *data);
+void v_enqueue_ret_unlink(struct vudc *udc, __u32 seqnum, __u32 status);
+void v_enqueue_ret_submit(struct vudc *udc, struct urbp *urb_p);
+
+/* vudc_rx.c */
+
+int v_rx_loop(void *data);
+
+/* vudc_transfer.c */
+
+void v_init_timer(struct vudc *udc);
+void v_start_timer(struct vudc *udc);
+void v_kick_timer(struct vudc *udc, unsigned long time);
+void v_stop_timer(struct vudc *udc);
+
+/* vudc_dev.c */
+
+struct urbp *alloc_urbp(void);
+void free_urbp_and_urb(struct urbp *urb_p);
+
+struct vep *vudc_find_endpoint(struct vudc *udc, u8 address);
+
+struct vudc_device *alloc_vudc_device(int devid);
+void put_vudc_device(struct vudc_device *udc_dev);
+
+int vudc_probe(struct platform_device *pdev);
+int vudc_remove(struct platform_device *pdev);
+
+#endif /* __USBIP_VUDC_H */
diff --git a/drivers/usb/usbip/vudc_dev.c b/drivers/usb/usbip/vudc_dev.c
new file mode 100644
index 000000000000..8994a13819ab
--- /dev/null
+++ b/drivers/usb/usbip/vudc_dev.c
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/hcd.h>
+#include <linux/kthread.h>
+#include <linux/file.h>
+#include <linux/byteorder/generic.h>
+
+#include "usbip_common.h"
+#include "vudc.h"
+
+#define VIRTUAL_ENDPOINTS (1 /* ep0 */ + 15 /* in eps */ + 15 /* out eps */)
+
+/* urb-related structures alloc / free */
+
+
+static void free_urb(struct urb *urb)
+{
+	if (!urb)
+		return;
+
+	kfree(urb->setup_packet);
+	urb->setup_packet = NULL;
+
+	kfree(urb->transfer_buffer);
+	urb->transfer_buffer = NULL;
+
+	usb_free_urb(urb);
+}
+
+struct urbp *alloc_urbp(void)
+{
+	struct urbp *urb_p;
+
+	urb_p = kzalloc(sizeof(*urb_p), GFP_KERNEL);
+	if (!urb_p)
+		return urb_p;
+
+	urb_p->urb = NULL;
+	urb_p->ep = NULL;
+	INIT_LIST_HEAD(&urb_p->urb_entry);
+	return urb_p;
+}
+
+static void free_urbp(struct urbp *urb_p)
+{
+	kfree(urb_p);
+}
+
+void free_urbp_and_urb(struct urbp *urb_p)
+{
+	if (!urb_p)
+		return;
+	free_urb(urb_p->urb);
+	free_urbp(urb_p);
+}
+
+
+/* utilities ; almost verbatim from dummy_hcd.c */
+
+/* called with spinlock held */
+static void nuke(struct vudc *udc, struct vep *ep)
+{
+	struct vrequest	*req;
+
+	while (!list_empty(&ep->req_queue)) {
+		req = list_first_entry(&ep->req_queue, struct vrequest,
+				       req_entry);
+		list_del_init(&req->req_entry);
+		req->req.status = -ESHUTDOWN;
+
+		spin_unlock(&udc->lock);
+		usb_gadget_giveback_request(&ep->ep, &req->req);
+		spin_lock(&udc->lock);
+	}
+}
+
+/* caller must hold lock */
+static void stop_activity(struct vudc *udc)
+{
+	int i;
+	struct urbp *urb_p, *tmp;
+
+	udc->address = 0;
+
+	for (i = 0; i < VIRTUAL_ENDPOINTS; i++)
+		nuke(udc, &udc->ep[i]);
+
+	list_for_each_entry_safe(urb_p, tmp, &udc->urb_queue, urb_entry) {
+		list_del(&urb_p->urb_entry);
+		free_urbp_and_urb(urb_p);
+	}
+}
+
+struct vep *vudc_find_endpoint(struct vudc *udc, u8 address)
+{
+	int i;
+
+	if ((address & ~USB_DIR_IN) == 0)
+		return &udc->ep[0];
+
+	for (i = 1; i < VIRTUAL_ENDPOINTS; i++) {
+		struct vep *ep = &udc->ep[i];
+
+		if (!ep->desc)
+			continue;
+		if (ep->desc->bEndpointAddress == address)
+			return ep;
+	}
+	return NULL;
+}
+
+/* gadget ops */
+
+/* FIXME - this will probably misbehave when suspend/resume is added */
+static int vgadget_get_frame(struct usb_gadget *_gadget)
+{
+	struct timeval now;
+	struct vudc *udc = usb_gadget_to_vudc(_gadget);
+
+	do_gettimeofday(&now);
+	return ((now.tv_sec - udc->start_time.tv_sec) * 1000 +
+			(now.tv_usec - udc->start_time.tv_usec) / 1000)
+			% 0x7FF;
+}
+
+static int vgadget_set_selfpowered(struct usb_gadget *_gadget, int value)
+{
+	struct vudc *udc = usb_gadget_to_vudc(_gadget);
+
+	if (value)
+		udc->devstatus |= (1 << USB_DEVICE_SELF_POWERED);
+	else
+		udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED);
+	return 0;
+}
+
+static int vgadget_pullup(struct usb_gadget *_gadget, int value)
+{
+	struct vudc *udc = usb_gadget_to_vudc(_gadget);
+	unsigned long flags;
+	int ret;
+
+
+	spin_lock_irqsave(&udc->lock, flags);
+	value = !!value;
+	if (value == udc->pullup)
+		goto unlock;
+
+	udc->pullup = value;
+	if (value) {
+		udc->gadget.speed = min_t(u8, USB_SPEED_HIGH,
+					   udc->driver->max_speed);
+		udc->ep[0].ep.maxpacket = 64;
+		/*
+		 * This is the first place where we can ask our
+		 * gadget driver for descriptors.
+		 */
+		ret = get_gadget_descs(udc);
+		if (ret) {
+			dev_err(&udc->gadget.dev, "Unable go get desc: %d", ret);
+			goto unlock;
+		}
+
+		spin_unlock_irqrestore(&udc->lock, flags);
+		usbip_start_eh(&udc->ud);
+	} else {
+		/* Invalidate descriptors */
+		udc->desc_cached = 0;
+
+		spin_unlock_irqrestore(&udc->lock, flags);
+		usbip_event_add(&udc->ud, VUDC_EVENT_REMOVED);
+		usbip_stop_eh(&udc->ud); /* Wait for eh completion */
+	}
+
+	return 0;
+
+unlock:
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return 0;
+}
+
+static int vgadget_udc_start(struct usb_gadget *g,
+		struct usb_gadget_driver *driver)
+{
+	struct vudc *udc = usb_gadget_to_vudc(g);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->driver = driver;
+	udc->pullup = udc->connected = udc->desc_cached = 0;
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int vgadget_udc_stop(struct usb_gadget *g)
+{
+	struct vudc *udc = usb_gadget_to_vudc(g);
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	udc->driver = NULL;
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return 0;
+}
+
+static const struct usb_gadget_ops vgadget_ops = {
+	.get_frame	= vgadget_get_frame,
+	.set_selfpowered = vgadget_set_selfpowered,
+	.pullup		= vgadget_pullup,
+	.udc_start	= vgadget_udc_start,
+	.udc_stop	= vgadget_udc_stop,
+};
+
+
+/* endpoint ops */
+
+static int vep_enable(struct usb_ep *_ep,
+		const struct usb_endpoint_descriptor *desc)
+{
+	struct vep *ep;
+	struct vudc *udc;
+	unsigned maxp;
+	unsigned long flags;
+
+	ep = to_vep(_ep);
+	udc = ep_to_vudc(ep);
+
+	if (!_ep || !desc || ep->desc || _ep->caps.type_control
+			|| desc->bDescriptorType != USB_DT_ENDPOINT)
+		return -EINVAL;
+
+	if (!udc->driver)
+		return -ESHUTDOWN;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	maxp = usb_endpoint_maxp(desc) & 0x7ff;
+	_ep->maxpacket = maxp;
+	ep->desc = desc;
+	ep->type = usb_endpoint_type(desc);
+	ep->halted = ep->wedged = 0;
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int vep_disable(struct usb_ep *_ep)
+{
+	struct vep *ep;
+	struct vudc *udc;
+	unsigned long flags;
+
+	ep = to_vep(_ep);
+	udc = ep_to_vudc(ep);
+	if (!_ep || !ep->desc || _ep->caps.type_control)
+		return -EINVAL;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	ep->desc = NULL;
+	nuke(udc, ep);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static struct usb_request *vep_alloc_request(struct usb_ep *_ep,
+		gfp_t mem_flags)
+{
+	struct vep *ep;
+	struct vrequest *req;
+
+	if (!_ep)
+		return NULL;
+	ep = to_vep(_ep);
+
+	req = kzalloc(sizeof(*req), mem_flags);
+	if (!req)
+		return NULL;
+
+	INIT_LIST_HEAD(&req->req_entry);
+
+	return &req->req;
+}
+
+static void vep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct vrequest *req;
+
+	if (WARN_ON(!_ep || !_req))
+		return;
+
+	req = to_vrequest(_req);
+	kfree(req);
+}
+
+static int vep_queue(struct usb_ep *_ep, struct usb_request *_req,
+		gfp_t mem_flags)
+{
+	struct vep *ep;
+	struct vrequest *req;
+	struct vudc *udc;
+	unsigned long flags;
+
+	if (!_ep || !_req)
+		return -EINVAL;
+
+	ep = to_vep(_ep);
+	req = to_vrequest(_req);
+	udc = ep_to_vudc(ep);
+
+	spin_lock_irqsave(&udc->lock, flags);
+	_req->actual = 0;
+	_req->status = -EINPROGRESS;
+
+	list_add_tail(&req->req_entry, &ep->req_queue);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int vep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct vep *ep;
+	struct vrequest *req;
+	struct vudc *udc;
+	struct vrequest *lst;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	if (!_ep || !_req)
+		return ret;
+
+	ep = to_vep(_ep);
+	req = to_vrequest(_req);
+	udc = req->udc;
+
+	if (!udc->driver)
+		return -ESHUTDOWN;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	list_for_each_entry(lst, &ep->req_queue, req_entry) {
+		if (&lst->req == _req) {
+			list_del_init(&lst->req_entry);
+			_req->status = -ECONNRESET;
+			ret = 0;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	if (ret == 0)
+		usb_gadget_giveback_request(_ep, _req);
+
+	return ret;
+}
+
+static int
+vep_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
+{
+	struct vep *ep;
+	struct vudc *udc;
+	unsigned long flags;
+	int ret = 0;
+
+	ep = to_vep(_ep);
+	if (!_ep)
+		return -EINVAL;
+
+	udc = ep_to_vudc(ep);
+	if (!udc->driver)
+		return -ESHUTDOWN;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (!value)
+		ep->halted = ep->wedged = 0;
+	else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
+			!list_empty(&ep->req_queue))
+		ret = -EAGAIN;
+	else {
+		ep->halted = 1;
+		if (wedged)
+			ep->wedged = 1;
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return ret;
+}
+
+static int
+vep_set_halt(struct usb_ep *_ep, int value)
+{
+	return vep_set_halt_and_wedge(_ep, value, 0);
+}
+
+static int vep_set_wedge(struct usb_ep *_ep)
+{
+	return vep_set_halt_and_wedge(_ep, 1, 1);
+}
+
+static const struct usb_ep_ops vep_ops = {
+	.enable		= vep_enable,
+	.disable	= vep_disable,
+
+	.alloc_request	= vep_alloc_request,
+	.free_request	= vep_free_request,
+
+	.queue		= vep_queue,
+	.dequeue	= vep_dequeue,
+
+	.set_halt	= vep_set_halt,
+	.set_wedge	= vep_set_wedge,
+};
+
+
+/* shutdown / reset / error handlers */
+
+static void vudc_shutdown(struct usbip_device *ud)
+{
+	struct vudc *udc = container_of(ud, struct vudc, ud);
+	int call_disconnect = 0;
+	unsigned long flags;
+
+	dev_dbg(&udc->pdev->dev, "device shutdown");
+	if (ud->tcp_socket)
+		kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
+
+	if (ud->tcp_tx) {
+		kthread_stop_put(ud->tcp_rx);
+		ud->tcp_rx = NULL;
+	}
+	if (ud->tcp_tx) {
+		kthread_stop_put(ud->tcp_tx);
+		ud->tcp_tx = NULL;
+	}
+
+	if (ud->tcp_socket) {
+		sockfd_put(ud->tcp_socket);
+		ud->tcp_socket = NULL;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	stop_activity(udc);
+	if (udc->connected && udc->driver->disconnect)
+		call_disconnect = 1;
+	udc->connected = 0;
+	spin_unlock_irqrestore(&udc->lock, flags);
+	if (call_disconnect)
+		udc->driver->disconnect(&udc->gadget);
+}
+
+static void vudc_device_reset(struct usbip_device *ud)
+{
+	struct vudc *udc = container_of(ud, struct vudc, ud);
+	unsigned long flags;
+
+	dev_dbg(&udc->pdev->dev, "device reset");
+	spin_lock_irqsave(&udc->lock, flags);
+	stop_activity(udc);
+	spin_unlock_irqrestore(&udc->lock, flags);
+	if (udc->driver)
+		usb_gadget_udc_reset(&udc->gadget, udc->driver);
+	spin_lock_irqsave(&ud->lock, flags);
+	ud->status = SDEV_ST_AVAILABLE;
+	spin_unlock_irqrestore(&ud->lock, flags);
+}
+
+static void vudc_device_unusable(struct usbip_device *ud)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ud->lock, flags);
+	ud->status = SDEV_ST_ERROR;
+	spin_unlock_irqrestore(&ud->lock, flags);
+}
+
+/* device setup / cleanup */
+
+struct vudc_device *alloc_vudc_device(int devid)
+{
+	struct vudc_device *udc_dev = NULL;
+
+	udc_dev = kzalloc(sizeof(*udc_dev), GFP_KERNEL);
+	if (!udc_dev)
+		goto out;
+
+	INIT_LIST_HEAD(&udc_dev->dev_entry);
+
+	udc_dev->pdev = platform_device_alloc(GADGET_NAME, devid);
+	if (!udc_dev->pdev) {
+		kfree(udc_dev);
+		udc_dev = NULL;
+	}
+
+out:
+	return udc_dev;
+}
+
+void put_vudc_device(struct vudc_device *udc_dev)
+{
+	platform_device_put(udc_dev->pdev);
+	kfree(udc_dev);
+}
+
+static int init_vudc_hw(struct vudc *udc)
+{
+	int i;
+	struct usbip_device *ud = &udc->ud;
+	struct vep *ep;
+
+	udc->ep = kcalloc(VIRTUAL_ENDPOINTS, sizeof(*udc->ep), GFP_KERNEL);
+	if (!udc->ep)
+		goto nomem_ep;
+
+	INIT_LIST_HEAD(&udc->gadget.ep_list);
+
+	/* create ep0 and 15 in, 15 out general purpose eps */
+	for (i = 0; i < VIRTUAL_ENDPOINTS; ++i) {
+		int is_out = i % 2;
+		int num = (i + 1) / 2;
+
+		ep = &udc->ep[i];
+
+		sprintf(ep->name, "ep%d%s", num,
+			i ? (is_out ? "out" : "in") : "");
+		ep->ep.name = ep->name;
+		if (i == 0) {
+			ep->ep.caps.type_control = true;
+			ep->ep.caps.dir_out = true;
+			ep->ep.caps.dir_in = true;
+		} else {
+			ep->ep.caps.type_iso = true;
+			ep->ep.caps.type_int = true;
+			ep->ep.caps.type_bulk = true;
+		}
+
+		if (is_out)
+			ep->ep.caps.dir_out = true;
+		else
+			ep->ep.caps.dir_in = true;
+
+		ep->ep.ops = &vep_ops;
+		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+		ep->halted = ep->wedged = ep->already_seen =
+			ep->setup_stage = 0;
+		usb_ep_set_maxpacket_limit(&ep->ep, ~0);
+		ep->ep.max_streams = 16;
+		ep->gadget = &udc->gadget;
+		ep->desc = NULL;
+		INIT_LIST_HEAD(&ep->req_queue);
+	}
+
+	spin_lock_init(&udc->lock);
+	spin_lock_init(&udc->lock_tx);
+	INIT_LIST_HEAD(&udc->urb_queue);
+	INIT_LIST_HEAD(&udc->tx_queue);
+	init_waitqueue_head(&udc->tx_waitq);
+
+	spin_lock_init(&ud->lock);
+	ud->status = SDEV_ST_AVAILABLE;
+	ud->side = USBIP_VUDC;
+
+	ud->eh_ops.shutdown = vudc_shutdown;
+	ud->eh_ops.reset    = vudc_device_reset;
+	ud->eh_ops.unusable = vudc_device_unusable;
+
+	udc->gadget.ep0 = &udc->ep[0].ep;
+	list_del_init(&udc->ep[0].ep.ep_list);
+
+	v_init_timer(udc);
+	return 0;
+
+nomem_ep:
+		return -ENOMEM;
+}
+
+static void cleanup_vudc_hw(struct vudc *udc)
+{
+	kfree(udc->ep);
+}
+
+/* platform driver ops */
+
+int vudc_probe(struct platform_device *pdev)
+{
+	struct vudc *udc;
+	int ret = -ENOMEM;
+
+	udc = kzalloc(sizeof(*udc), GFP_KERNEL);
+	if (!udc)
+		goto out;
+
+	udc->gadget.name = GADGET_NAME;
+	udc->gadget.ops = &vgadget_ops;
+	udc->gadget.max_speed = USB_SPEED_HIGH;
+	udc->gadget.dev.parent = &pdev->dev;
+	udc->pdev = pdev;
+
+	ret = init_vudc_hw(udc);
+	if (ret)
+		goto err_init_vudc_hw;
+
+	ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
+	if (ret < 0)
+		goto err_add_udc;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &vudc_attr_group);
+	if (ret) {
+		dev_err(&udc->pdev->dev, "create sysfs files\n");
+		goto err_sysfs;
+	}
+
+	platform_set_drvdata(pdev, udc);
+
+	return ret;
+
+err_sysfs:
+	usb_del_gadget_udc(&udc->gadget);
+err_add_udc:
+	cleanup_vudc_hw(udc);
+err_init_vudc_hw:
+	kfree(udc);
+out:
+	return ret;
+}
+
+int vudc_remove(struct platform_device *pdev)
+{
+	struct vudc *udc = platform_get_drvdata(pdev);
+
+	sysfs_remove_group(&pdev->dev.kobj, &vudc_attr_group);
+	usb_del_gadget_udc(&udc->gadget);
+	cleanup_vudc_hw(udc);
+	kfree(udc);
+	return 0;
+}
diff --git a/drivers/usb/usbip/vudc_main.c b/drivers/usb/usbip/vudc_main.c
new file mode 100644
index 000000000000..9e655714e389
--- /dev/null
+++ b/drivers/usb/usbip/vudc_main.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+#include "vudc.h"
+
+static unsigned int vudc_number = 1;
+
+module_param_named(num, vudc_number, uint, S_IRUGO);
+MODULE_PARM_DESC(num, "number of emulated controllers");
+
+static struct platform_driver vudc_driver = {
+	.probe		= vudc_probe,
+	.remove		= vudc_remove,
+	.driver		= {
+		.name	= GADGET_NAME,
+	},
+};
+
+static struct list_head vudc_devices = LIST_HEAD_INIT(vudc_devices);
+
+static int __init init(void)
+{
+	int retval = -ENOMEM;
+	int i;
+	struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	if (vudc_number < 1) {
+		pr_err("Number of emulated UDC must be no less than 1");
+		return -EINVAL;
+	}
+
+	retval = platform_driver_register(&vudc_driver);
+	if (retval < 0)
+		goto out;
+
+	for (i = 0; i < vudc_number; i++) {
+		udc_dev = alloc_vudc_device(i);
+		if (!udc_dev) {
+			retval = -ENOMEM;
+			goto cleanup;
+		}
+
+		retval = platform_device_add(udc_dev->pdev);
+		if (retval < 0) {
+			put_vudc_device(udc_dev);
+			goto cleanup;
+		}
+
+		list_add_tail(&udc_dev->dev_entry, &vudc_devices);
+		if (!platform_get_drvdata(udc_dev->pdev)) {
+			/*
+			 * The udc was added successfully but its probe
+			 * function failed for some reason.
+			 */
+			retval = -EINVAL;
+			goto cleanup;
+		}
+	}
+	goto out;
+
+cleanup:
+	list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
+		list_del(&udc_dev->dev_entry);
+		platform_device_del(udc_dev->pdev);
+		put_vudc_device(udc_dev);
+	}
+
+	platform_driver_unregister(&vudc_driver);
+out:
+	return retval;
+}
+module_init(init);
+
+static void __exit cleanup(void)
+{
+	struct vudc_device *udc_dev = NULL, *udc_dev2 = NULL;
+
+	list_for_each_entry_safe(udc_dev, udc_dev2, &vudc_devices, dev_entry) {
+		list_del(&udc_dev->dev_entry);
+		platform_device_unregister(udc_dev->pdev);
+		put_vudc_device(udc_dev);
+	}
+	platform_driver_unregister(&vudc_driver);
+}
+module_exit(cleanup);
+
+MODULE_DESCRIPTION("USB over IP Device Controller");
+MODULE_AUTHOR("Krzysztof Opasiak, Karol Kosik, Igor Kotrasinski");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/usbip/vudc_rx.c b/drivers/usb/usbip/vudc_rx.c
new file mode 100644
index 000000000000..344bd9473475
--- /dev/null
+++ b/drivers/usb/usbip/vudc_rx.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <net/sock.h>
+#include <linux/list.h>
+#include <linux/kthread.h>
+
+#include "usbip_common.h"
+#include "vudc.h"
+
+static int alloc_urb_from_cmd(struct urb **urbp,
+			      struct usbip_header *pdu, u8 type)
+{
+	struct urb *urb;
+
+	if (type == USB_ENDPOINT_XFER_ISOC)
+		urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets,
+					  GFP_KERNEL);
+	else
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+
+	if (!urb)
+		goto err;
+
+	usbip_pack_pdu(pdu, urb, USBIP_CMD_SUBMIT, 0);
+
+	if (urb->transfer_buffer_length > 0) {
+		urb->transfer_buffer = kzalloc(urb->transfer_buffer_length,
+			GFP_KERNEL);
+		if (!urb->transfer_buffer)
+			goto free_urb;
+	}
+
+	urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8,
+			    GFP_KERNEL);
+	if (!urb->setup_packet)
+		goto free_buffer;
+
+	/*
+	 * FIXME - we only setup pipe enough for usbip functions
+	 * to behave nicely
+	 */
+	urb->pipe |= pdu->base.direction == USBIP_DIR_IN ?
+			USB_DIR_IN : USB_DIR_OUT;
+
+	*urbp = urb;
+	return 0;
+
+free_buffer:
+	kfree(urb->transfer_buffer);
+	urb->transfer_buffer = NULL;
+free_urb:
+	usb_free_urb(urb);
+err:
+	return -ENOMEM;
+}
+
+static int v_recv_cmd_unlink(struct vudc *udc,
+				struct usbip_header *pdu)
+{
+	unsigned long flags;
+	struct urbp *urb_p;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	list_for_each_entry(urb_p, &udc->urb_queue, urb_entry) {
+		if (urb_p->seqnum != pdu->u.cmd_unlink.seqnum)
+			continue;
+		urb_p->urb->unlinked = -ECONNRESET;
+		urb_p->seqnum = pdu->base.seqnum;
+		v_kick_timer(udc, jiffies);
+		spin_unlock_irqrestore(&udc->lock, flags);
+		return 0;
+	}
+	/* Not found, completed / not queued */
+	spin_lock(&udc->lock_tx);
+	v_enqueue_ret_unlink(udc, pdu->base.seqnum, 0);
+	wake_up(&udc->tx_waitq);
+	spin_unlock(&udc->lock_tx);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+static int v_recv_cmd_submit(struct vudc *udc,
+				 struct usbip_header *pdu)
+{
+	int ret = 0;
+	struct urbp *urb_p;
+	u8 address;
+	unsigned long flags;
+
+	urb_p = alloc_urbp();
+	if (!urb_p) {
+		usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC);
+		return -ENOMEM;
+	}
+
+	/* base.ep is pipeendpoint(pipe) */
+	address = pdu->base.ep;
+	if (pdu->base.direction == USBIP_DIR_IN)
+		address |= USB_DIR_IN;
+
+	spin_lock_irq(&udc->lock);
+	urb_p->ep = vudc_find_endpoint(udc, address);
+	if (!urb_p->ep) {
+		/* we don't know the type, there may be isoc data! */
+		dev_err(&udc->pdev->dev, "request to nonexistent endpoint");
+		spin_unlock_irq(&udc->lock);
+		usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP);
+		ret = -EPIPE;
+		goto free_urbp;
+	}
+	urb_p->type = urb_p->ep->type;
+	spin_unlock_irq(&udc->lock);
+
+	urb_p->new = 1;
+	urb_p->seqnum = pdu->base.seqnum;
+
+	ret = alloc_urb_from_cmd(&urb_p->urb, pdu, urb_p->ep->type);
+	if (ret) {
+		usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC);
+		ret = -ENOMEM;
+		goto free_urbp;
+	}
+
+	urb_p->urb->status = -EINPROGRESS;
+
+	/* FIXME: more pipe setup to please usbip_common */
+	urb_p->urb->pipe &= ~(11 << 30);
+	switch (urb_p->ep->type) {
+	case USB_ENDPOINT_XFER_BULK:
+		urb_p->urb->pipe |= (PIPE_BULK << 30);
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		urb_p->urb->pipe |= (PIPE_INTERRUPT << 30);
+		break;
+	case USB_ENDPOINT_XFER_CONTROL:
+		urb_p->urb->pipe |= (PIPE_CONTROL << 30);
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		urb_p->urb->pipe |= (PIPE_ISOCHRONOUS << 30);
+		break;
+	}
+	ret = usbip_recv_xbuff(&udc->ud, urb_p->urb);
+	if (ret < 0)
+		goto free_urbp;
+
+	ret = usbip_recv_iso(&udc->ud, urb_p->urb);
+	if (ret < 0)
+		goto free_urbp;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	v_kick_timer(udc, jiffies);
+	list_add_tail(&urb_p->urb_entry, &udc->urb_queue);
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+
+free_urbp:
+	free_urbp_and_urb(urb_p);
+	return ret;
+}
+
+static int v_rx_pdu(struct usbip_device *ud)
+{
+	int ret;
+	struct usbip_header pdu;
+	struct vudc *udc = container_of(ud, struct vudc, ud);
+
+	memset(&pdu, 0, sizeof(pdu));
+	ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu));
+	if (ret != sizeof(pdu)) {
+		usbip_event_add(ud, VUDC_EVENT_ERROR_TCP);
+		if (ret >= 0)
+			return -EPIPE;
+		return ret;
+	}
+	usbip_header_correct_endian(&pdu, 0);
+
+	spin_lock_irq(&ud->lock);
+	ret = (ud->status == SDEV_ST_USED);
+	spin_unlock_irq(&ud->lock);
+	if (!ret) {
+		usbip_event_add(ud, VUDC_EVENT_ERROR_TCP);
+		return -EBUSY;
+	}
+
+	switch (pdu.base.command) {
+	case USBIP_CMD_UNLINK:
+		ret = v_recv_cmd_unlink(udc, &pdu);
+		break;
+	case USBIP_CMD_SUBMIT:
+		ret = v_recv_cmd_submit(udc, &pdu);
+		break;
+	default:
+		ret = -EPIPE;
+		pr_err("rx: unknown command");
+		break;
+	}
+	return ret;
+}
+
+int v_rx_loop(void *data)
+{
+	struct usbip_device *ud = data;
+	int ret = 0;
+
+	while (!kthread_should_stop()) {
+		if (usbip_event_happened(ud))
+			break;
+		ret = v_rx_pdu(ud);
+		if (ret < 0) {
+			pr_warn("v_rx exit with error %d", ret);
+			break;
+		}
+	}
+	return ret;
+}
diff --git a/drivers/usb/usbip/vudc_sysfs.c b/drivers/usb/usbip/vudc_sysfs.c
new file mode 100644
index 000000000000..99397fa1e3f0
--- /dev/null
+++ b/drivers/usb/usbip/vudc_sysfs.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/ch9.h>
+#include <linux/sysfs.h>
+#include <linux/kthread.h>
+#include <linux/byteorder/generic.h>
+
+#include "usbip_common.h"
+#include "vudc.h"
+
+#include <net/sock.h>
+
+/* called with udc->lock held */
+int get_gadget_descs(struct vudc *udc)
+{
+	struct vrequest *usb_req;
+	struct vep *ep0 = to_vep(udc->gadget.ep0);
+	struct usb_device_descriptor *ddesc = &udc->dev_desc;
+	struct usb_ctrlrequest req;
+	int ret;
+
+	if (!udc || !udc->driver || !udc->pullup)
+		return -EINVAL;
+
+	req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
+	req.bRequest = USB_REQ_GET_DESCRIPTOR;
+	req.wValue = cpu_to_le16(USB_DT_DEVICE << 8);
+	req.wIndex = cpu_to_le16(0);
+	req.wLength = cpu_to_le16(sizeof(*ddesc));
+
+	spin_unlock(&udc->lock);
+	ret = udc->driver->setup(&(udc->gadget), &req);
+	spin_lock(&udc->lock);
+	if (ret < 0)
+		goto out;
+
+	/* assuming request queue is empty; request is now on top */
+	usb_req = list_last_entry(&ep0->req_queue, struct vrequest, req_entry);
+	list_del(&usb_req->req_entry);
+
+	if (usb_req->req.length > sizeof(*ddesc)) {
+		ret = -EOVERFLOW;
+		goto giveback_req;
+	}
+
+	memcpy(ddesc, usb_req->req.buf, sizeof(*ddesc));
+	udc->desc_cached = 1;
+	ret = 0;
+giveback_req:
+	usb_req->req.status = 0;
+	usb_req->req.actual = usb_req->req.length;
+	usb_gadget_giveback_request(&(ep0->ep), &(usb_req->req));
+out:
+	return ret;
+}
+
+/*
+ * Exposes device descriptor from the gadget driver.
+ */
+static ssize_t dev_desc_read(struct file *file, struct kobject *kobj,
+			     struct bin_attribute *attr, char *out,
+			     loff_t off, size_t count)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct vudc *udc = (struct vudc *)dev_get_drvdata(dev);
+	char *desc_ptr = (char *) &udc->dev_desc;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	if (!udc->desc_cached) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+
+	memcpy(out, desc_ptr + off, count);
+	ret = count;
+unlock:
+	spin_unlock_irqrestore(&udc->lock, flags);
+	return ret;
+}
+static BIN_ATTR_RO(dev_desc, sizeof(struct usb_device_descriptor));
+
+static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr,
+		     const char *in, size_t count)
+{
+	struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
+	int rv;
+	int sockfd = 0;
+	int err;
+	struct socket *socket;
+	unsigned long flags;
+	int ret;
+
+	rv = kstrtoint(in, 0, &sockfd);
+	if (rv != 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&udc->lock, flags);
+	/* Don't export what we don't have */
+	if (!udc || !udc->driver || !udc->pullup) {
+		dev_err(dev, "no device or gadget not bound");
+		ret = -ENODEV;
+		goto unlock;
+	}
+
+	if (sockfd != -1) {
+		if (udc->connected) {
+			dev_err(dev, "Device already connected");
+			ret = -EBUSY;
+			goto unlock;
+		}
+
+		spin_lock_irq(&udc->ud.lock);
+
+		if (udc->ud.status != SDEV_ST_AVAILABLE) {
+			ret = -EINVAL;
+			goto unlock_ud;
+		}
+
+		socket = sockfd_lookup(sockfd, &err);
+		if (!socket) {
+			dev_err(dev, "failed to lookup sock");
+			ret = -EINVAL;
+			goto unlock_ud;
+		}
+
+		udc->ud.tcp_socket = socket;
+
+		spin_unlock_irq(&udc->ud.lock);
+		spin_unlock_irqrestore(&udc->lock, flags);
+
+		udc->ud.tcp_rx = kthread_get_run(&v_rx_loop,
+						    &udc->ud, "vudc_rx");
+		udc->ud.tcp_tx = kthread_get_run(&v_tx_loop,
+						    &udc->ud, "vudc_tx");
+
+		spin_lock_irqsave(&udc->lock, flags);
+		spin_lock_irq(&udc->ud.lock);
+		udc->ud.status = SDEV_ST_USED;
+		spin_unlock_irq(&udc->ud.lock);
+
+		do_gettimeofday(&udc->start_time);
+		v_start_timer(udc);
+		udc->connected = 1;
+	} else {
+		if (!udc->connected) {
+			dev_err(dev, "Device not connected");
+			ret = -EINVAL;
+			goto unlock;
+		}
+
+		spin_lock_irq(&udc->ud.lock);
+		if (udc->ud.status != SDEV_ST_USED) {
+			ret = -EINVAL;
+			goto unlock_ud;
+		}
+		spin_unlock_irq(&udc->ud.lock);
+
+		usbip_event_add(&udc->ud, VUDC_EVENT_DOWN);
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return count;
+
+unlock_ud:
+	spin_unlock_irq(&udc->ud.lock);
+unlock:
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return ret;
+}
+static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
+
+static ssize_t usbip_status_show(struct device *dev,
+			       struct device_attribute *attr, char *out)
+{
+	struct vudc *udc = (struct vudc *) dev_get_drvdata(dev);
+	int status;
+
+	if (!udc) {
+		dev_err(dev, "no device");
+		return -ENODEV;
+	}
+	spin_lock_irq(&udc->ud.lock);
+	status = udc->ud.status;
+	spin_unlock_irq(&udc->ud.lock);
+
+	return snprintf(out, PAGE_SIZE, "%d\n", status);
+}
+static DEVICE_ATTR_RO(usbip_status);
+
+static struct attribute *dev_attrs[] = {
+	&dev_attr_usbip_sockfd.attr,
+	&dev_attr_usbip_status.attr,
+	NULL,
+};
+
+static struct bin_attribute *dev_bin_attrs[] = {
+	&bin_attr_dev_desc,
+	NULL,
+};
+
+const struct attribute_group vudc_attr_group = {
+	.attrs = dev_attrs,
+	.bin_attrs = dev_bin_attrs,
+};
diff --git a/drivers/usb/usbip/vudc_transfer.c b/drivers/usb/usbip/vudc_transfer.c
new file mode 100644
index 000000000000..aba6bd478045
--- /dev/null
+++ b/drivers/usb/usbip/vudc_transfer.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *
+ * Based on dummy_hcd.c, which is:
+ * Copyright (C) 2003 David Brownell
+ * Copyright (C) 2003-2005 Alan Stern
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/usb.h>
+#include <linux/timer.h>
+#include <linux/usb/ch9.h>
+
+#include "vudc.h"
+
+#define DEV_REQUEST	(USB_TYPE_STANDARD | USB_RECIP_DEVICE)
+#define DEV_INREQUEST	(DEV_REQUEST | USB_DIR_IN)
+#define INTF_REQUEST	(USB_TYPE_STANDARD | USB_RECIP_INTERFACE)
+#define INTF_INREQUEST	(INTF_REQUEST | USB_DIR_IN)
+#define EP_REQUEST	(USB_TYPE_STANDARD | USB_RECIP_ENDPOINT)
+#define EP_INREQUEST	(EP_REQUEST | USB_DIR_IN)
+
+static int get_frame_limit(enum usb_device_speed speed)
+{
+	switch (speed) {
+	case USB_SPEED_LOW:
+		return 8 /*bytes*/ * 12 /*packets*/;
+	case USB_SPEED_FULL:
+		return 64 /*bytes*/ * 19 /*packets*/;
+	case USB_SPEED_HIGH:
+		return 512 /*bytes*/ * 13 /*packets*/ * 8 /*uframes*/;
+	case USB_SPEED_SUPER:
+		/* Bus speed is 500000 bytes/ms, so use a little less */
+		return 490000;
+	default:
+		/* error */
+		return -1;
+	}
+
+}
+
+/*
+ * handle_control_request() - handles all control transfers
+ * @udc: pointer to vudc
+ * @urb: the urb request to handle
+ * @setup: pointer to the setup data for a USB device control
+ *	 request
+ * @status: pointer to request handling status
+ *
+ * Return 0 - if the request was handled
+ *	  1 - if the request wasn't handles
+ *	  error code on error
+ *
+ * Adapted from drivers/usb/gadget/udc/dummy_hcd.c
+ */
+static int handle_control_request(struct vudc *udc, struct urb *urb,
+				  struct usb_ctrlrequest *setup,
+				  int *status)
+{
+	struct vep	*ep2;
+	int		ret_val = 1;
+	unsigned	w_index;
+	unsigned	w_value;
+
+	w_index = le16_to_cpu(setup->wIndex);
+	w_value = le16_to_cpu(setup->wValue);
+	switch (setup->bRequest) {
+	case USB_REQ_SET_ADDRESS:
+		if (setup->bRequestType != DEV_REQUEST)
+			break;
+		udc->address = w_value;
+		ret_val = 0;
+		*status = 0;
+		break;
+	case USB_REQ_SET_FEATURE:
+		if (setup->bRequestType == DEV_REQUEST) {
+			ret_val = 0;
+			switch (w_value) {
+			case USB_DEVICE_REMOTE_WAKEUP:
+				break;
+			case USB_DEVICE_B_HNP_ENABLE:
+				udc->gadget.b_hnp_enable = 1;
+				break;
+			case USB_DEVICE_A_HNP_SUPPORT:
+				udc->gadget.a_hnp_support = 1;
+				break;
+			case USB_DEVICE_A_ALT_HNP_SUPPORT:
+				udc->gadget.a_alt_hnp_support = 1;
+				break;
+			default:
+				ret_val = -EOPNOTSUPP;
+			}
+			if (ret_val == 0) {
+				udc->devstatus |= (1 << w_value);
+				*status = 0;
+			}
+		} else if (setup->bRequestType == EP_REQUEST) {
+			/* endpoint halt */
+			ep2 = vudc_find_endpoint(udc, w_index);
+			if (!ep2 || ep2->ep.name == udc->ep[0].ep.name) {
+				ret_val = -EOPNOTSUPP;
+				break;
+			}
+			ep2->halted = 1;
+			ret_val = 0;
+			*status = 0;
+		}
+		break;
+	case USB_REQ_CLEAR_FEATURE:
+		if (setup->bRequestType == DEV_REQUEST) {
+			ret_val = 0;
+			switch (w_value) {
+			case USB_DEVICE_REMOTE_WAKEUP:
+				w_value = USB_DEVICE_REMOTE_WAKEUP;
+				break;
+
+			case USB_DEVICE_U1_ENABLE:
+			case USB_DEVICE_U2_ENABLE:
+			case USB_DEVICE_LTM_ENABLE:
+				ret_val = -EOPNOTSUPP;
+				break;
+			default:
+				ret_val = -EOPNOTSUPP;
+				break;
+			}
+			if (ret_val == 0) {
+				udc->devstatus &= ~(1 << w_value);
+				*status = 0;
+			}
+		} else if (setup->bRequestType == EP_REQUEST) {
+			/* endpoint halt */
+			ep2 = vudc_find_endpoint(udc, w_index);
+			if (!ep2) {
+				ret_val = -EOPNOTSUPP;
+				break;
+			}
+			if (!ep2->wedged)
+				ep2->halted = 0;
+			ret_val = 0;
+			*status = 0;
+		}
+		break;
+	case USB_REQ_GET_STATUS:
+		if (setup->bRequestType == DEV_INREQUEST
+				|| setup->bRequestType == INTF_INREQUEST
+				|| setup->bRequestType == EP_INREQUEST) {
+			char *buf;
+			/*
+			 * device: remote wakeup, selfpowered
+			 * interface: nothing
+			 * endpoint: halt
+			 */
+			buf = (char *)urb->transfer_buffer;
+			if (urb->transfer_buffer_length > 0) {
+				if (setup->bRequestType == EP_INREQUEST) {
+					ep2 = vudc_find_endpoint(udc, w_index);
+					if (!ep2) {
+						ret_val = -EOPNOTSUPP;
+						break;
+					}
+					buf[0] = ep2->halted;
+				} else if (setup->bRequestType ==
+					   DEV_INREQUEST) {
+					buf[0] = (u8)udc->devstatus;
+				} else
+					buf[0] = 0;
+			}
+			if (urb->transfer_buffer_length > 1)
+				buf[1] = 0;
+			urb->actual_length = min_t(u32, 2,
+				urb->transfer_buffer_length);
+			ret_val = 0;
+			*status = 0;
+		}
+		break;
+	}
+	return ret_val;
+}
+
+/* Adapted from dummy_hcd.c ; caller must hold lock */
+static int transfer(struct vudc *udc,
+		struct urb *urb, struct vep *ep, int limit)
+{
+	struct vrequest	*req;
+	int sent = 0;
+top:
+	/* if there's no request queued, the device is NAKing; return */
+	list_for_each_entry(req, &ep->req_queue, req_entry) {
+		unsigned	host_len, dev_len, len;
+		void		*ubuf_pos, *rbuf_pos;
+		int		is_short, to_host;
+		int		rescan = 0;
+
+		/*
+		 * 1..N packets of ep->ep.maxpacket each ... the last one
+		 * may be short (including zero length).
+		 *
+		 * writer can send a zlp explicitly (length 0) or implicitly
+		 * (length mod maxpacket zero, and 'zero' flag); they always
+		 * terminate reads.
+		 */
+		host_len = urb->transfer_buffer_length - urb->actual_length;
+		dev_len = req->req.length - req->req.actual;
+		len = min(host_len, dev_len);
+
+		to_host = usb_pipein(urb->pipe);
+		if (unlikely(len == 0))
+			is_short = 1;
+		else {
+			/* send multiple of maxpacket first, then remainder */
+			if (len >= ep->ep.maxpacket) {
+				is_short = 0;
+				if (len % ep->ep.maxpacket > 0)
+					rescan = 1;
+				len -= len % ep->ep.maxpacket;
+			} else {
+				is_short = 1;
+			}
+
+			ubuf_pos = urb->transfer_buffer + urb->actual_length;
+			rbuf_pos = req->req.buf + req->req.actual;
+
+			if (urb->pipe & USB_DIR_IN)
+				memcpy(ubuf_pos, rbuf_pos, len);
+			else
+				memcpy(rbuf_pos, ubuf_pos, len);
+
+			urb->actual_length += len;
+			req->req.actual += len;
+			sent += len;
+		}
+
+		/*
+		 * short packets terminate, maybe with overflow/underflow.
+		 * it's only really an error to write too much.
+		 *
+		 * partially filling a buffer optionally blocks queue advances
+		 * (so completion handlers can clean up the queue) but we don't
+		 * need to emulate such data-in-flight.
+		 */
+		if (is_short) {
+			if (host_len == dev_len) {
+				req->req.status = 0;
+				urb->status = 0;
+			} else if (to_host) {
+				req->req.status = 0;
+				if (dev_len > host_len)
+					urb->status = -EOVERFLOW;
+				else
+					urb->status = 0;
+			} else {
+				urb->status = 0;
+				if (host_len > dev_len)
+					req->req.status = -EOVERFLOW;
+				else
+					req->req.status = 0;
+			}
+
+		/* many requests terminate without a short packet */
+		/* also check if we need to send zlp */
+		} else {
+			if (req->req.length == req->req.actual) {
+				if (req->req.zero && to_host)
+					rescan = 1;
+				else
+					req->req.status = 0;
+			}
+			if (urb->transfer_buffer_length == urb->actual_length) {
+				if (urb->transfer_flags & URB_ZERO_PACKET &&
+				    !to_host)
+					rescan = 1;
+				else
+					urb->status = 0;
+			}
+		}
+
+		/* device side completion --> continuable */
+		if (req->req.status != -EINPROGRESS) {
+
+			list_del_init(&req->req_entry);
+			spin_unlock(&udc->lock);
+			usb_gadget_giveback_request(&ep->ep, &req->req);
+			spin_lock(&udc->lock);
+
+			/* requests might have been unlinked... */
+			rescan = 1;
+		}
+
+		/* host side completion --> terminate */
+		if (urb->status != -EINPROGRESS)
+			break;
+
+		/* rescan to continue with any other queued i/o */
+		if (rescan)
+			goto top;
+	}
+	return sent;
+}
+
+static void v_timer(unsigned long _vudc)
+{
+	struct vudc *udc = (struct vudc *) _vudc;
+	struct transfer_timer *timer = &udc->tr_timer;
+	struct urbp *urb_p, *tmp;
+	unsigned long flags;
+	struct usb_ep *_ep;
+	struct vep *ep;
+	int ret = 0;
+	int total, limit;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	total = get_frame_limit(udc->gadget.speed);
+	if (total < 0) {	/* unknown speed, or not set yet */
+		timer->state = VUDC_TR_IDLE;
+		spin_unlock_irqrestore(&udc->lock, flags);
+		return;
+	}
+	/* is it next frame now? */
+	if (time_after(jiffies, timer->frame_start + msecs_to_jiffies(1))) {
+		timer->frame_limit = total;
+		/* FIXME: how to make it accurate? */
+		timer->frame_start = jiffies;
+	} else {
+		total = timer->frame_limit;
+	}
+
+	list_for_each_entry(_ep, &udc->gadget.ep_list, ep_list) {
+		ep = to_vep(_ep);
+		ep->already_seen = 0;
+	}
+
+restart:
+	list_for_each_entry_safe(urb_p, tmp, &udc->urb_queue, urb_entry) {
+		struct urb *urb = urb_p->urb;
+
+		ep = urb_p->ep;
+		if (urb->unlinked)
+			goto return_urb;
+		if (timer->state != VUDC_TR_RUNNING)
+			continue;
+
+		if (!ep) {
+			urb->status = -EPROTO;
+			goto return_urb;
+		}
+
+		/* Used up bandwidth? */
+		if (total <= 0 && ep->type == USB_ENDPOINT_XFER_BULK)
+			continue;
+
+		if (ep->already_seen)
+			continue;
+		ep->already_seen = 1;
+		if (ep == &udc->ep[0] && urb_p->new) {
+			ep->setup_stage = 1;
+			urb_p->new = 0;
+		}
+		if (ep->halted && !ep->setup_stage) {
+			urb->status = -EPIPE;
+			goto return_urb;
+		}
+
+		if (ep == &udc->ep[0] && ep->setup_stage) {
+			/* TODO - flush any stale requests */
+			ep->setup_stage = 0;
+			ep->halted = 0;
+
+			ret = handle_control_request(udc, urb,
+				(struct usb_ctrlrequest *) urb->setup_packet,
+				(&urb->status));
+			if (ret > 0) {
+				spin_unlock(&udc->lock);
+				ret = udc->driver->setup(&udc->gadget,
+					(struct usb_ctrlrequest *)
+					urb->setup_packet);
+				spin_lock(&udc->lock);
+			}
+			if (ret >= 0) {
+				/* no delays (max 64kb data stage) */
+				limit = 64 * 1024;
+				goto treat_control_like_bulk;
+			} else {
+				urb->status = -EPIPE;
+				urb->actual_length = 0;
+				goto return_urb;
+			}
+		}
+
+		limit = total;
+		switch (ep->type) {
+		case USB_ENDPOINT_XFER_ISOC:
+			/* TODO: support */
+			urb->status = -EXDEV;
+			break;
+
+		case USB_ENDPOINT_XFER_INT:
+			/*
+			 * TODO: figure out bandwidth guarantees
+			 * for now, give unlimited bandwidth
+			 */
+			limit += urb->transfer_buffer_length;
+			/* fallthrough */
+		default:
+treat_control_like_bulk:
+			total -= transfer(udc, urb, ep, limit);
+		}
+		if (urb->status == -EINPROGRESS)
+			continue;
+
+return_urb:
+		if (ep)
+			ep->already_seen = ep->setup_stage = 0;
+
+		spin_lock(&udc->lock_tx);
+		list_del(&urb_p->urb_entry);
+		if (!urb->unlinked) {
+			v_enqueue_ret_submit(udc, urb_p);
+		} else {
+			v_enqueue_ret_unlink(udc, urb_p->seqnum,
+					     urb->unlinked);
+			free_urbp_and_urb(urb_p);
+		}
+		wake_up(&udc->tx_waitq);
+		spin_unlock(&udc->lock_tx);
+
+		goto restart;
+	}
+
+	/* TODO - also wait on empty usb_request queues? */
+	if (list_empty(&udc->urb_queue))
+		timer->state = VUDC_TR_IDLE;
+	else
+		mod_timer(&timer->timer,
+			  timer->frame_start + msecs_to_jiffies(1));
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+}
+
+/* All timer functions are run with udc->lock held */
+
+void v_init_timer(struct vudc *udc)
+{
+	struct transfer_timer *t = &udc->tr_timer;
+
+	setup_timer(&t->timer, v_timer, (unsigned long) udc);
+	t->state = VUDC_TR_STOPPED;
+}
+
+void v_start_timer(struct vudc *udc)
+{
+	struct transfer_timer *t = &udc->tr_timer;
+
+	dev_dbg(&udc->pdev->dev, "timer start");
+	switch (t->state) {
+	case VUDC_TR_RUNNING:
+		return;
+	case VUDC_TR_IDLE:
+		return v_kick_timer(udc, jiffies);
+	case VUDC_TR_STOPPED:
+		t->state = VUDC_TR_IDLE;
+		t->frame_start = jiffies;
+		t->frame_limit = get_frame_limit(udc->gadget.speed);
+		return v_kick_timer(udc, jiffies);
+	}
+}
+
+void v_kick_timer(struct vudc *udc, unsigned long time)
+{
+	struct transfer_timer *t = &udc->tr_timer;
+
+	dev_dbg(&udc->pdev->dev, "timer kick");
+	switch (t->state) {
+	case VUDC_TR_RUNNING:
+		return;
+	case VUDC_TR_IDLE:
+		t->state = VUDC_TR_RUNNING;
+		/* fallthrough */
+	case VUDC_TR_STOPPED:
+		/* we may want to kick timer to unqueue urbs */
+		mod_timer(&t->timer, time);
+	}
+}
+
+void v_stop_timer(struct vudc *udc)
+{
+	struct transfer_timer *t = &udc->tr_timer;
+
+	/* timer itself will take care of stopping */
+	dev_dbg(&udc->pdev->dev, "timer stop");
+	t->state = VUDC_TR_STOPPED;
+}
diff --git a/drivers/usb/usbip/vudc_tx.c b/drivers/usb/usbip/vudc_tx.c
new file mode 100644
index 000000000000..234661782fa0
--- /dev/null
+++ b/drivers/usb/usbip/vudc_tx.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <net/sock.h>
+#include <linux/list.h>
+#include <linux/kthread.h>
+
+#include "usbip_common.h"
+#include "vudc.h"
+
+static inline void setup_base_pdu(struct usbip_header_basic *base,
+				  __u32 command, __u32 seqnum)
+{
+	base->command	= command;
+	base->seqnum	= seqnum;
+	base->devid	= 0;
+	base->ep	= 0;
+	base->direction = 0;
+}
+
+static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urbp *urb_p)
+{
+	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, urb_p->seqnum);
+	usbip_pack_pdu(rpdu, urb_p->urb, USBIP_RET_SUBMIT, 1);
+}
+
+static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
+				 struct v_unlink *unlink)
+{
+	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
+	rpdu->u.ret_unlink.status = unlink->status;
+}
+
+static int v_send_ret_unlink(struct vudc *udc, struct v_unlink *unlink)
+{
+	struct msghdr msg;
+	struct kvec iov[1];
+	size_t txsize;
+
+	int ret;
+	struct usbip_header pdu_header;
+
+	txsize = 0;
+	memset(&pdu_header, 0, sizeof(pdu_header));
+	memset(&msg, 0, sizeof(msg));
+	memset(&iov, 0, sizeof(iov));
+
+	/* 1. setup usbip_header */
+	setup_ret_unlink_pdu(&pdu_header, unlink);
+	usbip_header_correct_endian(&pdu_header, 1);
+
+	iov[0].iov_base = &pdu_header;
+	iov[0].iov_len  = sizeof(pdu_header);
+	txsize += sizeof(pdu_header);
+
+	ret = kernel_sendmsg(udc->ud.tcp_socket, &msg, iov,
+			     1, txsize);
+	if (ret != txsize) {
+		usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP);
+		if (ret >= 0)
+			return -EPIPE;
+		return ret;
+	}
+	kfree(unlink);
+
+	return txsize;
+}
+
+static int v_send_ret_submit(struct vudc *udc, struct urbp *urb_p)
+{
+	struct urb *urb = urb_p->urb;
+	struct usbip_header pdu_header;
+	struct usbip_iso_packet_descriptor *iso_buffer = NULL;
+	struct kvec *iov = NULL;
+	int iovnum = 0;
+	int ret = 0;
+	size_t txsize;
+	struct msghdr msg;
+
+	txsize = 0;
+	memset(&pdu_header, 0, sizeof(pdu_header));
+	memset(&msg, 0, sizeof(msg));
+
+	if (urb_p->type == USB_ENDPOINT_XFER_ISOC)
+		iovnum = 2 + urb->number_of_packets;
+	else
+		iovnum = 2;
+
+	iov = kcalloc(iovnum, sizeof(*iov), GFP_KERNEL);
+	if (!iov) {
+		usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC);
+		ret = -ENOMEM;
+		goto out;
+	}
+	iovnum = 0;
+
+	/* 1. setup usbip_header */
+	setup_ret_submit_pdu(&pdu_header, urb_p);
+	usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n",
+			  pdu_header.base.seqnum, urb);
+	usbip_header_correct_endian(&pdu_header, 1);
+
+	iov[iovnum].iov_base = &pdu_header;
+	iov[iovnum].iov_len  = sizeof(pdu_header);
+	iovnum++;
+	txsize += sizeof(pdu_header);
+
+	/* 2. setup transfer buffer */
+	if (urb_p->type != USB_ENDPOINT_XFER_ISOC &&
+	    usb_pipein(urb->pipe) && urb->actual_length > 0) {
+		iov[iovnum].iov_base = urb->transfer_buffer;
+		iov[iovnum].iov_len  = urb->actual_length;
+		iovnum++;
+		txsize += urb->actual_length;
+	} else if (urb_p->type == USB_ENDPOINT_XFER_ISOC &&
+		usb_pipein(urb->pipe)) {
+		/* FIXME - copypasted from stub_tx, refactor */
+		int i;
+
+		for (i = 0; i < urb->number_of_packets; i++) {
+			iov[iovnum].iov_base = urb->transfer_buffer +
+				urb->iso_frame_desc[i].offset;
+			iov[iovnum].iov_len =
+				urb->iso_frame_desc[i].actual_length;
+			iovnum++;
+			txsize += urb->iso_frame_desc[i].actual_length;
+		}
+
+		if (txsize != sizeof(pdu_header) + urb->actual_length) {
+			usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP);
+			ret = -EPIPE;
+			goto out;
+		}
+	}
+	/* else - no buffer to send */
+
+	/* 3. setup iso_packet_descriptor */
+	if (urb_p->type == USB_ENDPOINT_XFER_ISOC) {
+		ssize_t len = 0;
+
+		iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
+		if (!iso_buffer) {
+			usbip_event_add(&udc->ud,
+					VUDC_EVENT_ERROR_MALLOC);
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		iov[iovnum].iov_base = iso_buffer;
+		iov[iovnum].iov_len  = len;
+		txsize += len;
+		iovnum++;
+	}
+
+	ret = kernel_sendmsg(udc->ud.tcp_socket, &msg,
+						iov,  iovnum, txsize);
+	if (ret != txsize) {
+		usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_TCP);
+		if (ret >= 0)
+			ret = -EPIPE;
+		goto out;
+	}
+
+out:
+	kfree(iov);
+	kfree(iso_buffer);
+	free_urbp_and_urb(urb_p);
+	if (ret < 0)
+		return ret;
+	return txsize;
+}
+
+static int v_send_ret(struct vudc *udc)
+{
+	unsigned long flags;
+	struct tx_item *txi;
+	size_t total_size = 0;
+	int ret = 0;
+
+	spin_lock_irqsave(&udc->lock_tx, flags);
+	while (!list_empty(&udc->tx_queue)) {
+		txi = list_first_entry(&udc->tx_queue, struct tx_item,
+				       tx_entry);
+		list_del(&txi->tx_entry);
+		spin_unlock_irqrestore(&udc->lock_tx, flags);
+
+		switch (txi->type) {
+		case TX_SUBMIT:
+			ret = v_send_ret_submit(udc, txi->s);
+			break;
+		case TX_UNLINK:
+			ret = v_send_ret_unlink(udc, txi->u);
+			break;
+		}
+		kfree(txi);
+
+		if (ret < 0)
+			return ret;
+
+		total_size += ret;
+
+		spin_lock_irqsave(&udc->lock_tx, flags);
+	}
+
+	spin_unlock_irqrestore(&udc->lock_tx, flags);
+	return total_size;
+}
+
+
+int v_tx_loop(void *data)
+{
+	struct usbip_device *ud = (struct usbip_device *) data;
+	struct vudc *udc = container_of(ud, struct vudc, ud);
+	int ret;
+
+	while (!kthread_should_stop()) {
+		if (usbip_event_happened(&udc->ud))
+			break;
+		ret = v_send_ret(udc);
+		if (ret < 0) {
+			pr_warn("v_tx exit with error %d", ret);
+			break;
+		}
+		wait_event_interruptible(udc->tx_waitq,
+					 (!list_empty(&udc->tx_queue) ||
+					 kthread_should_stop()));
+	}
+
+	return 0;
+}
+
+/* called with spinlocks held */
+void v_enqueue_ret_unlink(struct vudc *udc, __u32 seqnum, __u32 status)
+{
+	struct tx_item *txi;
+	struct v_unlink *unlink;
+
+	txi = kzalloc(sizeof(*txi), GFP_ATOMIC);
+	if (!txi) {
+		usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC);
+		return;
+	}
+	unlink = kzalloc(sizeof(*unlink), GFP_ATOMIC);
+	if (!unlink) {
+		kfree(txi);
+		usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC);
+		return;
+	}
+
+	unlink->seqnum = seqnum;
+	unlink->status = status;
+	txi->type = TX_UNLINK;
+	txi->u = unlink;
+
+	list_add_tail(&txi->tx_entry, &udc->tx_queue);
+}
+
+/* called with spinlocks held */
+void v_enqueue_ret_submit(struct vudc *udc, struct urbp *urb_p)
+{
+	struct tx_item *txi;
+
+	txi = kzalloc(sizeof(*txi), GFP_ATOMIC);
+	if (!txi) {
+		usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC);
+		return;
+	}
+
+	txi->type = TX_SUBMIT;
+	txi->s = urb_p;
+
+	list_add_tail(&txi->tx_entry, &udc->tx_queue);
+}
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c
index 8ed8e34c3492..33acd1599e99 100644
--- a/drivers/usb/wusbcore/crypto.c
+++ b/drivers/usb/wusbcore/crypto.c
@@ -54,7 +54,7 @@
 #include <linux/usb/wusb.h>
 #include <linux/scatterlist.h>
 
-static int debug_crypto_verify = 0;
+static int debug_crypto_verify;
 
 module_param(debug_crypto_verify, int, 0);
 MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms");
@@ -390,7 +390,7 @@ static int wusb_oob_mic_verify(void)
 				    0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
 				    0x2c, 0x2d, 0x2e, 0x2f },
 		.MIC	 	= { 0x75, 0x6a, 0x97, 0x51, 0x0c, 0x8c,
-				    0x14, 0x7b } ,
+				    0x14, 0x7b },
 	};
 	size_t hs_size;
 
@@ -480,7 +480,7 @@ static int wusb_key_derive_verify(void)
 		printk(KERN_ERR "E: keydvt in: key\n");
 		wusb_key_dump(stv_key_a1, sizeof(stv_key_a1));
 		printk(KERN_ERR "E: keydvt in: nonce\n");
-		wusb_key_dump( &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
+		wusb_key_dump(&stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1));
 		printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n");
 		wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1));
 		printk(KERN_ERR "E: keydvt out: KCK\n");
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index 3f4f5fbded55..bf9551735938 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -893,7 +893,6 @@ out:
 error_nodev:
 	return;
 
-	wusb_dev_sysfs_rm(wusb_dev);
 error_add_sysfs:
 	wusb_dev_bos_rm(wusb_dev);
 error_bos_add:
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 0367c63f5960..e6b41f42602b 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -4,6 +4,7 @@
 #include <linux/pci.h>
 #include <linux/mod_devicetable.h>
 
+#include <linux/bcma/bcma_driver_arm_c9.h>
 #include <linux/bcma/bcma_driver_chipcommon.h>
 #include <linux/bcma/bcma_driver_pci.h>
 #include <linux/bcma/bcma_driver_pcie2.h>
diff --git a/include/linux/bcma/bcma_driver_arm_c9.h b/include/linux/bcma/bcma_driver_arm_c9.h
new file mode 100644
index 000000000000..93bd73d670d5
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_arm_c9.h
@@ -0,0 +1,15 @@
+#ifndef LINUX_BCMA_DRIVER_ARM_C9_H_
+#define LINUX_BCMA_DRIVER_ARM_C9_H_
+
+/* DMU (Device Management Unit) */
+#define BCMA_DMU_CRU_USB2_CONTROL			0x0164
+#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK	0x00000FFC
+#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT	2
+#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK	0x00007000
+#define  BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT	12
+#define BCMA_DMU_CRU_CLKSET_KEY				0x0180
+#define BCMA_DMU_CRU_STRAPS_CTRL			0x02A0
+#define  BCMA_DMU_CRU_STRAPS_CTRL_USB3			0x00000010
+#define  BCMA_DMU_CRU_STRAPS_CTRL_4BYTE			0x00008000
+
+#endif /* LINUX_BCMA_DRIVER_ARM_C9_H_ */
diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h
index 9352adc95de6..76f30f940c70 100644
--- a/include/linux/mfd/syscon/exynos5-pmu.h
+++ b/include/linux/mfd/syscon/exynos5-pmu.h
@@ -38,6 +38,9 @@
 
 /* Exynos5433 specific register definitions */
 #define EXYNOS5433_USBHOST30_PHY_CONTROL	(0x728)
+#define EXYNOS5433_MIPI_PHY0_CONTROL		(0x710)
+#define EXYNOS5433_MIPI_PHY1_CONTROL		(0x714)
+#define EXYNOS5433_MIPI_PHY2_CONTROL		(0x718)
 
 #define EXYNOS5_PHY_ENABLE			BIT(0)
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 6a9a0c28415d..eba1f10e8cfd 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -374,13 +374,12 @@ struct usb_bus {
 
 	int devnum_next;		/* Next open device number in
 					 * round-robin allocation */
+	struct mutex devnum_next_mutex; /* devnum_next mutex */
 
 	struct usb_devmap devmap;	/* device address allocation map */
 	struct usb_device *root_hub;	/* Root hub */
 	struct usb_bus *hs_companion;	/* Companion EHCI bus, if any */
 
-	struct mutex usb_address0_mutex; /* unaddressed device mutex */
-
 	int bandwidth_allocated;	/* on this bus: how much of the time
 					 * reserved for periodic (intr/iso)
 					 * requests is used, on average?
@@ -720,7 +719,7 @@ extern void usb_enable_ltm(struct usb_device *udev);
 
 static inline bool usb_device_supports_ltm(struct usb_device *udev)
 {
-	if (udev->speed != USB_SPEED_SUPER || !udev->bos || !udev->bos->ss_cap)
+	if (udev->speed < USB_SPEED_SUPER || !udev->bos || !udev->bos->ss_cap)
 		return false;
 	return udev->bos->ss_cap->bmAttributes & USB_LTM_SUPPORT;
 }
@@ -1069,7 +1068,7 @@ struct usbdrv_wrap {
  *	for interfaces bound to this driver.
  * @soft_unbind: if set to 1, the USB core will not kill URBs and disable
  *	endpoints before calling the driver's disconnect method.
- * @disable_hub_initiated_lpm: if set to 0, the USB core will not allow hubs
+ * @disable_hub_initiated_lpm: if set to 1, the USB core will not allow hubs
  *	to initiate lower power link state transitions when an idle timeout
  *	occurs.  Device-initiated USB 3.0 link PM will still be allowed.
  *
@@ -1569,7 +1568,7 @@ static inline void usb_fill_bulk_urb(struct urb *urb,
  * Initializes a interrupt urb with the proper information needed to submit
  * it to a device.
  *
- * Note that High Speed and SuperSpeed interrupt endpoints use a logarithmic
+ * Note that High Speed and SuperSpeed(+) interrupt endpoints use a logarithmic
  * encoding of the endpoint interval, and express polling intervals in
  * microframes (eight per millisecond) rather than in frames (one per
  * millisecond).
@@ -1595,7 +1594,7 @@ static inline void usb_fill_int_urb(struct urb *urb,
 	urb->complete = complete_fn;
 	urb->context = context;
 
-	if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) {
+	if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) {
 		/* make sure interval is within allowed range */
 		interval = clamp(interval, 1, 16);
 
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 5d4e151c49bf..457651bf45b0 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -1223,9 +1223,13 @@ int usb_otg_descriptor_init(struct usb_gadget *gadget,
 
 /* utility to simplify map/unmap of usb_requests to/from DMA */
 
+extern int usb_gadget_map_request_by_dev(struct device *dev,
+		struct usb_request *req, int is_in);
 extern int usb_gadget_map_request(struct usb_gadget *gadget,
 		struct usb_request *req, int is_in);
 
+extern void usb_gadget_unmap_request_by_dev(struct device *dev,
+		struct usb_request *req, int is_in);
 extern void usb_gadget_unmap_request(struct usb_gadget *gadget,
 		struct usb_request *req, int is_in);
 
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index b98f831dcda3..66fc13705ab7 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -181,6 +181,7 @@ struct usb_hcd {
 	 * bandwidth_mutex should be dropped after a successful control message
 	 * to the device, or resetting the bandwidth after a failed attempt.
 	 */
+	struct mutex		*address0_mutex;
 	struct mutex		*bandwidth_mutex;
 	struct usb_hcd		*shared_hcd;
 	struct usb_hcd		*primary_hcd;
diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h
index 24198e16f849..7a0350535cb1 100644
--- a/include/linux/usb/otg-fsm.h
+++ b/include/linux/usb/otg-fsm.h
@@ -72,37 +72,113 @@ enum otg_fsm_timer {
 	NUM_OTG_FSM_TIMERS,
 };
 
-/* OTG state machine according to the OTG spec */
+/**
+ * struct otg_fsm - OTG state machine according to the OTG spec
+ *
+ * OTG hardware Inputs
+ *
+ *	Common inputs for A and B device
+ * @id:		TRUE for B-device, FALSE for A-device.
+ * @adp_change: TRUE when current ADP measurement (n) value, compared to the
+ *		ADP measurement taken at n-2, differs by more than CADP_THR
+ * @power_up:	TRUE when the OTG device first powers up its USB system and
+ *		ADP measurement taken if ADP capable
+ *
+ *	A-Device state inputs
+ * @a_srp_det:	TRUE if the A-device detects SRP
+ * @a_vbus_vld:	TRUE when VBUS voltage is in regulation
+ * @b_conn:	TRUE if the A-device detects connection from the B-device
+ * @a_bus_resume: TRUE when the B-device detects that the A-device is signaling
+ *		  a resume (K state)
+ *	B-Device state inputs
+ * @a_bus_suspend: TRUE when the B-device detects that the A-device has put the
+ *		bus into suspend
+ * @a_conn:	TRUE if the B-device detects a connection from the A-device
+ * @b_se0_srp:	TRUE when the line has been at SE0 for more than the minimum
+ *		time before generating SRP
+ * @b_ssend_srp: TRUE when the VBUS has been below VOTG_SESS_VLD for more than
+ *		 the minimum time before generating SRP
+ * @b_sess_vld:	TRUE when the B-device detects that the voltage on VBUS is
+ *		above VOTG_SESS_VLD
+ * @test_device: TRUE when the B-device switches to B-Host and detects an OTG
+ *		test device. This must be set by host/hub driver
+ *
+ *	Application inputs (A-Device)
+ * @a_bus_drop:	TRUE when A-device application needs to power down the bus
+ * @a_bus_req:	TRUE when A-device application wants to use the bus.
+ *		FALSE to suspend the bus
+ *
+ *	Application inputs (B-Device)
+ * @b_bus_req:	TRUE during the time that the Application running on the
+ *		B-device wants to use the bus
+ *
+ *	Auxilary inputs (OTG v1.3 only. Obsolete now.)
+ * @a_sess_vld:	TRUE if the A-device detects that VBUS is above VA_SESS_VLD
+ * @b_bus_suspend: TRUE when the A-device detects that the B-device has put
+ *		the bus into suspend
+ * @b_bus_resume: TRUE when the A-device detects that the B-device is signaling
+ *		 resume on the bus
+ *
+ * OTG Output status. Read only for users. Updated by OTG FSM helpers defined
+ * in this file
+ *
+ *	Outputs for Both A and B device
+ * @drv_vbus:	TRUE when A-device is driving VBUS
+ * @loc_conn:	TRUE when the local device has signaled that it is connected
+ *		to the bus
+ * @loc_sof:	TRUE when the local device is generating activity on the bus
+ * @adp_prb:	TRUE when the local device is in the process of doing
+ *		ADP probing
+ *
+ *	Outputs for B-device state
+ * @adp_sns:	TRUE when the B-device is in the process of carrying out
+ *		ADP sensing
+ * @data_pulse: TRUE when the B-device is performing data line pulsing
+ *
+ * Internal Variables
+ *
+ * a_set_b_hnp_en: TRUE when the A-device has successfully set the
+ *		b_hnp_enable bit in the B-device.
+ *		   Unused as OTG fsm uses otg->host->b_hnp_enable instead
+ * b_srp_done:	TRUE when the B-device has completed initiating SRP
+ * b_hnp_enable: TRUE when the B-device has accepted the
+ *		SetFeature(b_hnp_enable) B-device.
+ *		Unused as OTG fsm uses otg->gadget->b_hnp_enable instead
+ * a_clr_err:	Asserted (by application ?) to clear a_vbus_err due to an
+ *		overcurrent condition and causes the A-device to transition
+ *		to a_wait_vfall
+ */
 struct otg_fsm {
 	/* Input */
 	int id;
 	int adp_change;
 	int power_up;
-	int test_device;
-	int a_bus_drop;
-	int a_bus_req;
 	int a_srp_det;
 	int a_vbus_vld;
 	int b_conn;
 	int a_bus_resume;
 	int a_bus_suspend;
 	int a_conn;
-	int b_bus_req;
 	int b_se0_srp;
 	int b_ssend_srp;
 	int b_sess_vld;
+	int test_device;
+	int a_bus_drop;
+	int a_bus_req;
+	int b_bus_req;
+
 	/* Auxilary inputs */
 	int a_sess_vld;
 	int b_bus_resume;
 	int b_bus_suspend;
 
 	/* Output */
-	int data_pulse;
 	int drv_vbus;
 	int loc_conn;
 	int loc_sof;
 	int adp_prb;
 	int adp_sns;
+	int data_pulse;
 
 	/* Internal variables */
 	int a_set_b_hnp_en;
@@ -110,7 +186,7 @@ struct otg_fsm {
 	int b_hnp_enable;
 	int a_clr_err;
 
-	/* Informative variables */
+	/* Informative variables. All unused as of now */
 	int a_bus_drop_inf;
 	int a_bus_req_inf;
 	int a_clr_err_inf;
@@ -134,6 +210,7 @@ struct otg_fsm {
 	struct mutex lock;
 	u8 *host_req_flag;
 	struct delayed_work hnp_polling_work;
+	bool state_changed;
 };
 
 struct otg_fsm_ops {
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index d5ce71607972..a8acc24765fe 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -105,6 +105,13 @@
 #define USB_REQ_LOOPBACK_DATA_READ	0x16
 #define USB_REQ_SET_INTERFACE_DS	0x17
 
+/* specific requests for USB Power Delivery */
+#define USB_REQ_GET_PARTNER_PDO		20
+#define USB_REQ_GET_BATTERY_STATUS	21
+#define USB_REQ_SET_PDO			22
+#define USB_REQ_GET_VDM			23
+#define USB_REQ_SEND_VDM		24
+
 /* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command,
  * used by hubs to put ports into a new L1 suspend state, except that it
  * forgot to define its number ...
@@ -165,6 +172,22 @@
 #define USB_DEV_STAT_U2_ENABLED		3	/* transition into U2 state */
 #define USB_DEV_STAT_LTM_ENABLED	4	/* Latency tolerance messages */
 
+/*
+ * Feature selectors from Table 9-8 USB Power Delivery spec
+ */
+#define USB_DEVICE_BATTERY_WAKE_MASK	40
+#define USB_DEVICE_OS_IS_PD_AWARE	41
+#define USB_DEVICE_POLICY_MODE		42
+#define USB_PORT_PR_SWAP		43
+#define USB_PORT_GOTO_MIN		44
+#define USB_PORT_RETURN_POWER		45
+#define USB_PORT_ACCEPT_PD_REQUEST	46
+#define USB_PORT_REJECT_PD_REQUEST	47
+#define USB_PORT_PORT_PD_RESET		48
+#define USB_PORT_C_PORT_PD_CHANGE	49
+#define USB_PORT_CABLE_PD_RESET		50
+#define USB_DEVICE_CHARGING_POLICY	54
+
 /**
  * struct usb_ctrlrequest - SETUP data for a USB device control request
  * @bRequestType: matches the USB bmRequestType field
@@ -914,6 +937,104 @@ struct usb_ssp_cap_descriptor {
 } __attribute__((packed));
 
 /*
+ * USB Power Delivery Capability Descriptor:
+ * Defines capabilities for PD
+ */
+/* Defines the various PD Capabilities of this device */
+#define USB_PD_POWER_DELIVERY_CAPABILITY	0x06
+/* Provides information on each battery supported by the device */
+#define USB_PD_BATTERY_INFO_CAPABILITY		0x07
+/* The Consumer characteristics of a Port on the device */
+#define USB_PD_PD_CONSUMER_PORT_CAPABILITY	0x08
+/* The provider characteristics of a Port on the device */
+#define USB_PD_PD_PROVIDER_PORT_CAPABILITY	0x09
+
+struct usb_pd_cap_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType; /* set to USB_PD_POWER_DELIVERY_CAPABILITY */
+	__u8  bReserved;
+	__le32 bmAttributes;
+#define USB_PD_CAP_BATTERY_CHARGING	(1 << 1) /* supports Battery Charging specification */
+#define USB_PD_CAP_USB_PD		(1 << 2) /* supports USB Power Delivery specification */
+#define USB_PD_CAP_PROVIDER		(1 << 3) /* can provide power */
+#define USB_PD_CAP_CONSUMER		(1 << 4) /* can consume power */
+#define USB_PD_CAP_CHARGING_POLICY	(1 << 5) /* supports CHARGING_POLICY feature */
+#define USB_PD_CAP_TYPE_C_CURRENT	(1 << 6) /* supports power capabilities defined in the USB Type-C Specification */
+
+#define USB_PD_CAP_PWR_AC		(1 << 8)
+#define USB_PD_CAP_PWR_BAT		(1 << 9)
+#define USB_PD_CAP_PWR_USE_V_BUS	(1 << 14)
+
+	__le16 bmProviderPorts; /* Bit zero refers to the UFP of the device */
+	__le16 bmConsumerPorts;
+	__le16 bcdBCVersion;
+	__le16 bcdPDVersion;
+	__le16 bcdUSBTypeCVersion;
+} __attribute__((packed));
+
+struct usb_pd_cap_battery_info_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDevCapabilityType;
+	/* Index of string descriptor shall contain the user friendly name for this battery */
+	__u8 iBattery;
+	/* Index of string descriptor shall contain the Serial Number String for this battery */
+	__u8 iSerial;
+	__u8 iManufacturer;
+	__u8 bBatteryId; /* uniquely identifies this battery in status Messages */
+	__u8 bReserved;
+	/*
+	 * Shall contain the Battery Charge value above which this
+	 * battery is considered to be fully charged but not necessarily
+	 * “topped off.”
+	 */
+	__le32 dwChargedThreshold; /* in mWh */
+	/*
+	 * Shall contain the minimum charge level of this battery such
+	 * that above this threshold, a device can be assured of being
+	 * able to power up successfully (see Battery Charging 1.2).
+	 */
+	__le32 dwWeakThreshold; /* in mWh */
+	__le32 dwBatteryDesignCapacity; /* in mWh */
+	__le32 dwBatteryLastFullchargeCapacity; /* in mWh */
+} __attribute__((packed));
+
+struct usb_pd_cap_consumer_port_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDevCapabilityType;
+	__u8 bReserved;
+	__u8 bmCapabilities;
+/* port will oerate under: */
+#define USB_PD_CAP_CONSUMER_BC		(1 << 0) /* BC */
+#define USB_PD_CAP_CONSUMER_PD		(1 << 1) /* PD */
+#define USB_PD_CAP_CONSUMER_TYPE_C	(1 << 2) /* USB Type-C Current */
+	__le16 wMinVoltage; /* in 50mV units */
+	__le16 wMaxVoltage; /* in 50mV units */
+	__u16 wReserved;
+	__le32 dwMaxOperatingPower; /* in 10 mW - operating at steady state */
+	__le32 dwMaxPeakPower; /* in 10mW units - operating at peak power */
+	__le32 dwMaxPeakPowerTime; /* in 100ms units - duration of peak */
+#define USB_PD_CAP_CONSUMER_UNKNOWN_PEAK_POWER_TIME 0xffff
+} __attribute__((packed));
+
+struct usb_pd_cap_provider_port_descriptor {
+	__u8 bLength;
+	__u8 bDescriptorType;
+	__u8 bDevCapabilityType;
+	__u8 bReserved1;
+	__u8 bmCapabilities;
+/* port will oerate under: */
+#define USB_PD_CAP_PROVIDER_BC		(1 << 0) /* BC */
+#define USB_PD_CAP_PROVIDER_PD		(1 << 1) /* PD */
+#define USB_PD_CAP_PROVIDER_TYPE_C	(1 << 2) /* USB Type-C Current */
+	__u8 bNumOfPDObjects;
+	__u8 bReserved2;
+	__le32 wPowerDataObject[];
+} __attribute__((packed));
+
+/*
  * Precision time measurement capability descriptor: advertised by devices and
  * hubs that support PTM
  */
diff --git a/tools/usb/usbip/libsrc/Makefile.am b/tools/usb/usbip/libsrc/Makefile.am
index 7c8f8a4d54e4..90daf95c0804 100644
--- a/tools/usb/usbip/libsrc/Makefile.am
+++ b/tools/usb/usbip/libsrc/Makefile.am
@@ -4,5 +4,7 @@ libusbip_la_LDFLAGS  = -version-info @LIBUSBIP_VERSION@
 
 lib_LTLIBRARIES := libusbip.la
 libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \
-		       usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h \
+		       usbip_device_driver.c usbip_device_driver.h \
+		       usbip_common.c usbip_common.h usbip_host_common.h \
+		       usbip_host_common.c vhci_driver.c vhci_driver.h \
 		       sysfs_utils.c sysfs_utils.h
diff --git a/tools/usb/usbip/libsrc/usbip_common.h b/tools/usb/usbip/libsrc/usbip_common.h
index 15fe792e1e96..51ef5fe485dd 100644
--- a/tools/usb/usbip/libsrc/usbip_common.h
+++ b/tools/usb/usbip/libsrc/usbip_common.h
@@ -25,9 +25,12 @@
 #define VHCI_STATE_PATH "/var/run/vhci_hcd"
 #endif
 
+#define VUDC_DEVICE_DESCR_FILE "dev_desc"
+
 /* kernel module names */
 #define USBIP_CORE_MOD_NAME	"usbip-core"
 #define USBIP_HOST_DRV_NAME	"usbip-host"
+#define USBIP_DEVICE_DRV_NAME	"usbip-vudc"
 #define USBIP_VHCI_DRV_NAME	"vhci_hcd"
 
 /* sysfs constants */
diff --git a/tools/usb/usbip/libsrc/usbip_device_driver.c b/tools/usb/usbip/libsrc/usbip_device_driver.c
new file mode 100644
index 000000000000..e059b7d1ec5b
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_device_driver.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ *		 2015 Samsung Electronics
+ * Author:	 Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *
+ * Based on tools/usb/usbip/libsrc/usbip_host_driver.c, which is:
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ *               2005-2007 Takahiro Hirofuchi
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <linux/usb/ch9.h>
+
+#include <unistd.h>
+
+#include "usbip_host_common.h"
+#include "usbip_device_driver.h"
+
+#undef  PROGNAME
+#define PROGNAME "libusbip"
+
+#define copy_descr_attr16(dev, descr, attr)			\
+		((dev)->attr = le16toh((descr)->attr))		\
+
+#define copy_descr_attr(dev, descr, attr)			\
+		((dev)->attr = (descr)->attr)			\
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static struct {
+	enum usb_device_speed speed;
+	const char *name;
+} speed_names[] = {
+	{
+		.speed = USB_SPEED_UNKNOWN,
+		.name = "UNKNOWN",
+	},
+	{
+		.speed = USB_SPEED_LOW,
+		.name = "low-speed",
+	},
+	{
+		.speed = USB_SPEED_FULL,
+		.name = "full-speed",
+	},
+	{
+		.speed = USB_SPEED_HIGH,
+		.name = "high-speed",
+	},
+	{
+		.speed = USB_SPEED_WIRELESS,
+		.name = "wireless",
+	},
+	{
+		.speed = USB_SPEED_SUPER,
+		.name = "super-speed",
+	},
+};
+
+static
+int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev)
+{
+	const char *path, *name;
+	char filepath[SYSFS_PATH_MAX];
+	struct usb_device_descriptor descr;
+	unsigned i;
+	FILE *fd = NULL;
+	struct udev_device *plat;
+	const char *speed;
+	int ret = 0;
+
+	plat = udev_device_get_parent(sdev);
+	path = udev_device_get_syspath(plat);
+	snprintf(filepath, SYSFS_PATH_MAX, "%s/%s",
+		 path, VUDC_DEVICE_DESCR_FILE);
+	fd = fopen(filepath, "r");
+	if (!fd)
+		return -1;
+	ret = fread((char *) &descr, sizeof(descr), 1, fd);
+	if (ret < 0)
+		return -1;
+	fclose(fd);
+
+	copy_descr_attr(dev, &descr, bDeviceClass);
+	copy_descr_attr(dev, &descr, bDeviceSubClass);
+	copy_descr_attr(dev, &descr, bDeviceProtocol);
+	copy_descr_attr(dev, &descr, bNumConfigurations);
+	copy_descr_attr16(dev, &descr, idVendor);
+	copy_descr_attr16(dev, &descr, idProduct);
+	copy_descr_attr16(dev, &descr, bcdDevice);
+
+	strncpy(dev->path, path, SYSFS_PATH_MAX);
+
+	dev->speed = USB_SPEED_UNKNOWN;
+	speed = udev_device_get_sysattr_value(sdev, "current_speed");
+	if (speed) {
+		for (i = 0; i < ARRAY_SIZE(speed_names); i++) {
+			if (!strcmp(speed_names[i].name, speed)) {
+				dev->speed = speed_names[i].speed;
+				break;
+			}
+		}
+	}
+
+	/* Only used for user output, little sense to output them in general */
+	dev->bNumInterfaces = 0;
+	dev->bConfigurationValue = 0;
+	dev->busnum = 0;
+
+	name = udev_device_get_sysname(plat);
+	strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE);
+	return 0;
+}
+
+static int is_my_device(struct udev_device *dev)
+{
+	const char *driver;
+
+	driver = udev_device_get_property_value(dev, "USB_UDC_NAME");
+	return driver != NULL && !strcmp(driver, USBIP_DEVICE_DRV_NAME);
+}
+
+static int usbip_device_driver_open(struct usbip_host_driver *hdriver)
+{
+	int ret;
+
+	hdriver->ndevs = 0;
+	INIT_LIST_HEAD(&hdriver->edev_list);
+
+	ret = usbip_generic_driver_open(hdriver);
+	if (ret)
+		err("please load " USBIP_CORE_MOD_NAME ".ko and "
+		    USBIP_DEVICE_DRV_NAME ".ko!");
+
+	return ret;
+}
+
+struct usbip_host_driver device_driver = {
+	.edev_list = LIST_HEAD_INIT(device_driver.edev_list),
+	.udev_subsystem = "udc",
+	.ops = {
+		.open = usbip_device_driver_open,
+		.close = usbip_generic_driver_close,
+		.refresh_device_list = usbip_generic_refresh_device_list,
+		.get_device = usbip_generic_get_device,
+		.read_device = read_usb_vudc_device,
+		.is_my_device = is_my_device,
+	},
+};
diff --git a/tools/usb/usbip/libsrc/usbip_device_driver.h b/tools/usb/usbip/libsrc/usbip_device_driver.h
new file mode 100644
index 000000000000..54cb658b37a3
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_device_driver.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 Karol Kosik <karo9@interia.eu>
+ *		 2015 Samsung Electronics
+ * Author:	 Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *
+ * Based on tools/usb/usbip/libsrc/usbip_host_driver.c, which is:
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ *               2005-2007 Takahiro Hirofuchi
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __USBIP_DEVICE_DRIVER_H
+#define __USBIP_DEVICE_DRIVER_H
+
+#include <stdint.h>
+#include "usbip_common.h"
+#include "usbip_host_common.h"
+#include "list.h"
+
+extern struct usbip_host_driver device_driver;
+
+#endif /* __USBIP_DEVICE_DRIVER_H */
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c
new file mode 100644
index 000000000000..9d415228883d
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_host_common.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
+ *
+ * Refactored from usbip_host_driver.c, which is:
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ *               2005-2007 Takahiro Hirofuchi
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <libudev.h>
+
+#include "usbip_common.h"
+#include "usbip_host_common.h"
+#include "list.h"
+#include "sysfs_utils.h"
+
+struct udev *udev_context;
+
+static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
+{
+	char status_attr_path[SYSFS_PATH_MAX];
+	int fd;
+	int length;
+	char status;
+	int value = 0;
+
+	snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
+		 udev->path);
+
+	fd = open(status_attr_path, O_RDONLY);
+	if (fd < 0) {
+		err("error opening attribute %s", status_attr_path);
+		return -1;
+	}
+
+	length = read(fd, &status, 1);
+	if (length < 0) {
+		err("error reading attribute %s", status_attr_path);
+		close(fd);
+		return -1;
+	}
+
+	value = atoi(&status);
+
+	return value;
+}
+
+static
+struct usbip_exported_device *usbip_exported_device_new(
+		struct usbip_host_driver *hdriver, const char *sdevpath)
+{
+	struct usbip_exported_device *edev = NULL;
+	struct usbip_exported_device *edev_old;
+	size_t size;
+	int i;
+
+	edev = calloc(1, sizeof(struct usbip_exported_device));
+
+	edev->sudev =
+		udev_device_new_from_syspath(udev_context, sdevpath);
+	if (!edev->sudev) {
+		err("udev_device_new_from_syspath: %s", sdevpath);
+		goto err;
+	}
+
+	if (hdriver->ops.read_device(edev->sudev, &edev->udev) < 0)
+		goto err;
+
+	edev->status = read_attr_usbip_status(&edev->udev);
+	if (edev->status < 0)
+		goto err;
+
+	/* reallocate buffer to include usb interface data */
+	size = sizeof(struct usbip_exported_device) +
+		edev->udev.bNumInterfaces * sizeof(struct usbip_usb_interface);
+
+	edev_old = edev;
+	edev = realloc(edev, size);
+	if (!edev) {
+		edev = edev_old;
+		dbg("realloc failed");
+		goto err;
+	}
+
+	for (i = 0; i < edev->udev.bNumInterfaces; i++) {
+		/* vudc does not support reading interfaces */
+		if (!hdriver->ops.read_interface)
+			break;
+		hdriver->ops.read_interface(&edev->udev, i, &edev->uinf[i]);
+	}
+
+	return edev;
+err:
+	if (edev->sudev)
+		udev_device_unref(edev->sudev);
+	if (edev)
+		free(edev);
+
+	return NULL;
+}
+
+static int refresh_exported_devices(struct usbip_host_driver *hdriver)
+{
+	struct usbip_exported_device *edev;
+	struct udev_enumerate *enumerate;
+	struct udev_list_entry *devices, *dev_list_entry;
+	struct udev_device *dev;
+	const char *path;
+
+	enumerate = udev_enumerate_new(udev_context);
+	udev_enumerate_add_match_subsystem(enumerate, hdriver->udev_subsystem);
+	udev_enumerate_scan_devices(enumerate);
+
+	devices = udev_enumerate_get_list_entry(enumerate);
+
+	udev_list_entry_foreach(dev_list_entry, devices) {
+		path = udev_list_entry_get_name(dev_list_entry);
+		dev = udev_device_new_from_syspath(udev_context,
+						   path);
+		if (dev == NULL)
+			continue;
+
+		/* Check whether device uses usbip driver. */
+		if (hdriver->ops.is_my_device(dev)) {
+			edev = usbip_exported_device_new(hdriver, path);
+			if (!edev) {
+				dbg("usbip_exported_device_new failed");
+				continue;
+			}
+
+			list_add(&edev->node, &hdriver->edev_list);
+			hdriver->ndevs++;
+		}
+	}
+
+	return 0;
+}
+
+static void usbip_exported_device_destroy(struct list_head *devs)
+{
+	struct list_head *i, *tmp;
+	struct usbip_exported_device *edev;
+
+	list_for_each_safe(i, tmp, devs) {
+		edev = list_entry(i, struct usbip_exported_device, node);
+		list_del(i);
+		free(edev);
+	}
+}
+
+int usbip_generic_driver_open(struct usbip_host_driver *hdriver)
+{
+	int rc;
+
+	udev_context = udev_new();
+	if (!udev_context) {
+		err("udev_new failed");
+		return -1;
+	}
+
+	rc = refresh_exported_devices(hdriver);
+	if (rc < 0)
+		goto err;
+	return 0;
+err:
+	udev_unref(udev_context);
+	return -1;
+}
+
+void usbip_generic_driver_close(struct usbip_host_driver *hdriver)
+{
+	if (!hdriver)
+		return;
+
+	usbip_exported_device_destroy(&hdriver->edev_list);
+
+	udev_unref(udev_context);
+}
+
+int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver)
+{
+	int rc;
+
+	usbip_exported_device_destroy(&hdriver->edev_list);
+
+	hdriver->ndevs = 0;
+	INIT_LIST_HEAD(&hdriver->edev_list);
+
+	rc = refresh_exported_devices(hdriver);
+	if (rc < 0)
+		return -1;
+
+	return 0;
+}
+
+int usbip_export_device(struct usbip_exported_device *edev, int sockfd)
+{
+	char attr_name[] = "usbip_sockfd";
+	char sockfd_attr_path[SYSFS_PATH_MAX];
+	char sockfd_buff[30];
+	int ret;
+
+	if (edev->status != SDEV_ST_AVAILABLE) {
+		dbg("device not available: %s", edev->udev.busid);
+		switch (edev->status) {
+		case SDEV_ST_ERROR:
+			dbg("status SDEV_ST_ERROR");
+			break;
+		case SDEV_ST_USED:
+			dbg("status SDEV_ST_USED");
+			break;
+		default:
+			dbg("status unknown: 0x%x", edev->status);
+		}
+		return -1;
+	}
+
+	/* only the first interface is true */
+	snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
+		 edev->udev.path, attr_name);
+
+	snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
+
+	ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
+				    strlen(sockfd_buff));
+	if (ret < 0) {
+		err("write_sysfs_attribute failed: sockfd %s to %s",
+		    sockfd_buff, sockfd_attr_path);
+		return ret;
+	}
+
+	info("connect: %s", edev->udev.busid);
+
+	return ret;
+}
+
+struct usbip_exported_device *usbip_generic_get_device(
+		struct usbip_host_driver *hdriver, int num)
+{
+	struct list_head *i;
+	struct usbip_exported_device *edev;
+	int cnt = 0;
+
+	list_for_each(i, &hdriver->edev_list) {
+		edev = list_entry(i, struct usbip_exported_device, node);
+		if (num == cnt)
+			return edev;
+		cnt++;
+	}
+
+	return NULL;
+}
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h
new file mode 100644
index 000000000000..a64b8033fe64
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_host_common.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
+ *
+ * Refactored from usbip_host_driver.c, which is:
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ *               2005-2007 Takahiro Hirofuchi
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __USBIP_HOST_COMMON_H
+#define __USBIP_HOST_COMMON_H
+
+#include <stdint.h>
+#include <libudev.h>
+#include <errno.h>
+#include "list.h"
+#include "usbip_common.h"
+#include "sysfs_utils.h"
+
+struct usbip_host_driver;
+
+struct usbip_host_driver_ops {
+	int (*open)(struct usbip_host_driver *hdriver);
+	void (*close)(struct usbip_host_driver *hdriver);
+	int (*refresh_device_list)(struct usbip_host_driver *hdriver);
+	struct usbip_exported_device * (*get_device)(
+		struct usbip_host_driver *hdriver, int num);
+
+	int (*read_device)(struct udev_device *sdev,
+			   struct usbip_usb_device *dev);
+	int (*read_interface)(struct usbip_usb_device *udev, int i,
+			      struct usbip_usb_interface *uinf);
+	int (*is_my_device)(struct udev_device *udev);
+};
+
+struct usbip_host_driver {
+	int ndevs;
+	/* list of exported device */
+	struct list_head edev_list;
+	const char *udev_subsystem;
+	struct usbip_host_driver_ops ops;
+};
+
+struct usbip_exported_device {
+	struct udev_device *sudev;
+	int32_t status;
+	struct usbip_usb_device udev;
+	struct list_head node;
+	struct usbip_usb_interface uinf[];
+};
+
+/* External API to access the driver */
+static inline int usbip_driver_open(struct usbip_host_driver *hdriver)
+{
+	if (!hdriver->ops.open)
+		return -EOPNOTSUPP;
+	return hdriver->ops.open(hdriver);
+}
+
+static inline void usbip_driver_close(struct usbip_host_driver *hdriver)
+{
+	if (!hdriver->ops.close)
+		return;
+	hdriver->ops.close(hdriver);
+}
+
+static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver)
+{
+	if (!hdriver->ops.refresh_device_list)
+		return -EOPNOTSUPP;
+	return hdriver->ops.refresh_device_list(hdriver);
+}
+
+static inline struct usbip_exported_device *
+usbip_get_device(struct usbip_host_driver *hdriver, int num)
+{
+	if (!hdriver->ops.get_device)
+		return NULL;
+	return hdriver->ops.get_device(hdriver, num);
+}
+
+/* Helper functions for implementing driver backend */
+int usbip_generic_driver_open(struct usbip_host_driver *hdriver);
+void usbip_generic_driver_close(struct usbip_host_driver *hdriver);
+int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver);
+int usbip_export_device(struct usbip_exported_device *edev, int sockfd);
+struct usbip_exported_device *usbip_generic_get_device(
+		struct usbip_host_driver *hdriver, int num);
+
+#endif /* __USBIP_HOST_COMMON_H */
diff --git a/tools/usb/usbip/libsrc/usbip_host_driver.c b/tools/usb/usbip/libsrc/usbip_host_driver.c
index bef08d5c44e8..4de6edc54d35 100644
--- a/tools/usb/usbip/libsrc/usbip_host_driver.c
+++ b/tools/usb/usbip/libsrc/usbip_host_driver.c
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,265 +19,47 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <errno.h>
 #include <unistd.h>
-
 #include <libudev.h>
 
-#include "usbip_common.h"
+#include "usbip_host_common.h"
 #include "usbip_host_driver.h"
-#include "list.h"
-#include "sysfs_utils.h"
 
 #undef  PROGNAME
 #define PROGNAME "libusbip"
 
-struct usbip_host_driver *host_driver;
-struct udev *udev_context;
-
-static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
-{
-	char status_attr_path[SYSFS_PATH_MAX];
-	int fd;
-	int length;
-	char status;
-	int value = 0;
-
-	snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
-		 udev->path);
-
-	fd = open(status_attr_path, O_RDONLY);
-	if (fd < 0) {
-		err("error opening attribute %s", status_attr_path);
-		return -1;
-	}
-
-	length = read(fd, &status, 1);
-	if (length < 0) {
-		err("error reading attribute %s", status_attr_path);
-		close(fd);
-		return -1;
-	}
-
-	value = atoi(&status);
-
-	return value;
-}
-
-static
-struct usbip_exported_device *usbip_exported_device_new(const char *sdevpath)
-{
-	struct usbip_exported_device *edev = NULL;
-	struct usbip_exported_device *edev_old;
-	size_t size;
-	int i;
-
-	edev = calloc(1, sizeof(struct usbip_exported_device));
-
-	edev->sudev = udev_device_new_from_syspath(udev_context, sdevpath);
-	if (!edev->sudev) {
-		err("udev_device_new_from_syspath: %s", sdevpath);
-		goto err;
-	}
-
-	read_usb_device(edev->sudev, &edev->udev);
-
-	edev->status = read_attr_usbip_status(&edev->udev);
-	if (edev->status < 0)
-		goto err;
-
-	/* reallocate buffer to include usb interface data */
-	size = sizeof(struct usbip_exported_device) +
-		edev->udev.bNumInterfaces * sizeof(struct usbip_usb_interface);
-
-	edev_old = edev;
-	edev = realloc(edev, size);
-	if (!edev) {
-		edev = edev_old;
-		dbg("realloc failed");
-		goto err;
-	}
-
-	for (i = 0; i < edev->udev.bNumInterfaces; i++)
-		read_usb_interface(&edev->udev, i, &edev->uinf[i]);
-
-	return edev;
-err:
-	if (edev->sudev)
-		udev_device_unref(edev->sudev);
-	if (edev)
-		free(edev);
-
-	return NULL;
-}
-
-static int refresh_exported_devices(void)
+static int is_my_device(struct udev_device *dev)
 {
-	struct usbip_exported_device *edev;
-	struct udev_enumerate *enumerate;
-	struct udev_list_entry *devices, *dev_list_entry;
-	struct udev_device *dev;
-	const char *path;
 	const char *driver;
 
-	enumerate = udev_enumerate_new(udev_context);
-	udev_enumerate_add_match_subsystem(enumerate, "usb");
-	udev_enumerate_scan_devices(enumerate);
-
-	devices = udev_enumerate_get_list_entry(enumerate);
-
-	udev_list_entry_foreach(dev_list_entry, devices) {
-		path = udev_list_entry_get_name(dev_list_entry);
-		dev = udev_device_new_from_syspath(udev_context, path);
-		if (dev == NULL)
-			continue;
-
-		/* Check whether device uses usbip-host driver. */
-		driver = udev_device_get_driver(dev);
-		if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) {
-			edev = usbip_exported_device_new(path);
-			if (!edev) {
-				dbg("usbip_exported_device_new failed");
-				continue;
-			}
-
-			list_add(&edev->node, &host_driver->edev_list);
-			host_driver->ndevs++;
-		}
-	}
-
-	return 0;
-}
-
-static void usbip_exported_device_destroy(void)
-{
-	struct list_head *i, *tmp;
-	struct usbip_exported_device *edev;
-
-	list_for_each_safe(i, tmp, &host_driver->edev_list) {
-		edev = list_entry(i, struct usbip_exported_device, node);
-		list_del(i);
-		free(edev);
-	}
+	driver = udev_device_get_driver(dev);
+	return driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME);
 }
 
-int usbip_host_driver_open(void)
+static int usbip_host_driver_open(struct usbip_host_driver *hdriver)
 {
-	int rc;
-
-	udev_context = udev_new();
-	if (!udev_context) {
-		err("udev_new failed");
-		return -1;
-	}
-
-	host_driver = calloc(1, sizeof(*host_driver));
-
-	host_driver->ndevs = 0;
-	INIT_LIST_HEAD(&host_driver->edev_list);
-
-	rc = refresh_exported_devices();
-	if (rc < 0)
-		goto err_free_host_driver;
-
-	return 0;
-
-err_free_host_driver:
-	free(host_driver);
-	host_driver = NULL;
-
-	udev_unref(udev_context);
-
-	return -1;
-}
-
-void usbip_host_driver_close(void)
-{
-	if (!host_driver)
-		return;
-
-	usbip_exported_device_destroy();
-
-	free(host_driver);
-	host_driver = NULL;
-
-	udev_unref(udev_context);
-}
-
-int usbip_host_refresh_device_list(void)
-{
-	int rc;
-
-	usbip_exported_device_destroy();
-
-	host_driver->ndevs = 0;
-	INIT_LIST_HEAD(&host_driver->edev_list);
-
-	rc = refresh_exported_devices();
-	if (rc < 0)
-		return -1;
-
-	return 0;
-}
-
-int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd)
-{
-	char attr_name[] = "usbip_sockfd";
-	char sockfd_attr_path[SYSFS_PATH_MAX];
-	char sockfd_buff[30];
 	int ret;
 
-	if (edev->status != SDEV_ST_AVAILABLE) {
-		dbg("device not available: %s", edev->udev.busid);
-		switch (edev->status) {
-		case SDEV_ST_ERROR:
-			dbg("status SDEV_ST_ERROR");
-			break;
-		case SDEV_ST_USED:
-			dbg("status SDEV_ST_USED");
-			break;
-		default:
-			dbg("status unknown: 0x%x", edev->status);
-		}
-		return -1;
-	}
-
-	/* only the first interface is true */
-	snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
-		 edev->udev.path, attr_name);
-
-	snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
-
-	ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
-				    strlen(sockfd_buff));
-	if (ret < 0) {
-		err("write_sysfs_attribute failed: sockfd %s to %s",
-		    sockfd_buff, sockfd_attr_path);
-		return ret;
-	}
-
-	info("connect: %s", edev->udev.busid);
+	hdriver->ndevs = 0;
+	INIT_LIST_HEAD(&hdriver->edev_list);
 
+	ret = usbip_generic_driver_open(hdriver);
+	if (ret)
+		err("please load " USBIP_CORE_MOD_NAME ".ko and "
+		    USBIP_HOST_DRV_NAME ".ko!");
 	return ret;
 }
 
-struct usbip_exported_device *usbip_host_get_device(int num)
-{
-	struct list_head *i;
-	struct usbip_exported_device *edev;
-	int cnt = 0;
-
-	list_for_each(i, &host_driver->edev_list) {
-		edev = list_entry(i, struct usbip_exported_device, node);
-		if (num == cnt)
-			return edev;
-		else
-			cnt++;
-	}
-
-	return NULL;
-}
+struct usbip_host_driver host_driver = {
+	.edev_list = LIST_HEAD_INIT(host_driver.edev_list),
+	.udev_subsystem = "usb",
+	.ops = {
+		.open = usbip_host_driver_open,
+		.close = usbip_generic_driver_close,
+		.refresh_device_list = usbip_generic_refresh_device_list,
+		.get_device = usbip_generic_get_device,
+		.read_device = read_usb_device,
+		.read_interface = read_usb_interface,
+		.is_my_device = is_my_device,
+	},
+};
diff --git a/tools/usb/usbip/libsrc/usbip_host_driver.h b/tools/usb/usbip/libsrc/usbip_host_driver.h
index 2a31f855c616..77f07e72a7fe 100644
--- a/tools/usb/usbip/libsrc/usbip_host_driver.h
+++ b/tools/usb/usbip/libsrc/usbip_host_driver.h
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,28 +25,8 @@
 #include <stdint.h>
 #include "usbip_common.h"
 #include "list.h"
+#include "usbip_host_common.h"
 
-struct usbip_host_driver {
-	int ndevs;
-	/* list of exported device */
-	struct list_head edev_list;
-};
-
-struct usbip_exported_device {
-	struct udev_device *sudev;
-	int32_t status;
-	struct usbip_usb_device udev;
-	struct list_head node;
-	struct usbip_usb_interface uinf[];
-};
-
-extern struct usbip_host_driver *host_driver;
-
-int usbip_host_driver_open(void);
-void usbip_host_driver_close(void);
-
-int usbip_host_refresh_device_list(void);
-int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd);
-struct usbip_exported_device *usbip_host_get_device(int num);
+extern struct usbip_host_driver host_driver;
 
 #endif /* __USBIP_HOST_DRIVER_H */
diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c
index d58a14dfc094..70a6b507fb62 100644
--- a/tools/usb/usbip/src/usbip_attach.c
+++ b/tools/usb/usbip/src/usbip_attach.c
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,7 +39,8 @@
 static const char usbip_attach_usage_string[] =
 	"usbip attach <args>\n"
 	"    -r, --remote=<host>      The machine with exported USB devices\n"
-	"    -b, --busid=<busid>    Busid of the device on <host>\n";
+	"    -b, --busid=<busid>    Busid of the device on <host>\n"
+	"    -d, --device=<devid>    Id of the virtual UDC on <host>\n";
 
 void usbip_attach_usage(void)
 {
@@ -203,6 +207,7 @@ int usbip_attach(int argc, char *argv[])
 	static const struct option opts[] = {
 		{ "remote", required_argument, NULL, 'r' },
 		{ "busid",  required_argument, NULL, 'b' },
+		{ "device",  required_argument, NULL, 'd' },
 		{ NULL, 0,  NULL, 0 }
 	};
 	char *host = NULL;
@@ -211,7 +216,7 @@ int usbip_attach(int argc, char *argv[])
 	int ret = -1;
 
 	for (;;) {
-		opt = getopt_long(argc, argv, "r:b:", opts, NULL);
+		opt = getopt_long(argc, argv, "d:r:b:", opts, NULL);
 
 		if (opt == -1)
 			break;
@@ -220,6 +225,7 @@ int usbip_attach(int argc, char *argv[])
 		case 'r':
 			host = optarg;
 			break;
+		case 'd':
 		case 'b':
 			busid = optarg;
 			break;
diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c
index d5ce34a410e7..f1b38e866dd7 100644
--- a/tools/usb/usbip/src/usbip_list.c
+++ b/tools/usb/usbip/src/usbip_list.c
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,6 +33,10 @@
 #include <netdb.h>
 #include <unistd.h>
 
+#include <dirent.h>
+
+#include <linux/usb/ch9.h>
+
 #include "usbip_common.h"
 #include "usbip_network.h"
 #include "usbip.h"
@@ -205,8 +212,10 @@ static int list_devices(bool parsable)
 		/* Get device information. */
 		idVendor = udev_device_get_sysattr_value(dev, "idVendor");
 		idProduct = udev_device_get_sysattr_value(dev, "idProduct");
-		bConfValue = udev_device_get_sysattr_value(dev, "bConfigurationValue");
-		bNumIntfs = udev_device_get_sysattr_value(dev, "bNumInterfaces");
+		bConfValue = udev_device_get_sysattr_value(dev,
+				"bConfigurationValue");
+		bNumIntfs = udev_device_get_sysattr_value(dev,
+				"bNumInterfaces");
 		busid = udev_device_get_sysname(dev);
 		if (!idVendor || !idProduct || !bConfValue || !bNumIntfs) {
 			err("problem getting device attributes: %s",
@@ -237,12 +246,90 @@ err_out:
 	return ret;
 }
 
+static int list_gadget_devices(bool parsable)
+{
+	int ret = -1;
+	struct udev *udev;
+	struct udev_enumerate *enumerate;
+	struct udev_list_entry *devices, *dev_list_entry;
+	struct udev_device *dev;
+	const char *path;
+	const char *driver;
+
+	const struct usb_device_descriptor *d_desc;
+	const char *descriptors;
+	char product_name[128];
+
+	uint16_t idVendor;
+	char idVendor_buf[8];
+	uint16_t idProduct;
+	char idProduct_buf[8];
+	const char *busid;
+
+	udev = udev_new();
+	enumerate = udev_enumerate_new(udev);
+
+	udev_enumerate_add_match_subsystem(enumerate, "platform");
+
+	udev_enumerate_scan_devices(enumerate);
+	devices = udev_enumerate_get_list_entry(enumerate);
+
+	udev_list_entry_foreach(dev_list_entry, devices) {
+		path = udev_list_entry_get_name(dev_list_entry);
+		dev = udev_device_new_from_syspath(udev, path);
+
+		driver = udev_device_get_driver(dev);
+		/* We only have mechanism to enumerate gadgets bound to vudc */
+		if (driver == NULL || strcmp(driver, USBIP_DEVICE_DRV_NAME))
+			continue;
+
+		/* Get device information. */
+		descriptors = udev_device_get_sysattr_value(dev,
+				VUDC_DEVICE_DESCR_FILE);
+
+		if (!descriptors) {
+			err("problem getting device attributes: %s",
+			    strerror(errno));
+			goto err_out;
+		}
+
+		d_desc = (const struct usb_device_descriptor *) descriptors;
+
+		idVendor = le16toh(d_desc->idVendor);
+		sprintf(idVendor_buf, "0x%4x", idVendor);
+		idProduct = le16toh(d_desc->idProduct);
+		sprintf(idProduct_buf, "0x%4x", idVendor);
+		busid = udev_device_get_sysname(dev);
+
+		/* Get product name. */
+		usbip_names_get_product(product_name, sizeof(product_name),
+					le16toh(idVendor),
+					le16toh(idProduct));
+
+		/* Print information. */
+		print_device(busid, idVendor_buf, idProduct_buf, parsable);
+		print_product_name(product_name, parsable);
+
+		printf("\n");
+
+		udev_device_unref(dev);
+	}
+	ret = 0;
+
+err_out:
+	udev_enumerate_unref(enumerate);
+	udev_unref(udev);
+
+	return ret;
+}
+
 int usbip_list(int argc, char *argv[])
 {
 	static const struct option opts[] = {
 		{ "parsable", no_argument,       NULL, 'p' },
 		{ "remote",   required_argument, NULL, 'r' },
 		{ "local",    no_argument,       NULL, 'l' },
+		{ "device",    no_argument,       NULL, 'd' },
 		{ NULL,       0,                 NULL,  0  }
 	};
 
@@ -254,7 +341,7 @@ int usbip_list(int argc, char *argv[])
 		err("failed to open %s", USBIDS_FILE);
 
 	for (;;) {
-		opt = getopt_long(argc, argv, "pr:l", opts, NULL);
+		opt = getopt_long(argc, argv, "pr:ld", opts, NULL);
 
 		if (opt == -1)
 			break;
@@ -269,6 +356,9 @@ int usbip_list(int argc, char *argv[])
 		case 'l':
 			ret = list_devices(parsable);
 			goto out;
+		case 'd':
+			ret = list_gadget_devices(parsable);
+			goto out;
 		default:
 			goto err_out;
 		}
diff --git a/tools/usb/usbip/src/usbip_port.c b/tools/usb/usbip/src/usbip_port.c
index a2e884fd9226..7bd74fb3a9cd 100644
--- a/tools/usb/usbip/src/usbip_port.c
+++ b/tools/usb/usbip/src/usbip_port.c
@@ -22,10 +22,13 @@ static int list_imported_devices(void)
 	struct usbip_imported_device *idev;
 	int ret;
 
+	if (usbip_names_init(USBIDS_FILE))
+		err("failed to open %s", USBIDS_FILE);
+
 	ret = usbip_vhci_driver_open();
 	if (ret < 0) {
 		err("open vhci_driver");
-		return -1;
+		goto err_names_free;
 	}
 
 	printf("Imported USB devices\n");
@@ -35,13 +38,19 @@ static int list_imported_devices(void)
 		idev = &vhci_driver->idev[i];
 
 		if (usbip_vhci_imported_device_dump(idev) < 0)
-			ret = -1;
+			goto err_driver_close;
 	}
 
 	usbip_vhci_driver_close();
+	usbip_names_free();
 
 	return ret;
 
+err_driver_close:
+	usbip_vhci_driver_close();
+err_names_free:
+	usbip_names_free();
+	return -1;
 }
 
 int usbip_port_show(__attribute__((unused)) int argc,
diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c
index 2a7cd2b8d966..a0972dea9e6c 100644
--- a/tools/usb/usbip/src/usbipd.c
+++ b/tools/usb/usbip/src/usbipd.c
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +44,8 @@
 #include <poll.h>
 
 #include "usbip_host_driver.h"
+#include "usbip_host_common.h"
+#include "usbip_device_driver.h"
 #include "usbip_common.h"
 #include "usbip_network.h"
 #include "list.h"
@@ -64,6 +69,11 @@ static const char usbipd_help_string[] =
 	"	-6, --ipv6\n"
 	"		Bind to IPv6. Default is both.\n"
 	"\n"
+	"	-e, --device\n"
+	"		Run in device mode.\n"
+	"		Rather than drive an attached device, create\n"
+	"		a virtual UDC to bind gadgets to.\n"
+	"\n"
 	"	-D, --daemon\n"
 	"		Run as a daemon process.\n"
 	"\n"
@@ -83,6 +93,8 @@ static const char usbipd_help_string[] =
 	"	-v, --version\n"
 	"		Show version.\n";
 
+static struct usbip_host_driver *driver;
+
 static void usbipd_help(void)
 {
 	printf("%s\n", usbipd_help_string);
@@ -107,7 +119,7 @@ static int recv_request_import(int sockfd)
 	}
 	PACK_OP_IMPORT_REQUEST(0, &req);
 
-	list_for_each(i, &host_driver->edev_list) {
+	list_for_each(i, &driver->edev_list) {
 		edev = list_entry(i, struct usbip_exported_device, node);
 		if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) {
 			info("found requested device: %s", req.busid);
@@ -121,7 +133,7 @@ static int recv_request_import(int sockfd)
 		usbip_net_set_nodelay(sockfd);
 
 		/* export device needs a TCP/IP socket descriptor */
-		rc = usbip_host_export_device(edev, sockfd);
+		rc = usbip_export_device(edev, sockfd);
 		if (rc < 0)
 			error = 1;
 	} else {
@@ -166,7 +178,7 @@ static int send_reply_devlist(int connfd)
 
 	reply.ndev = 0;
 	/* number of exported devices */
-	list_for_each(j, &host_driver->edev_list) {
+	list_for_each(j, &driver->edev_list) {
 		reply.ndev += 1;
 	}
 	info("exportable devices: %d", reply.ndev);
@@ -184,7 +196,7 @@ static int send_reply_devlist(int connfd)
 		return -1;
 	}
 
-	list_for_each(j, &host_driver->edev_list) {
+	list_for_each(j, &driver->edev_list) {
 		edev = list_entry(j, struct usbip_exported_device, node);
 		dump_usb_device(&edev->udev);
 		memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
@@ -246,7 +258,7 @@ static int recv_pdu(int connfd)
 		return -1;
 	}
 
-	ret = usbip_host_refresh_device_list();
+	ret = usbip_refresh_device_list(driver);
 	if (ret < 0) {
 		dbg("could not refresh device list: %d", ret);
 		return -1;
@@ -491,16 +503,13 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 	struct timespec timeout;
 	sigset_t sigmask;
 
-	if (usbip_host_driver_open()) {
-		err("please load " USBIP_CORE_MOD_NAME ".ko and "
-		    USBIP_HOST_DRV_NAME ".ko!");
+	if (usbip_driver_open(driver))
 		return -1;
-	}
 
 	if (daemonize) {
 		if (daemon(0, 0) < 0) {
 			err("daemonizing failed: %s", strerror(errno));
-			usbip_host_driver_close();
+			usbip_driver_close(driver);
 			return -1;
 		}
 		umask(0);
@@ -525,7 +534,7 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 
 	ai_head = do_getaddrinfo(NULL, family);
 	if (!ai_head) {
-		usbip_host_driver_close();
+		usbip_driver_close(driver);
 		return -1;
 	}
 	nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
@@ -533,7 +542,7 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 	freeaddrinfo(ai_head);
 	if (nsockfd <= 0) {
 		err("failed to open a listening socket");
-		usbip_host_driver_close();
+		usbip_driver_close(driver);
 		return -1;
 	}
 
@@ -574,7 +583,7 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 
 	info("shutting down " PROGNAME);
 	free(fds);
-	usbip_host_driver_close();
+	usbip_driver_close(driver);
 
 	return 0;
 }
@@ -587,6 +596,7 @@ int main(int argc, char *argv[])
 		{ "daemon",   no_argument,       NULL, 'D' },
 		{ "daemon",   no_argument,       NULL, 'D' },
 		{ "debug",    no_argument,       NULL, 'd' },
+		{ "device",   no_argument,       NULL, 'e' },
 		{ "pid",      optional_argument, NULL, 'P' },
 		{ "tcp-port", required_argument, NULL, 't' },
 		{ "help",     no_argument,       NULL, 'h' },
@@ -613,8 +623,9 @@ int main(int argc, char *argv[])
 		err("not running as root?");
 
 	cmd = cmd_standalone_mode;
+	driver = &host_driver;
 	for (;;) {
-		opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL);
+		opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL);
 
 		if (opt == -1)
 			break;
@@ -644,6 +655,9 @@ int main(int argc, char *argv[])
 		case 'v':
 			cmd = cmd_version;
 			break;
+		case 'e':
+			driver = &device_driver;
+			break;
 		case '?':
 			usbipd_help();
 		default: